<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:dcterms="http://purl.org/dc/terms/"
     xmlns:media="http://search.yahoo.com/mrss/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:cf="https://www.futureplc.com/rss/content-flags"
>
    <channel>
                    <atom:link href="https://www.tomsguide.com/feeds/tag/iphones" rel="self" type="application/rss+xml" />
                            <title><![CDATA[ Latest from Tom's Guide in Iphones ]]></title>
                <link>https://www.tomsguide.com/phones/iphones</link>
        <description><![CDATA[ All the latest iphones content from the Tom's Guide team ]]></description>
                                    <lastBuildDate>Wed, 07 Oct 2026 07:02:00 +0000</lastBuildDate>
                            <language>en</language>
                                <item>
                                                            <title><![CDATA[ 'That’s my dealbreaker': Tom's Guide readers sound off on iPhone Duo trade-offs — and if they'll buy ]]></title>
                                                                                                <dc:content><![CDATA[ <p>The iPhone Duo has certainly got people talking (read: feverishly debating). While some are already forming an orderly line to <a href="https://www.tomsguide.com/phones/iphones/planning-to-buy-apples-foldable-iphone-duo-heres-how-to-get-one-on-launch-day">pre-order Apple’s first foldable phone</a>, others have been vocal in their criticism of Apple's first foldable phone and what you don't get for $2,000.</p><p>Tom’s Guide’s global editor-in-chief Mark Spoonauer broke down some of the trade-offs of the Duo in <a href="https://www.youtube.com/watch?v=EiAmyzzVhts">this YouTube video</a>, pulling out the Duo’s camera, lack of Face ID, weight, battery life and price as areas of concern. In response, 329 viewers left comments on the video, and 176 commented on <a href="https://www.reddit.com/r/toms_guide/comments/1wsb1kp/iphone_duo_7_features_youre_giving_up_by_not/">our related Reddit post</a>. </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/EiAmyzzVhts" allowfullscreen></iframe></div></div><p>For some, certain specs seem to be dealbreakers, while others expressed they’re excited to become day one adopters of the new tech regardless. </p><p>Let’s dig into the crowd reaction – and please do leave your thoughts in the comments and poll below.</p><h3 class="article-body__section" id="section-just-because-it-s-2k-doesn-t-mean-it-needs-top-shelf-cameras"><span>“Just because it's $2k doesn't mean it needs top shelf cameras”</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="P3tEYZC3x2BZsheo9XqbWc" name="Apple iPhone Duo hands on-6" alt="iPhone Duo hands on" src="https://cdn.mos.cms.futurecdn.net/P3tEYZC3x2BZsheo9XqbWc-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Mark pointed out the Duo doesn’t have a telephoto camera, so zoomed photos will look blurrier than those from the iPhone 18 Pro Max (which by the way costs $800 less and also has the new <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-variable-aperture-camera-explained-heres-what-it-actually-does">variable aperture</a>). The price-to-camera quality equation is definitely one that feels a little off, and it was this point that attracted the most opinions from our YouTube viewers and Redditors.</p><div><blockquote><p>“I kinda like the Duo. But I’m not paying top dollar for a worse camera. That’s the biggest issue.”</p><p>Throwtheamiibosaway</p></blockquote></div><p>@EricK-vw5wh was one viewer who wasn’t too concerned by the camera, writing, “I think people need to remember that these things are smartphones, not dedicated cameras. Nowadays people act like these are digital cameras that just happen to have cellular phone feature if you want it. Just because it's $2k doesn't mean it needs top shelf cameras. You want that, get the Pros, that's what they are made for. Folding phones are meant for productivity and content consumption.”</p><p>But @FairchildV countered that the camera was an issue for them, replying, “It doesn’t need ‘top shelf’ cameras. But, I fully expect a pro camera for $2,000… For people that actually care about their photo and video quality, this could be a huge deal breaker unfortunately.”</p><p>Over on Reddit, FarBack5807 wrote, “For anyone who zooms in on things, the lack of telephoto means the duo is considerably worse at 25% the resolving power of the 17 Pro, and even worse than 14 Pro at 66% of its resolving power.”</p><p>Similarly, Throwtheamiibosaway wrote, “I kinda like the Duo. But I’m not paying top dollar for a worse camera. That’s the biggest issue.”</p><p>Rounding off the camera debate, I found this comment from @itsacookie1 on YouTube a very sensible reality check: “I think we all want the security of having the best cameras in our pocket but most of us just don't take photography seriously or post to social media enough that it matters. It's a hard choice or trade-off because we all have been conditioned to more money = better cameras as this is how ‘pro’ or bigger phones have been marketed for decades.”</p><p>It's worth mentioning at this point that when asked simply 'Would you buy the iPhone Duo?', some 63% of respondents (or 3,429 people) replied that yes, they would. Are you tempted by the Duo, or one of the other new iPhones?</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-eGbxVX"></div>                            </div>                            <script src="https://kwizly.com/embed/eGbxVX.js" async></script><h3 class="article-body__section" id="section-is-touch-id-even-a-downgrade-really"><span>Is Touch ID even a downgrade, really?</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:4573px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="tszeKHQnfPPM5b6CnmnYvd" name="iPhone Duo-3" alt="iPhone Duo hands on" src="https://cdn.mos.cms.futurecdn.net/tszeKHQnfPPM5b6CnmnYvd-1920-80.jpg" mos="" align="middle" fullscreen="" width="4573" height="2572" attribution="" endorsement="" class="inline"></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 Duo lacks Face ID as there wasn’t physically space in the form factor for the required sensors. Instead, users need to use Touch ID to unlock the phone — a tech that was phased out with the advent of the iPhone X. But is the older tech necessarily a downgrade?</p><p>@Tejae504 posted a comment that I can relate to, “I [would rather have] Touch ID when I get up at 6am my phone doesn’t recognize me 😂” </p><p>Indeed, if you’ve ever had a bad hair day, dabbled in a new makeup look or dared to try unlocking your phone while wearing sunglasses, you’ll know that Face ID isn’t always seamless. Then again, as we approach gloves season I remember that neither was Touch ID.</p><div><blockquote><p>“I [would rather have] Touch ID when I get up at 6am my phone doesn’t recognize me 😂” </p><p>@Tejae504 </p></blockquote></div><p>Another viewer unperturbed by the manual unlocking was @chocoloco9985, who said, “For lack of Face ID, yeah it sucks, but if I can unlock it with my Apple Watch I don’t think it will be that big of an issue.”</p><p>Many commenters pointed out that Apple Watch wearers will barely notice the "downgrade," as their watches will unlock the phone automatically anyway.</p><p>On the other hand, @g0nk wrote, “No FaceID is my dealbreaker. My arthritic fingers can't touch that sensor every single time.”</p><h3 class="article-body__section" id="section-nobody-needs-45-hour-battery-life-anyway"><span>Nobody needs 45-hour battery life anyway</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="K4dYCSX4YtJxxvZCenRip9" name="iphone duo display" alt="iPhone Duo hands on display" src="https://cdn.mos.cms.futurecdn.net/K4dYCSX4YtJxxvZCenRip9-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Looking into the battery life, Mark pointed out that Apple estimates the iPhone Duo is good for 24 hours of ‘normal use’ vs the Pro Max’s 30 hours.</p><p>This gap widens when it comes to video playback, when the Duo’s stamina is rated at 31 hours vs the 18 Pro Max’s 45. </p><div><blockquote><p>“Anyone with a job or that needs rest is never going to use the phone for a video playback for that many hours."</p><p>@dlsme</p></blockquote></div><p>Could this become an irritation for some users, especially as this is a phone marketed for multitasking?</p><p>@dlsme wrote on this point, “Anyone with a job or that needs rest is never going to use the phone for a video playback for that many hours. It’s a superficial first world problem, people are just looking for something to be upset about.”</p><h3 class="article-body__section" id="section-2-for-the-price-of-1"><span>2 for the price of 1</span></h3><p>A lot of viewers really did take the trouble to use our advice to help weigh up their next upgrade decision. One thoughtful comment from @Heartlessgamer_3242 said, “Unless you take pictures all the time, especially zoomed in, or are some kind of photographer using the Apple iPhone, the iPhone Duo is not a downgrade as a whole compared to the Pro/Pro Max. </p><p>"If you care only about the camera, then yes. But for someone like me that multitasks on the device and watches a lot of content and movies, I prefer the bigger screen and dual screen. And if not using the dual screen, I can close it and still have an active screen to use on the fly. I also don’t want an iPad and iPhone if now we have both in one.”</p><p>Whether the compromises are worth it for a device that can potentially replace two for the price of one is, in a nutshell, the decision facing iPhone Duo purchasers. </p><p>As Apple’s first foray into foldables, it’s not perfect, but as @out_of_focus_foto simply said, “I regret not buying the first iPhone when it was released. First gen isn’t that big of a deal.”</p><p><strong>What do you think? Let us know in the comments below.</strong></p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/planning-to-buy-apples-foldable-iphone-duo-heres-how-to-get-one-on-launch-day">Planning to buy the iPhone Duo? Here's how to get one on pre-order day</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-downgraded-my-iphone-15-pro-max-to-a-regular-iphone-17-and-i-have-zero-regrets">I 'downgraded' my iPhone 15 Pro Max to a regular iPhone 17 — and I have zero regrets</a></li><li><a href="https://www.tomsguide.com/computing/ipads/you-dont-need-the-iphone-duo-this-ipad-mini-prime-day-deal-is-the-reason-why">You don't need the iPhone Duo — this iPad mini Prime Day deal is the reason why</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/thats-my-dealbreaker-toms-guide-readers-sound-off-on-iphone-duo-trade-offs-and-if-theyll-buy</link>
                                                                            <description>
                            <![CDATA[ Tom’s Guide readers got heated in their response to the iPhone Duo 'trade-offs' — and gave their verdicts on whether they'll buy one. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">26MCZTWZozHhesRsjSQikG</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/Nx8S7eKqrH7ukWtNr669J8-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 07 Oct 2026 07:02:00 +0000</pubDate>                                                                                                                                <updated>Wed, 07 Oct 2026 08:30:29 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ ella.taylor@futurenet.com (Ella Taylor) ]]></author>                    <dc:creator><![CDATA[ Ella Taylor ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/W2nC7HFA6avQHdFNFbFPNa-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Ella is Tom’s Guide’s Engagement Editor, on a mission to get to know all about our readers, to help you with your burning questions, and to create an exciting mix of content that entices you to keep coming back to the site – whether you’re a regular reader or a &lt;a href=&quot;https://www.tomsguide.com/membership&quot;&gt;member&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;She has more than 15 years of editorial experience, graduating from Kingston University with a First Class Honours degree in Journalism in 2008. She has written for and edited magazines and websites, including fellow Future titles &lt;em&gt;TechRadar.com, CreativeBloq.com, Digital Camera magazine, NPhoto, BikeRadar.com, Mollie Makes&lt;/em&gt; and more. &lt;/p&gt;&lt;p&gt;Most recently, she was Managing Editor of &lt;em&gt;womanandhome.com&lt;/em&gt;, where she co-launched its &lt;a href=&quot;https://www.womanandhome.com/tag/quiz/&quot; target=&quot;_blank&quot;&gt;Quiz of the Day&lt;/a&gt; and led the charge for articles that actively asked readers for their views. Before that, she was Editor of professional photography website &lt;em&gt;canon-europe.com/pro&lt;/em&gt;, having worked her way up from Production Editor. As such, she&#039;s a stickler for fact-checking, has too many opinions about grammar and is easily excited by a beautiful photo.&lt;/p&gt;&lt;p&gt;A mum of two young children, she keeps fit by typically carrying at least one of them on her shoulders around the hilly streets of Bristol. When not chasing her sons around the play parks and soft plays of South West England and worshipping her three rescue cats, she&#039;s likely to be in the garden, steadily turning it from a neglected concrete jungle to a usable green space. She’s also finally embarking on a kitchen extension in May, so 2026 looks set to be a year of big home improvements and lots of builders’ tea.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/Nx8S7eKqrH7ukWtNr669J8-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone Duo closed in hand with Readers Say badge]]></media:description>                                                            <media:text><![CDATA[iPhone Duo closed in hand with Readers Say badge]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone Duo closed in hand with Readers Say badge]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/Nx8S7eKqrH7ukWtNr669J8-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The iPhone Duo has certainly got people talking (read: feverishly debating). While some are already forming an orderly line to <a href="https://www.tomsguide.com/phones/iphones/planning-to-buy-apples-foldable-iphone-duo-heres-how-to-get-one-on-launch-day">pre-order Apple’s first foldable phone</a>, others have been vocal in their criticism of Apple's first foldable phone and what you don't get for $2,000.</p><p>Tom’s Guide’s global editor-in-chief Mark Spoonauer broke down some of the trade-offs of the Duo in <a href="https://www.youtube.com/watch?v=EiAmyzzVhts">this YouTube video</a>, pulling out the Duo’s camera, lack of Face ID, weight, battery life and price as areas of concern. In response, 329 viewers left comments on the video, and 176 commented on <a href="https://www.reddit.com/r/toms_guide/comments/1wsb1kp/iphone_duo_7_features_youre_giving_up_by_not/">our related Reddit post</a>. </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/EiAmyzzVhts" allowfullscreen></iframe></div></div><p>For some, certain specs seem to be dealbreakers, while others expressed they’re excited to become day one adopters of the new tech regardless. </p><p>Let’s dig into the crowd reaction – and please do leave your thoughts in the comments and poll below.</p><h3 class="article-body__section" id="section-just-because-it-s-2k-doesn-t-mean-it-needs-top-shelf-cameras"><span>“Just because it's $2k doesn't mean it needs top shelf cameras”</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="P3tEYZC3x2BZsheo9XqbWc" name="Apple iPhone Duo hands on-6" alt="iPhone Duo hands on" src="https://cdn.mos.cms.futurecdn.net/P3tEYZC3x2BZsheo9XqbWc-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Mark pointed out the Duo doesn’t have a telephoto camera, so zoomed photos will look blurrier than those from the iPhone 18 Pro Max (which by the way costs $800 less and also has the new <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-variable-aperture-camera-explained-heres-what-it-actually-does">variable aperture</a>). The price-to-camera quality equation is definitely one that feels a little off, and it was this point that attracted the most opinions from our YouTube viewers and Redditors.</p><div><blockquote><p>“I kinda like the Duo. But I’m not paying top dollar for a worse camera. That’s the biggest issue.”</p><p>Throwtheamiibosaway</p></blockquote></div><p>@EricK-vw5wh was one viewer who wasn’t too concerned by the camera, writing, “I think people need to remember that these things are smartphones, not dedicated cameras. Nowadays people act like these are digital cameras that just happen to have cellular phone feature if you want it. Just because it's $2k doesn't mean it needs top shelf cameras. You want that, get the Pros, that's what they are made for. Folding phones are meant for productivity and content consumption.”</p><p>But @FairchildV countered that the camera was an issue for them, replying, “It doesn’t need ‘top shelf’ cameras. But, I fully expect a pro camera for $2,000… For people that actually care about their photo and video quality, this could be a huge deal breaker unfortunately.”</p><p>Over on Reddit, FarBack5807 wrote, “For anyone who zooms in on things, the lack of telephoto means the duo is considerably worse at 25% the resolving power of the 17 Pro, and even worse than 14 Pro at 66% of its resolving power.”</p><p>Similarly, Throwtheamiibosaway wrote, “I kinda like the Duo. But I’m not paying top dollar for a worse camera. That’s the biggest issue.”</p><p>Rounding off the camera debate, I found this comment from @itsacookie1 on YouTube a very sensible reality check: “I think we all want the security of having the best cameras in our pocket but most of us just don't take photography seriously or post to social media enough that it matters. It's a hard choice or trade-off because we all have been conditioned to more money = better cameras as this is how ‘pro’ or bigger phones have been marketed for decades.”</p><p>It's worth mentioning at this point that when asked simply 'Would you buy the iPhone Duo?', some 63% of respondents (or 3,429 people) replied that yes, they would. Are you tempted by the Duo, or one of the other new iPhones?</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-eGbxVX"></div>                            </div>                            <script src="https://kwizly.com/embed/eGbxVX.js" async></script><h3 class="article-body__section" id="section-is-touch-id-even-a-downgrade-really"><span>Is Touch ID even a downgrade, really?</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:4573px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="tszeKHQnfPPM5b6CnmnYvd" name="iPhone Duo-3" alt="iPhone Duo hands on" src="https://cdn.mos.cms.futurecdn.net/tszeKHQnfPPM5b6CnmnYvd-1920-80.jpg" mos="" align="middle" fullscreen="" width="4573" height="2572" attribution="" endorsement="" class="inline"></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 Duo lacks Face ID as there wasn’t physically space in the form factor for the required sensors. Instead, users need to use Touch ID to unlock the phone — a tech that was phased out with the advent of the iPhone X. But is the older tech necessarily a downgrade?</p><p>@Tejae504 posted a comment that I can relate to, “I [would rather have] Touch ID when I get up at 6am my phone doesn’t recognize me 😂” </p><p>Indeed, if you’ve ever had a bad hair day, dabbled in a new makeup look or dared to try unlocking your phone while wearing sunglasses, you’ll know that Face ID isn’t always seamless. Then again, as we approach gloves season I remember that neither was Touch ID.</p><div><blockquote><p>“I [would rather have] Touch ID when I get up at 6am my phone doesn’t recognize me 😂” </p><p>@Tejae504 </p></blockquote></div><p>Another viewer unperturbed by the manual unlocking was @chocoloco9985, who said, “For lack of Face ID, yeah it sucks, but if I can unlock it with my Apple Watch I don’t think it will be that big of an issue.”</p><p>Many commenters pointed out that Apple Watch wearers will barely notice the "downgrade," as their watches will unlock the phone automatically anyway.</p><p>On the other hand, @g0nk wrote, “No FaceID is my dealbreaker. My arthritic fingers can't touch that sensor every single time.”</p><h3 class="article-body__section" id="section-nobody-needs-45-hour-battery-life-anyway"><span>Nobody needs 45-hour battery life anyway</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="K4dYCSX4YtJxxvZCenRip9" name="iphone duo display" alt="iPhone Duo hands on display" src="https://cdn.mos.cms.futurecdn.net/K4dYCSX4YtJxxvZCenRip9-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Looking into the battery life, Mark pointed out that Apple estimates the iPhone Duo is good for 24 hours of ‘normal use’ vs the Pro Max’s 30 hours.</p><p>This gap widens when it comes to video playback, when the Duo’s stamina is rated at 31 hours vs the 18 Pro Max’s 45. </p><div><blockquote><p>“Anyone with a job or that needs rest is never going to use the phone for a video playback for that many hours."</p><p>@dlsme</p></blockquote></div><p>Could this become an irritation for some users, especially as this is a phone marketed for multitasking?</p><p>@dlsme wrote on this point, “Anyone with a job or that needs rest is never going to use the phone for a video playback for that many hours. It’s a superficial first world problem, people are just looking for something to be upset about.”</p><h3 class="article-body__section" id="section-2-for-the-price-of-1"><span>2 for the price of 1</span></h3><p>A lot of viewers really did take the trouble to use our advice to help weigh up their next upgrade decision. One thoughtful comment from @Heartlessgamer_3242 said, “Unless you take pictures all the time, especially zoomed in, or are some kind of photographer using the Apple iPhone, the iPhone Duo is not a downgrade as a whole compared to the Pro/Pro Max. </p><p>"If you care only about the camera, then yes. But for someone like me that multitasks on the device and watches a lot of content and movies, I prefer the bigger screen and dual screen. And if not using the dual screen, I can close it and still have an active screen to use on the fly. I also don’t want an iPad and iPhone if now we have both in one.”</p><p>Whether the compromises are worth it for a device that can potentially replace two for the price of one is, in a nutshell, the decision facing iPhone Duo purchasers. </p><p>As Apple’s first foray into foldables, it’s not perfect, but as @out_of_focus_foto simply said, “I regret not buying the first iPhone when it was released. First gen isn’t that big of a deal.”</p><p><strong>What do you think? Let us know in the comments below.</strong></p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/planning-to-buy-apples-foldable-iphone-duo-heres-how-to-get-one-on-launch-day">Planning to buy the iPhone Duo? Here's how to get one on pre-order day</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-downgraded-my-iphone-15-pro-max-to-a-regular-iphone-17-and-i-have-zero-regrets">I 'downgraded' my iPhone 15 Pro Max to a regular iPhone 17 — and I have zero regrets</a></li><li><a href="https://www.tomsguide.com/computing/ipads/you-dont-need-the-iphone-duo-this-ipad-mini-prime-day-deal-is-the-reason-why">You don't need the iPhone Duo — this iPad mini Prime Day deal is the reason why</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tested the iPhone 18 Pro Max vs. iPhone 15 Pro Max side-by-side: Is it time to upgrade? ]]></title>
                                                                                                <dc:content><![CDATA[ <p>In my last face-off, I drilled down into all the differences between the <a href="https://www.tomsguide.com/phones/iphones/i-tested-the-iphone-18-pro-max-vs-iphone-16-pro-max-side-by-side-should-you-upgrade">iPhone 18 Pro Max and iPhone 16 Pro Max</a>. There wasn’t a huge difference across the two-year gap separating them — but now I’m going further by taking the <a href="https://www.tomsguide.com/reviews/iphone-15-pro-max">iPhone 15 Pro Max</a> for a spin.</p><p>As I’ve said numerous times before, three years is the bare minimum you should wait before <a href="https://www.tomsguide.com/phones/ive-been-reviewing-phones-for-almost-18-years-heres-my-advice-on-when-to-upgrade-your-phone">thinking about upgrading to a new phone</a>. That’s exactly what I’m tackling in this iPhone 18 Pro Max vs. iPhone 15 Pro Max face-off, where the differences on paper are much more substantial.</p><p>But looking at specs doesn't give a clear-cut indication of how much of a difference three years actually makes. That's why I’m going to show you whether there’s enough of a generational leap to justify making the switch.</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-15-pro-max-specifications"><span>iPhone 18 Pro Max vs. iPhone 15 Pro Max: Specifications</span></h2><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>iPhone 18 Pro Max</strong></p></th><th  ><p><strong>iPhone 15 Pro Max</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p>From $1,299</p></td><td  ><p>From $1,199</p></td></tr><tr><td class="firstcol " ><p><strong>Main Display</strong></p></td><td  ><p>6.9-inch Super Retina XDR display (2,868 x 1,320)</p></td><td  ><p>6.7-inch Super Retina XDR display (2,796 x 1,290)</p></td></tr><tr><td class="firstcol " ><p><strong>Refresh Rate</strong></p></td><td  ><p>1-120Hz ProMotion</p></td><td  ><p>1-120Hz ProMotion</p></td></tr><tr><td class="firstcol " ><p><strong>Processor</strong></p></td><td  ><p>A20 Pro</p></td><td  ><p>A17 Pro</p></td></tr><tr><td class="firstcol " ><p><strong>Storage</strong></p></td><td  ><p>256GB, 512GB, 1TB, 2TB</p></td><td  ><p>256GB, 512GB, 1TB</p></td></tr><tr><td class="firstcol " ><p><strong>RAM</strong></p></td><td  ><p>12GB</p></td><td  ><p>8GB</p></td></tr><tr><td class="firstcol " ><p><strong>Front Camera</strong></p></td><td  ><p>18MP Center Stage camera (f/1.9)</p></td><td  ><p>12MP (f/1.9)</p></td></tr><tr><td class="firstcol " ><p><strong>Rear Cameras</strong></p></td><td  ><p>48MP main with variable aperture (f/1.48, f/1.8, f/2.8, f/4), 48MP ultrawide (f/2.2), 48MP telephoto w/4x optical zoom (f/2.8)</p></td><td  ><p>48MP main (f/1.78), 12MP ultrawide (f/2.2), 12MP telephoto w/5x optical zoom (f/2.8)</p></td></tr><tr><td class="firstcol " ><p><strong>Battery Capacity</strong></p></td><td  ><p>5,391 mAh </p></td><td  ><p>4,422 mAh</p></td></tr><tr><td class="firstcol " ><p><strong>Charging</strong></p></td><td  ><p>60W wired, 25W wireless</p></td><td  ><p>20W* wired, 15W wireless</p></td></tr><tr><td class="firstcol " ><p><strong>Size</strong></p></td><td  ><p>6.43 x 3.07 x 0.34 inches (163.4 x 78.0 x 8.75 mm)</p></td><td  ><p>6.29 x 3.02 x 0.32 inches (159.9 x 76.7 x 8.25 mm)</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>8.78 ounces (249 grams)</p></td><td  ><p>7.81 ounces (221 grams)</p></td></tr><tr><td class="firstcol " ><p><strong>IP Rating</strong></p></td><td  ><p>IP68</p></td><td  ><p>IP68</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Black, Silver, Glacier, Burgundy</p></td><td  ><p>Black Titanium, White Titanium, Blue Titanium, Natural Titanium</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-15-pro-max-cameras"><span>iPhone 18 Pro Max vs. iPhone 15 Pro Max: Cameras</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="j5hrsXcki8ofsjwp8MRNy5" name="iPhone 18 Pro Max vs iPhone 15 Pro Max-4" alt="iPhone 18 Pro Max vs. iPhone 15 Pro Max" src="https://cdn.mos.cms.futurecdn.net/j5hrsXcki8ofsjwp8MRNy5-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Just as before, camera performance is tops on my list because it’s the feature I rely on most. The iPhone 18 Pro Max clearly benefits from having the latest hardware — a 48MP triple-camera system complete with a mechanical variable aperture on the main lens. Other notable advantages for the iPhone 18 Pro Max include a wider maximum f/1.48 aperture that inherently allows more light to hit the sensor, as well as the wider field of view from its 18MP Center Stage front camera.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/SGfp5XiUJsGDo2kUU43cob-1920-80.jpg" alt="iPhone 18 Pro Max aperture f/4.0" /><figcaption>iPhone 18 Pro Max - Aperture f/4.0<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/QVLjmGvb9JGFx8FxZ8ByVb-1920-80.jpg" alt="iPhone 18 Pro Max aperture f/1.8" /><figcaption>iPhone 18 Pro Max - Aperture f/1.8<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>Beyond the hardware, the appeal of the iPhone 18 Pro Max lies in its Pro Controls for granular exposure adjustments, along with significantly improved video modes. For example, it can record 4K footage at 120fps and includes pro-video features I crave, such as Log recording, Cinematic mode, smart focus tracking, ProRes support, and Audio Mix.</p><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="AMBv4Ph4SJdrGjTs978Ur7" name="iPhone 18 Pro - Pro Controls" alt="iPhone 18 Pro showing Pro Controls." src="https://cdn.mos.cms.futurecdn.net/AMBv4Ph4SJdrGjTs978Ur7-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>From both a hardware and feature standpoint, the iPhone 18 Pro Max makes a compelling argument — enough to make an upgrade seem like an open-and-shut case. But hold that thought until you see the side-by-side snapshots below.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/St78X9QDjvuUCeZWzm8iaj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/G7Pot4FXPKi29SkrgGn3oa-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/AuqcbKAQUh8cVKZ7m2V6bj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/VqhmgcmbUySB4yAggcUMta-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/dBcfW8a9zY6ptNewKtpMaj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/uuSPiwVaaBxw9nfPKtCWta-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/kpX3q73AmUhUAQVypiTgaj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/wP2zDUdbb3JqpXfcHDb6Ka-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/TVbsA4kNjbU5RcnJhKn6Yj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/NcXKXd9WAJD84THqhJoiqa-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/EoF8XqFacZE5sPBCghHuXj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/eVs26hcN3gdgtUCqSgx5oa-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/bWBFeQRWahWYG3ftDzUyAj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/27eHVbPRxYdu9f2H7JiwRa-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/xHWatpNDbcdCZjeZkNPTxi-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/wenVcfqfcCKnkniTND3CqZ-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/6jYLLx3stux5qKY5QRWiai-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption><small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/mTuHcLHN6b2jsQsgsJRXUY-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption><small role="credit">John Velasco / Tom's Guide</small></figcaption></figure></figure><p>Honestly, I was hoping for a much wider divide between their camera performances, but the iPhone 15 Pro Max holds its ground in most situations. Under ideal conditions, the 15 Pro Max’s main and ultrawide cameras produce nearly the same results as the iPhone 18 Pro Max. You can see this in the daytime shots around Bryant Park, the macro flower close-up, the panorama, and even in how both phones neutralize harsh highlights.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/8S33uMW4mJRTv9yJJZkFcj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max (4x).<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/LwC5ZA2jUaVkJzksuFGroa-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max (4x).<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/jTd8cpXhzyiit7FXiXNcdj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max (8x).<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/BKMuoakDwTQuhHJ5ataDwa-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max (8x).<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/AL5Vnyypng2deBznCELC7j-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max (40x).<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/aQTmF6XmuuafpR6PxmM3ia-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max (25x).<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure></figure><p>Interestingly enough, the iPhone 15 Pro Max’s 12MP telephoto camera with 5x optical zoom actually delivers sharper results on the apartment building graffiti shown above. While the iPhone 18 Pro Max holds a clear advantage at 4x, the 15 Pro Max pulls out finer detail at 8x and 40x zoom by leaning on its dedicated telephoto shooter.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/VhBGyinAsqZh2sL6Dhmfbj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/VTey6zf8X9cwiavauGrbua-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure></figure><p>Where I do see a substantial leap is with the iPhone 18 Pro Max’s 18MP Center Stage camera. It captures noticeably crisper definition and provides a wider field of view, making it far better suited for group selfies.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/qF4iyMhPvYFVdgwLCBxssi-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/huRaNmghkbV6t6eCwW4ALZ-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/sTjEWfVe4WJoVRDsAWjcqi-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/DpkyrYPPm5x6UVcYoNzdEZ-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/yAH7qN74GgU7QVWgoF6Cmi-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/zAEGsGBKUsx9DEA2pjb8XZ-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/ZFccnQv5adezgsbRqmr6Xi-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/g929xvLqgUGkkKHDV88ouY-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/3CNi6MwngejEj7AMaNFYTi-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/FLCxmVdQsVAyHKK8BubeqY-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/F4toWWnrVGToiR68FRtaKi-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/eJDf4EvUNDNR75hWXLHJtY-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/PogZQtSQmpXQ7iefnwu3Zj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/udtM5doYuQcRBbuN8BPH5a-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/kKCFdFcFprjNjje9jfBpWj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/xo3grcytw3ucAM7D2hF2Ea-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure></figure><p>Lastly, the iPhone 18 Pro Max has the edge in low-light performance — but primarily in near-pitch-black settings. In the gallery shots along the beach boardwalk, there’s very little difference between them because ambient glow from the street lamps illuminates the scene.</p><p>But in my backyard where there’s virtually no ambient light, the iPhone 18 Pro Max clearly boosts shadows to draw out details that are otherwise lost on the 15 Pro Max.</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-15-pro-max-battery-and-charging"><span>iPhone 18 Pro Max vs. iPhone 15 Pro Max: Battery and charging</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="P4a52nEzq5jAqfBJjosuy5" name="iPhone 18 Pro Max vs iPhone 15 Pro Max-5" alt="iPhone 18 Pro Max vs. iPhone 15 Pro Max" src="https://cdn.mos.cms.futurecdn.net/P4a52nEzq5jAqfBJjosuy5-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro Max </strong></p></td><td  ><p><strong>iPhone 15 Pro Max</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Battery Size</strong></p></td><td  ><p>5,391 mAh </p></td><td  ><p>4,422 mAh</p></td></tr><tr><td class="firstcol " ><p><strong>Battery Life (hours:minutes)</strong></p></td><td  ><p>18:27 </p></td><td  ><p>14:02</p></td></tr><tr><td class="firstcol " ><p><strong>Charging level in 15 minutes</strong></p></td><td  ><p>53%</p></td><td  ><p>20%</p></td></tr><tr><td class="firstcol " ><p><strong>Charging level in 30 minutes</strong></p></td><td  ><p>80%</p></td><td  ><p>41%</p></td></tr></tbody></table></div><p>Because it’s a physically bigger device, Apple packs a much larger <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-battery-size-just-revealed-heres-the-official-capacity-from-ifixits-teardown">5,391 mAh battery inside the iPhone 18 Pro Max</a> — compared to 4,422 mAh in the 15 Pro Max. That translates to roughly a 22% increase in battery capacity, but our test results show that Apple has also made massive strides in power efficiency.</p><p>In our custom battery drain test, the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-18-pro-battery-life-tested-the-results-are-surprising">iPhone 18 Pro Max clocked in at 18 hours and 27 minutes</a>, which blows past the <a href="https://www.tomsguide.com/news/iphone-15-battery-life-tested">15 Pro Max’s 14 hours and 2 minutes</a>. That’s a 4-hour and 25-minute difference — a 31.5% improvement in endurance — that I credit largely to the efficiency of the <a href="https://www.tomsguide.com/phones/iphones/apple-a20-pro-chip-why-its-such-a-big-deal-for-the-iphone-ultra-and-iphone-18-pro-max">A20 Pro chip</a>. In day-to-day use, the difference is night and day.</p><p>Charging is also significantly faster across the board, both wired and wireless. In just 15 minutes over USB-C, the iPhone 18 Pro Max reaches a 53% charge, compared to just 20% on the 15 Pro Max.</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-15-pro-max-performance"><span>iPhone 18 Pro Max vs. iPhone 15 Pro Max: Performance</span></h2><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro Max</strong></p></td><td  ><p><strong>iPhone 15 Pro Max</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Chipset</strong></p></td><td  ><p>A20 Pro</p></td><td  ><p>A17 Pro</p></td></tr><tr><td class="firstcol " ><p><strong>Geekbench 6 (single / multi-core)</strong></p></td><td  ><p>4,741 / 12,789</p></td><td  ><p>2,783 / 6,945</p></td></tr><tr><td class="firstcol " ><p><strong>3DMark Solar Bay Unlimited (fps / score)</strong></p></td><td  ><p>67.9 fps / 17,850</p></td><td  ><p>23.9 fps / 6,283</p></td></tr></tbody></table></div><p>Both phones feel fast and fluid during everyday tasks, thanks to their 120Hz ProMotion displays. But for more processor-intensive workloads — like editing 4K footage or playing demanding games — the newer A20 Pro chip holds a decisive advantage over the older A17 Pro. Simply put, there is no contest.</p><p>Looking at our Geekbench 6 scores, there's nearly a 2,000-point spread in single-core performance and a massive 5,800-point gap in multi-core. That translates to a 70.4% leap in single-core speeds for the iPhone 18 Pro Max and an even larger 84.2% boost in multi-core muscle.</p><p>While those CPU gains are substantial, the iPhone 18 Pro Max’s graphics performance is where the generational gap truly widens. In 3DMark’s Solar Bay Unlimited test, the iPhone 18 Pro Max averaged 67.9 fps, making the 15 Pro Max’s 23.9 fps look choppy by comparison. That represents an astonishing 184.1% leap in graphics capability — a gain bolstered by the 18 Pro Max's redesigned internal vapor chamber, a cooling advantage the iPhone 15 Pro Max lacks entirely.</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-15-pro-max-software-and-ai"><span>iPhone 18 Pro Max vs. iPhone 15 Pro Max: Software and AI</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="UokDSRt3CZpCZ2Yq655236" name="iPhone 18 Pro Max vs iPhone 15 Pro Max-2" alt="iPhone 18 Pro Max vs. iPhone 15 Pro Max" src="https://cdn.mos.cms.futurecdn.net/UokDSRt3CZpCZ2Yq655236-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I won’t spend too much time hashing out their software and AI features because they’re practically identical — save for a couple of details. That’s the beauty of Apple supporting older flagships with its latest platform update: <a href="https://www.tomsguide.com/phones/iphones/ios-27-is-live-heres-how-to-download-and-install-it-now">iOS 27</a>. The release brings the older iPhone 15 Pro Max to near-complete parity with the iPhone 18 Pro Max, delivering the <a href="https://www.tomsguide.com/phones/iphones/apple-added-5-new-lock-screen-tools-in-ios-27-heres-what-to-change-first">Liquid Glass </a>interface, refreshed customization tools, and core system tweaks.</p><p>The most visible functional difference comes down to the Dynamic Island and how many Live Activities it can handle simultaneously. Thanks to the redesigned, slimmer cutout on the iPhone 18 Pro Max, it accommodates up to three Live Activities — compared to just two on the 15 Pro Max.</p><p>Under the hood, the iPhone 18 Pro Max packs 12GB of RAM, granting it extra processing muscle for the most demanding, on-device Siri AI workflows. In day-to-day practice, however, these distinctions hardly tip the scales, as the iPhone 15 Pro Max retains full access to the broader Apple Intelligence suite.</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-15-pro-max-displays"><span>iPhone 18 Pro Max vs. iPhone 15 Pro Max: Displays</span></h2><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro Max</strong></p></td><td  ><p><strong>iPhone 15 Pro Max</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Display</strong></p></td><td  ><p>6.9-inch Super Retina XDR display (2,868 x 1,320)</p></td><td  ><p>6.7-inch Super Retina XDR display (2,796 x 1,290)</p></td></tr><tr><td class="firstcol " ><p><strong>Peak Brightness</strong></p></td><td  ><p>2,326 nits</p></td><td  ><p>1,550 nits</p></td></tr><tr><td class="firstcol " ><p><strong>sRGB</strong></p></td><td  ><p>115.4%</p></td><td  ><p>119.4%</p></td></tr><tr><td class="firstcol " ><p><strong>DCI-P3</strong></p></td><td  ><p>81.8%</p></td><td  ><p>84.5%</p></td></tr><tr><td class="firstcol " ><p><strong>Delta-E</strong></p></td><td  ><p>0.26</p></td><td  ><p>0.14</p></td></tr></tbody></table></div><p>Beyond the bump from a 6.7-inch panel to a larger 6.9-inch Super Retina XDR display with the iPhone 18 Pro Max, the biggest upgrade here comes down to raw outdoor visibility. In our display testing, the iPhone 18 Pro Max hit a peak brightness of 2,326 nits — compared to the 1,550 nits measured on the iPhone 15 Pro Max.</p><p>That works out to a massive 50.06% increase in peak brightness, which is instantly noticeable when I’m outside with the sun glaring down on their screens. While the 15 Pro Max is still visible, the extra brightness just makes the 18 Pro Max much easier on the eyes.</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-15-pro-max-verdict"><span>iPhone 18 Pro Max vs. iPhone 15 Pro Max: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="tLbSjtMUhQyWZqPMXbzu26" name="iPhone 18 Pro Max vs iPhone 15 Pro Max-3" alt="iPhone 18 Pro Max vs. iPhone 15 Pro Max" src="https://cdn.mos.cms.futurecdn.net/tLbSjtMUhQyWZqPMXbzu26-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The evidence points to an obvious conclusion: the iPhone 18 Pro Max delivers a substantial enough upgrade to convince at least some iPhone 15 Pro Max owners to make the leap — even with Apple asking $100 more for its flagship.</p><p>From the raw muscle of the A20 Pro chip and a battery that lasts more than four hours longer, to its upgraded camera hardware and professional shooting tools, this comparison proves that three years remains the sweet spot for upgrading. However, if your iPhone 15 Pro Max still offers good battery health, you can probably get by at least until Apple unveils the <a href="https://www.tomsguide.com/phones/iphones/iphone-20-leak-reveals-7-jaw-dropping-features-for-the-20th-anniversary-model">iPhone 20</a> next year.</p><p>While day-to-day photo quality remains neck and neck in most scenarios, the iPhone 18 Pro Max pulls away in other areas. Between the mechanical variable aperture on the main lens, dedicated Pro Controls, and an expanded suite of pro-grade video tools, it offers more than enough tangible upgrades to justify the jump for power users.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Od2mme"></div>                            </div>                            <script src="https://kwizly.com/embed/Od2mme.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="">I tested the iPhone 18 Pro Max vs. iPhone 16 Pro Max side-by-side: Should you upgrade?</a></li><li><a href="https://www.tomsguide.com/entertainment/streaming/9-new-movies-and-shows-to-stream-this-weekend-on-netflix-hbo-max-and-more-oct-2-4">9 new movies and shows to stream this weekend on Netflix, HBO Max and more (Oct. 2-4)</a></li><li><a href="https://www.tomsguide.com/phones/pre-ordering-iphone-duo-3-big-reasons-to-consider-galaxy-z-fold-8-first">4 ways Samsung's Galaxy Z Fold 8 beats Apple iPhone Duo</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/i-tested-the-iphone-18-pro-max-vs-iphone-15-pro-max-side-by-side-is-it-time-to-upgrade</link>
                                                                            <description>
                            <![CDATA[ I put the iPhone 18 Pro Max and iPhone 15 Pro Max to the test to see if the three-year gap between them is enough to justify to the latest flagship. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">D87UxzHC6yNzGN7BukYBGH</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/9MAKbyUSoTSBGoLxPNcnw5-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 07 Oct 2026 04:30:00 +0000</pubDate>                                                                                                                                <updated>Wed, 07 Oct 2026 08:30:29 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ john.velasco@futurenet.com (John Velasco) ]]></author>                    <dc:creator><![CDATA[ John Velasco ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/TSj224oX8d5ERXaDs8pDGd-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/9MAKbyUSoTSBGoLxPNcnw5-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 18 Pro Max vs. iPhone 15 Pro Max]]></media:description>                                                            <media:text><![CDATA[iPhone 18 Pro Max vs. iPhone 15 Pro Max]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 18 Pro Max vs. iPhone 15 Pro Max]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/9MAKbyUSoTSBGoLxPNcnw5-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>In my last face-off, I drilled down into all the differences between the <a href="https://www.tomsguide.com/phones/iphones/i-tested-the-iphone-18-pro-max-vs-iphone-16-pro-max-side-by-side-should-you-upgrade">iPhone 18 Pro Max and iPhone 16 Pro Max</a>. There wasn’t a huge difference across the two-year gap separating them — but now I’m going further by taking the <a href="https://www.tomsguide.com/reviews/iphone-15-pro-max">iPhone 15 Pro Max</a> for a spin.</p><p>As I’ve said numerous times before, three years is the bare minimum you should wait before <a href="https://www.tomsguide.com/phones/ive-been-reviewing-phones-for-almost-18-years-heres-my-advice-on-when-to-upgrade-your-phone">thinking about upgrading to a new phone</a>. That’s exactly what I’m tackling in this iPhone 18 Pro Max vs. iPhone 15 Pro Max face-off, where the differences on paper are much more substantial.</p><p>But looking at specs doesn't give a clear-cut indication of how much of a difference three years actually makes. That's why I’m going to show you whether there’s enough of a generational leap to justify making the switch.</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-15-pro-max-specifications"><span>iPhone 18 Pro Max vs. iPhone 15 Pro Max: Specifications</span></h2><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>iPhone 18 Pro Max</strong></p></th><th  ><p><strong>iPhone 15 Pro Max</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p>From $1,299</p></td><td  ><p>From $1,199</p></td></tr><tr><td class="firstcol " ><p><strong>Main Display</strong></p></td><td  ><p>6.9-inch Super Retina XDR display (2,868 x 1,320)</p></td><td  ><p>6.7-inch Super Retina XDR display (2,796 x 1,290)</p></td></tr><tr><td class="firstcol " ><p><strong>Refresh Rate</strong></p></td><td  ><p>1-120Hz ProMotion</p></td><td  ><p>1-120Hz ProMotion</p></td></tr><tr><td class="firstcol " ><p><strong>Processor</strong></p></td><td  ><p>A20 Pro</p></td><td  ><p>A17 Pro</p></td></tr><tr><td class="firstcol " ><p><strong>Storage</strong></p></td><td  ><p>256GB, 512GB, 1TB, 2TB</p></td><td  ><p>256GB, 512GB, 1TB</p></td></tr><tr><td class="firstcol " ><p><strong>RAM</strong></p></td><td  ><p>12GB</p></td><td  ><p>8GB</p></td></tr><tr><td class="firstcol " ><p><strong>Front Camera</strong></p></td><td  ><p>18MP Center Stage camera (f/1.9)</p></td><td  ><p>12MP (f/1.9)</p></td></tr><tr><td class="firstcol " ><p><strong>Rear Cameras</strong></p></td><td  ><p>48MP main with variable aperture (f/1.48, f/1.8, f/2.8, f/4), 48MP ultrawide (f/2.2), 48MP telephoto w/4x optical zoom (f/2.8)</p></td><td  ><p>48MP main (f/1.78), 12MP ultrawide (f/2.2), 12MP telephoto w/5x optical zoom (f/2.8)</p></td></tr><tr><td class="firstcol " ><p><strong>Battery Capacity</strong></p></td><td  ><p>5,391 mAh </p></td><td  ><p>4,422 mAh</p></td></tr><tr><td class="firstcol " ><p><strong>Charging</strong></p></td><td  ><p>60W wired, 25W wireless</p></td><td  ><p>20W* wired, 15W wireless</p></td></tr><tr><td class="firstcol " ><p><strong>Size</strong></p></td><td  ><p>6.43 x 3.07 x 0.34 inches (163.4 x 78.0 x 8.75 mm)</p></td><td  ><p>6.29 x 3.02 x 0.32 inches (159.9 x 76.7 x 8.25 mm)</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>8.78 ounces (249 grams)</p></td><td  ><p>7.81 ounces (221 grams)</p></td></tr><tr><td class="firstcol " ><p><strong>IP Rating</strong></p></td><td  ><p>IP68</p></td><td  ><p>IP68</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Black, Silver, Glacier, Burgundy</p></td><td  ><p>Black Titanium, White Titanium, Blue Titanium, Natural Titanium</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-15-pro-max-cameras"><span>iPhone 18 Pro Max vs. iPhone 15 Pro Max: Cameras</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="j5hrsXcki8ofsjwp8MRNy5" name="iPhone 18 Pro Max vs iPhone 15 Pro Max-4" alt="iPhone 18 Pro Max vs. iPhone 15 Pro Max" src="https://cdn.mos.cms.futurecdn.net/j5hrsXcki8ofsjwp8MRNy5-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Just as before, camera performance is tops on my list because it’s the feature I rely on most. The iPhone 18 Pro Max clearly benefits from having the latest hardware — a 48MP triple-camera system complete with a mechanical variable aperture on the main lens. Other notable advantages for the iPhone 18 Pro Max include a wider maximum f/1.48 aperture that inherently allows more light to hit the sensor, as well as the wider field of view from its 18MP Center Stage front camera.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/SGfp5XiUJsGDo2kUU43cob-1920-80.jpg" alt="iPhone 18 Pro Max aperture f/4.0" /><figcaption>iPhone 18 Pro Max - Aperture f/4.0<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/QVLjmGvb9JGFx8FxZ8ByVb-1920-80.jpg" alt="iPhone 18 Pro Max aperture f/1.8" /><figcaption>iPhone 18 Pro Max - Aperture f/1.8<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>Beyond the hardware, the appeal of the iPhone 18 Pro Max lies in its Pro Controls for granular exposure adjustments, along with significantly improved video modes. For example, it can record 4K footage at 120fps and includes pro-video features I crave, such as Log recording, Cinematic mode, smart focus tracking, ProRes support, and Audio Mix.</p><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="AMBv4Ph4SJdrGjTs978Ur7" name="iPhone 18 Pro - Pro Controls" alt="iPhone 18 Pro showing Pro Controls." src="https://cdn.mos.cms.futurecdn.net/AMBv4Ph4SJdrGjTs978Ur7-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>From both a hardware and feature standpoint, the iPhone 18 Pro Max makes a compelling argument — enough to make an upgrade seem like an open-and-shut case. But hold that thought until you see the side-by-side snapshots below.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/St78X9QDjvuUCeZWzm8iaj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/G7Pot4FXPKi29SkrgGn3oa-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/AuqcbKAQUh8cVKZ7m2V6bj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/VqhmgcmbUySB4yAggcUMta-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/dBcfW8a9zY6ptNewKtpMaj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/uuSPiwVaaBxw9nfPKtCWta-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/kpX3q73AmUhUAQVypiTgaj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/wP2zDUdbb3JqpXfcHDb6Ka-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/TVbsA4kNjbU5RcnJhKn6Yj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/NcXKXd9WAJD84THqhJoiqa-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/EoF8XqFacZE5sPBCghHuXj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/eVs26hcN3gdgtUCqSgx5oa-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/bWBFeQRWahWYG3ftDzUyAj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/27eHVbPRxYdu9f2H7JiwRa-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/xHWatpNDbcdCZjeZkNPTxi-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/wenVcfqfcCKnkniTND3CqZ-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/6jYLLx3stux5qKY5QRWiai-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption><small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/mTuHcLHN6b2jsQsgsJRXUY-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption><small role="credit">John Velasco / Tom's Guide</small></figcaption></figure></figure><p>Honestly, I was hoping for a much wider divide between their camera performances, but the iPhone 15 Pro Max holds its ground in most situations. Under ideal conditions, the 15 Pro Max’s main and ultrawide cameras produce nearly the same results as the iPhone 18 Pro Max. You can see this in the daytime shots around Bryant Park, the macro flower close-up, the panorama, and even in how both phones neutralize harsh highlights.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/8S33uMW4mJRTv9yJJZkFcj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max (4x).<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/LwC5ZA2jUaVkJzksuFGroa-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max (4x).<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/jTd8cpXhzyiit7FXiXNcdj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max (8x).<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/BKMuoakDwTQuhHJ5ataDwa-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max (8x).<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/AL5Vnyypng2deBznCELC7j-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max (40x).<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/aQTmF6XmuuafpR6PxmM3ia-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max (25x).<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure></figure><p>Interestingly enough, the iPhone 15 Pro Max’s 12MP telephoto camera with 5x optical zoom actually delivers sharper results on the apartment building graffiti shown above. While the iPhone 18 Pro Max holds a clear advantage at 4x, the 15 Pro Max pulls out finer detail at 8x and 40x zoom by leaning on its dedicated telephoto shooter.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/VhBGyinAsqZh2sL6Dhmfbj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/VTey6zf8X9cwiavauGrbua-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure></figure><p>Where I do see a substantial leap is with the iPhone 18 Pro Max’s 18MP Center Stage camera. It captures noticeably crisper definition and provides a wider field of view, making it far better suited for group selfies.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/qF4iyMhPvYFVdgwLCBxssi-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/huRaNmghkbV6t6eCwW4ALZ-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/sTjEWfVe4WJoVRDsAWjcqi-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/DpkyrYPPm5x6UVcYoNzdEZ-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/yAH7qN74GgU7QVWgoF6Cmi-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/zAEGsGBKUsx9DEA2pjb8XZ-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/ZFccnQv5adezgsbRqmr6Xi-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/g929xvLqgUGkkKHDV88ouY-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/3CNi6MwngejEj7AMaNFYTi-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/FLCxmVdQsVAyHKK8BubeqY-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/F4toWWnrVGToiR68FRtaKi-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/eJDf4EvUNDNR75hWXLHJtY-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/PogZQtSQmpXQ7iefnwu3Zj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/udtM5doYuQcRBbuN8BPH5a-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/kKCFdFcFprjNjje9jfBpWj-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/xo3grcytw3ucAM7D2hF2Ea-1920-80.jpg" alt="Apple iPhone 15 Pro Max camera sample." /><figcaption>iPhone 15 Pro Max.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure></figure><p>Lastly, the iPhone 18 Pro Max has the edge in low-light performance — but primarily in near-pitch-black settings. In the gallery shots along the beach boardwalk, there’s very little difference between them because ambient glow from the street lamps illuminates the scene.</p><p>But in my backyard where there’s virtually no ambient light, the iPhone 18 Pro Max clearly boosts shadows to draw out details that are otherwise lost on the 15 Pro Max.</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-15-pro-max-battery-and-charging"><span>iPhone 18 Pro Max vs. iPhone 15 Pro Max: Battery and charging</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="P4a52nEzq5jAqfBJjosuy5" name="iPhone 18 Pro Max vs iPhone 15 Pro Max-5" alt="iPhone 18 Pro Max vs. iPhone 15 Pro Max" src="https://cdn.mos.cms.futurecdn.net/P4a52nEzq5jAqfBJjosuy5-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro Max </strong></p></td><td  ><p><strong>iPhone 15 Pro Max</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Battery Size</strong></p></td><td  ><p>5,391 mAh </p></td><td  ><p>4,422 mAh</p></td></tr><tr><td class="firstcol " ><p><strong>Battery Life (hours:minutes)</strong></p></td><td  ><p>18:27 </p></td><td  ><p>14:02</p></td></tr><tr><td class="firstcol " ><p><strong>Charging level in 15 minutes</strong></p></td><td  ><p>53%</p></td><td  ><p>20%</p></td></tr><tr><td class="firstcol " ><p><strong>Charging level in 30 minutes</strong></p></td><td  ><p>80%</p></td><td  ><p>41%</p></td></tr></tbody></table></div><p>Because it’s a physically bigger device, Apple packs a much larger <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-battery-size-just-revealed-heres-the-official-capacity-from-ifixits-teardown">5,391 mAh battery inside the iPhone 18 Pro Max</a> — compared to 4,422 mAh in the 15 Pro Max. That translates to roughly a 22% increase in battery capacity, but our test results show that Apple has also made massive strides in power efficiency.</p><p>In our custom battery drain test, the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-18-pro-battery-life-tested-the-results-are-surprising">iPhone 18 Pro Max clocked in at 18 hours and 27 minutes</a>, which blows past the <a href="https://www.tomsguide.com/news/iphone-15-battery-life-tested">15 Pro Max’s 14 hours and 2 minutes</a>. That’s a 4-hour and 25-minute difference — a 31.5% improvement in endurance — that I credit largely to the efficiency of the <a href="https://www.tomsguide.com/phones/iphones/apple-a20-pro-chip-why-its-such-a-big-deal-for-the-iphone-ultra-and-iphone-18-pro-max">A20 Pro chip</a>. In day-to-day use, the difference is night and day.</p><p>Charging is also significantly faster across the board, both wired and wireless. In just 15 minutes over USB-C, the iPhone 18 Pro Max reaches a 53% charge, compared to just 20% on the 15 Pro Max.</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-15-pro-max-performance"><span>iPhone 18 Pro Max vs. iPhone 15 Pro Max: Performance</span></h2><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro Max</strong></p></td><td  ><p><strong>iPhone 15 Pro Max</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Chipset</strong></p></td><td  ><p>A20 Pro</p></td><td  ><p>A17 Pro</p></td></tr><tr><td class="firstcol " ><p><strong>Geekbench 6 (single / multi-core)</strong></p></td><td  ><p>4,741 / 12,789</p></td><td  ><p>2,783 / 6,945</p></td></tr><tr><td class="firstcol " ><p><strong>3DMark Solar Bay Unlimited (fps / score)</strong></p></td><td  ><p>67.9 fps / 17,850</p></td><td  ><p>23.9 fps / 6,283</p></td></tr></tbody></table></div><p>Both phones feel fast and fluid during everyday tasks, thanks to their 120Hz ProMotion displays. But for more processor-intensive workloads — like editing 4K footage or playing demanding games — the newer A20 Pro chip holds a decisive advantage over the older A17 Pro. Simply put, there is no contest.</p><p>Looking at our Geekbench 6 scores, there's nearly a 2,000-point spread in single-core performance and a massive 5,800-point gap in multi-core. That translates to a 70.4% leap in single-core speeds for the iPhone 18 Pro Max and an even larger 84.2% boost in multi-core muscle.</p><p>While those CPU gains are substantial, the iPhone 18 Pro Max’s graphics performance is where the generational gap truly widens. In 3DMark’s Solar Bay Unlimited test, the iPhone 18 Pro Max averaged 67.9 fps, making the 15 Pro Max’s 23.9 fps look choppy by comparison. That represents an astonishing 184.1% leap in graphics capability — a gain bolstered by the 18 Pro Max's redesigned internal vapor chamber, a cooling advantage the iPhone 15 Pro Max lacks entirely.</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-15-pro-max-software-and-ai"><span>iPhone 18 Pro Max vs. iPhone 15 Pro Max: Software and AI</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="UokDSRt3CZpCZ2Yq655236" name="iPhone 18 Pro Max vs iPhone 15 Pro Max-2" alt="iPhone 18 Pro Max vs. iPhone 15 Pro Max" src="https://cdn.mos.cms.futurecdn.net/UokDSRt3CZpCZ2Yq655236-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I won’t spend too much time hashing out their software and AI features because they’re practically identical — save for a couple of details. That’s the beauty of Apple supporting older flagships with its latest platform update: <a href="https://www.tomsguide.com/phones/iphones/ios-27-is-live-heres-how-to-download-and-install-it-now">iOS 27</a>. The release brings the older iPhone 15 Pro Max to near-complete parity with the iPhone 18 Pro Max, delivering the <a href="https://www.tomsguide.com/phones/iphones/apple-added-5-new-lock-screen-tools-in-ios-27-heres-what-to-change-first">Liquid Glass </a>interface, refreshed customization tools, and core system tweaks.</p><p>The most visible functional difference comes down to the Dynamic Island and how many Live Activities it can handle simultaneously. Thanks to the redesigned, slimmer cutout on the iPhone 18 Pro Max, it accommodates up to three Live Activities — compared to just two on the 15 Pro Max.</p><p>Under the hood, the iPhone 18 Pro Max packs 12GB of RAM, granting it extra processing muscle for the most demanding, on-device Siri AI workflows. In day-to-day practice, however, these distinctions hardly tip the scales, as the iPhone 15 Pro Max retains full access to the broader Apple Intelligence suite.</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-15-pro-max-displays"><span>iPhone 18 Pro Max vs. iPhone 15 Pro Max: Displays</span></h2><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro Max</strong></p></td><td  ><p><strong>iPhone 15 Pro Max</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Display</strong></p></td><td  ><p>6.9-inch Super Retina XDR display (2,868 x 1,320)</p></td><td  ><p>6.7-inch Super Retina XDR display (2,796 x 1,290)</p></td></tr><tr><td class="firstcol " ><p><strong>Peak Brightness</strong></p></td><td  ><p>2,326 nits</p></td><td  ><p>1,550 nits</p></td></tr><tr><td class="firstcol " ><p><strong>sRGB</strong></p></td><td  ><p>115.4%</p></td><td  ><p>119.4%</p></td></tr><tr><td class="firstcol " ><p><strong>DCI-P3</strong></p></td><td  ><p>81.8%</p></td><td  ><p>84.5%</p></td></tr><tr><td class="firstcol " ><p><strong>Delta-E</strong></p></td><td  ><p>0.26</p></td><td  ><p>0.14</p></td></tr></tbody></table></div><p>Beyond the bump from a 6.7-inch panel to a larger 6.9-inch Super Retina XDR display with the iPhone 18 Pro Max, the biggest upgrade here comes down to raw outdoor visibility. In our display testing, the iPhone 18 Pro Max hit a peak brightness of 2,326 nits — compared to the 1,550 nits measured on the iPhone 15 Pro Max.</p><p>That works out to a massive 50.06% increase in peak brightness, which is instantly noticeable when I’m outside with the sun glaring down on their screens. While the 15 Pro Max is still visible, the extra brightness just makes the 18 Pro Max much easier on the eyes.</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-15-pro-max-verdict"><span>iPhone 18 Pro Max vs. iPhone 15 Pro Max: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="tLbSjtMUhQyWZqPMXbzu26" name="iPhone 18 Pro Max vs iPhone 15 Pro Max-3" alt="iPhone 18 Pro Max vs. iPhone 15 Pro Max" src="https://cdn.mos.cms.futurecdn.net/tLbSjtMUhQyWZqPMXbzu26-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The evidence points to an obvious conclusion: the iPhone 18 Pro Max delivers a substantial enough upgrade to convince at least some iPhone 15 Pro Max owners to make the leap — even with Apple asking $100 more for its flagship.</p><p>From the raw muscle of the A20 Pro chip and a battery that lasts more than four hours longer, to its upgraded camera hardware and professional shooting tools, this comparison proves that three years remains the sweet spot for upgrading. However, if your iPhone 15 Pro Max still offers good battery health, you can probably get by at least until Apple unveils the <a href="https://www.tomsguide.com/phones/iphones/iphone-20-leak-reveals-7-jaw-dropping-features-for-the-20th-anniversary-model">iPhone 20</a> next year.</p><p>While day-to-day photo quality remains neck and neck in most scenarios, the iPhone 18 Pro Max pulls away in other areas. Between the mechanical variable aperture on the main lens, dedicated Pro Controls, and an expanded suite of pro-grade video tools, it offers more than enough tangible upgrades to justify the jump for power users.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Od2mme"></div>                            </div>                            <script src="https://kwizly.com/embed/Od2mme.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="">I tested the iPhone 18 Pro Max vs. iPhone 16 Pro Max side-by-side: Should you upgrade?</a></li><li><a href="https://www.tomsguide.com/entertainment/streaming/9-new-movies-and-shows-to-stream-this-weekend-on-netflix-hbo-max-and-more-oct-2-4">9 new movies and shows to stream this weekend on Netflix, HBO Max and more (Oct. 2-4)</a></li><li><a href="https://www.tomsguide.com/phones/pre-ordering-iphone-duo-3-big-reasons-to-consider-galaxy-z-fold-8-first">4 ways Samsung's Galaxy Z Fold 8 beats Apple iPhone Duo</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Planning to buy the iPhone Duo? Here's how to get one on pre-order day ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Securing the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo </a>on pre-order day is going to be a battle. Between massive global interest in Apple’s first foldable and notoriously tight initial stock, opening inventory could disappear in seconds. </p><p><strong>Pre-orders open strictly at 5:00 a.m. PT on Friday, October 16</strong>, ahead of the official October 23 launch across major international markets (with a secondary rollout starting October 30).</p><p>If you want to bypass long backorder delays and ensure your foldable lands on your doorstep on day one, here's the game plan to follow. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xj2RQX"></div>                            </div>                            <script src="https://kwizly.com/embed/Xj2RQX.js" async></script><h3 class="article-body__section" id="section-how-to-guarantee-your-iphone-duo-before-pre-order-day"><span>How to guarantee your iPhone Duo before pre-order day</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="XFCxXSuM9ujaXaBT7dqk2g" name="iphone duo software-2" alt="iPhone Duo software" src="https://cdn.mos.cms.futurecdn.net/XFCxXSuM9ujaXaBT7dqk2g-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><h2 id="1-lock-in-quot-get-ready-quot-on-oct-12">1. Lock in "Get Ready" on Oct 12</h2><p>Don't wait for pre-order day. Four days before the drop, Apple opens its pre-order portal. Head into the Apple Store app on October 12 to pick your color, storage capacity, carrier status, and payment method ahead of time — allowing you to complete the entire purchase with a single tap the moment the clock strikes 5:00 a.m.</p><h2 id="2-audit-your-apple-account-details-today">2. Audit your Apple Account details today </h2><p>A single wrong digit will knock you out of the queue. Verify that your credit card hasn't expired, your billing address matches your bank records, and your shipping address is up to date.</p><h2 id="3-secure-your-trade-in-quote-early">3. Secure your trade-in quote early</h2><p>Navigating trade-in questions during checkout adds unnecessary screens to your purchase. Get your valuation sorted in advance to bypass those extra steps on drop morning. The 14-day clock to return your old phone only starts once your iPhone Duo is physically delivered.</p><h2 id="4-confirm-your-financing-options">4. Confirm your financing options</h2><p>Apple retired its legacy Upgrade Program in mid-2026. If you financed your last device, check your account status now to see if you qualify for Apple Card Installments, carrier options, or a direct purchase.</p><h2 id="5-load-the-app-on-multiple-devices">5. Load the app on multiple devices</h2><p>The Apple Store app usually goes live faster than the desktop website. Have the app open and ready on your phone, but keep a desktop browser open on Apple’s site as a secondary backup just in case.</p><h2 id="6-stick-strictly-to-your-saved-setup">6. Stick strictly to your saved setup</h2><p>Once pre-orders open, load your saved configuration and hit pay. Avoid changing your color choice or storage size at the last second — altering your basket re-queries Apple’s live inventory systems and risks pushing back your shipping date.</p><h2 id="7-pivot-to-in-store-pickup">7. Pivot to in-store pickup</h2><p>If shipping dates start sliding into November during checkout, select local Apple Store pickup instead. Retail stores receive dedicated inventory allocations completely separate from warehouse delivery stocks, making it the ultimate safety net for launch-day possession.</p><h2 id="8-check-launch-morning-store-stock">8. Check launch-morning store stock</h2><p>If you miss iPhone Duo pre-orders entirely, physical Apple Stores routinely save dedicated stock for launch day walk-ins on October 23. Check Apple's online store tracker early on launch morning to grab unallocated local store stock.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><a href="https://www.tomsguide.com/phones/ios-27-has-a-hidden-anti-scam-setting-heres-why-every-iphone-user-should-turn-it-on">iOS 27 has a hidden anti-scam setting — here’s why every iPhone user should turn it on</a></li><li><a href="https://www.tomsguide.com/phones/the-new-iphone-feature-in-ios-27-im-using-every-single-day-and-where-to-find-it">There's a new shortcut in iOS 27 I’m using every single day — here's where to find it</a></li><li><a href="https://www.tomsguide.com/phones/apple-gave-the-notes-app-massive-upgrades-in-ios-27-and-now-its-a-legitimate-writing-tool">4 new iOS 27 features that turn Apple Notes into a productivity powerhouse</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/planning-to-buy-apples-foldable-iphone-duo-heres-how-to-get-one-on-launch-day</link>
                                                                            <description>
                            <![CDATA[ Score the iPhone Duo on launch day. Essential pre-order hacks, checkout strategies, and Apple Store tips to secure your foldable on October 16. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">ZncWi3qUYDX7V8Msg487iQ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/PivA8XMLx8JvKvycCoarDc-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 06 Oct 2026 07:30:00 +0000</pubDate>                                                                                                                                <updated>Tue, 06 Oct 2026 15:42:09 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ kaycee.hill@futurenet.com (Kaycee Hill) ]]></author>                    <dc:creator><![CDATA[ Kaycee Hill ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/xHn6RmpEqg87cvtLwrBu9G-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/PivA8XMLx8JvKvycCoarDc-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone Duo hands on]]></media:description>                                                            <media:text><![CDATA[iPhone Duo hands on]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone Duo hands on]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/PivA8XMLx8JvKvycCoarDc-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Securing the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo </a>on pre-order day is going to be a battle. Between massive global interest in Apple’s first foldable and notoriously tight initial stock, opening inventory could disappear in seconds. </p><p><strong>Pre-orders open strictly at 5:00 a.m. PT on Friday, October 16</strong>, ahead of the official October 23 launch across major international markets (with a secondary rollout starting October 30).</p><p>If you want to bypass long backorder delays and ensure your foldable lands on your doorstep on day one, here's the game plan to follow. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xj2RQX"></div>                            </div>                            <script src="https://kwizly.com/embed/Xj2RQX.js" async></script><h3 class="article-body__section" id="section-how-to-guarantee-your-iphone-duo-before-pre-order-day"><span>How to guarantee your iPhone Duo before pre-order day</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="XFCxXSuM9ujaXaBT7dqk2g" name="iphone duo software-2" alt="iPhone Duo software" src="https://cdn.mos.cms.futurecdn.net/XFCxXSuM9ujaXaBT7dqk2g-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><h2 id="1-lock-in-quot-get-ready-quot-on-oct-12">1. Lock in "Get Ready" on Oct 12</h2><p>Don't wait for pre-order day. Four days before the drop, Apple opens its pre-order portal. Head into the Apple Store app on October 12 to pick your color, storage capacity, carrier status, and payment method ahead of time — allowing you to complete the entire purchase with a single tap the moment the clock strikes 5:00 a.m.</p><h2 id="2-audit-your-apple-account-details-today">2. Audit your Apple Account details today </h2><p>A single wrong digit will knock you out of the queue. Verify that your credit card hasn't expired, your billing address matches your bank records, and your shipping address is up to date.</p><h2 id="3-secure-your-trade-in-quote-early">3. Secure your trade-in quote early</h2><p>Navigating trade-in questions during checkout adds unnecessary screens to your purchase. Get your valuation sorted in advance to bypass those extra steps on drop morning. The 14-day clock to return your old phone only starts once your iPhone Duo is physically delivered.</p><h2 id="4-confirm-your-financing-options">4. Confirm your financing options</h2><p>Apple retired its legacy Upgrade Program in mid-2026. If you financed your last device, check your account status now to see if you qualify for Apple Card Installments, carrier options, or a direct purchase.</p><h2 id="5-load-the-app-on-multiple-devices">5. Load the app on multiple devices</h2><p>The Apple Store app usually goes live faster than the desktop website. Have the app open and ready on your phone, but keep a desktop browser open on Apple’s site as a secondary backup just in case.</p><h2 id="6-stick-strictly-to-your-saved-setup">6. Stick strictly to your saved setup</h2><p>Once pre-orders open, load your saved configuration and hit pay. Avoid changing your color choice or storage size at the last second — altering your basket re-queries Apple’s live inventory systems and risks pushing back your shipping date.</p><h2 id="7-pivot-to-in-store-pickup">7. Pivot to in-store pickup</h2><p>If shipping dates start sliding into November during checkout, select local Apple Store pickup instead. Retail stores receive dedicated inventory allocations completely separate from warehouse delivery stocks, making it the ultimate safety net for launch-day possession.</p><h2 id="8-check-launch-morning-store-stock">8. Check launch-morning store stock</h2><p>If you miss iPhone Duo pre-orders entirely, physical Apple Stores routinely save dedicated stock for launch day walk-ins on October 23. Check Apple's online store tracker early on launch morning to grab unallocated local store stock.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><a href="https://www.tomsguide.com/phones/ios-27-has-a-hidden-anti-scam-setting-heres-why-every-iphone-user-should-turn-it-on">iOS 27 has a hidden anti-scam setting — here’s why every iPhone user should turn it on</a></li><li><a href="https://www.tomsguide.com/phones/the-new-iphone-feature-in-ios-27-im-using-every-single-day-and-where-to-find-it">There's a new shortcut in iOS 27 I’m using every single day — here's where to find it</a></li><li><a href="https://www.tomsguide.com/phones/apple-gave-the-notes-app-massive-upgrades-in-ios-27-and-now-its-a-legitimate-writing-tool">4 new iOS 27 features that turn Apple Notes into a productivity powerhouse</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I 'downgraded' my iPhone 15 Pro Max to a regular iPhone 17 — and I have zero regrets ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Every few years, I get trapped in the classic Apple upgrade loop. Three years ago, I jumped up from an <a href="https://www.tomsguide.com/reviews/iphone-12-pro-max">iPhone 12 Pro Max</a> to a 512GB <a href="https://www.tomsguide.com/reviews/iphone-15-pro-max">iPhone 15 Pro Max</a> for its big screen and flagship camera specs. This year I was ready to do the same for the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max</a> — until I saw the insane prices, even with trade-in values added in.</p><p>Making things urgent, my trusty iPhone was aging. Despite my best efforts, the battery health steadily declined over the years and a minor issue with the USB-C port popped up when charging it one day. </p><p>Thinking about having to pay nearly $600 for out-of-warranty repairs, $100 for a new battery, or dropping $1,000 for the latest iPhone 18 Pro Max, I decided to do something I’ve never done before: give up on the iPhone’s Pro tier altogether.  </p><p>I traded in my 15 Pro Max and bought a base 256GB <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-17-review">iPhone 17</a> instead. Sure, I might have given up storage space, camera features, and the screen might be smaller, but moving to a standard iPhone <em>didn't</em> feel like a downgrade from an older iPhone Pro model. Here’s why it was a relief to me, and my wallet.</p><h2 id="the-price-conundrum">The price conundrum </h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="YoXiWMqiePrsfprmyChu3C" name="iPhone 15 Pro Max vs iPhone 17" alt="iPhone 15 Pro Max vs iPhone 17." src="https://cdn.mos.cms.futurecdn.net/YoXiWMqiePrsfprmyChu3C-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Times are tough, and with the cost of living going up in NYC, the biggest factor in my decision was the iPhone pricing. With Apple’s trade-in values, I get a lot for my old iPhone Pro model when trading it in for a base-tier iPhone 17. It almost felt like a steal.</p><p>While it would have been nice to get a new Pro iPhone again, the price didn’t make sense for my wallet. Trading in a 512GB iPhone 15 Pro Max for the same 512GB iPhone 18 Pro Max 512GB would have been $1,044 — with Apple paying me $455 in trade-in value. I had also considered the 512GB iPhone 18 Pro which would have been $944 with the same offer.</p><div><blockquote><p>The biggest factor in my decision was the iPhone pricing.</p></blockquote></div><p>Dropping down to 256GB would have also saved me $200 from that on either model, bringing the 18 Pro Max down to $844 and the standard 18 Pro down to $744 after trade-in, but it was still steep.</p><p>I went for the iPhone 17 256GB instead, it was just $444 with the same $455 trade-in. I might have had to clean up apps and photos from my old iPhone before making the switch to 256GB, but I saved $600 compared to getting the iPhone 18 Pro Max. Or $500 vs getting the iPhone 18 Pro. Considering all the features the base iPhone 17 has to offer, this wasn’t too bad of a choice. </p><h2 id="i-still-have-plenty-of-39-pro-39-features">I still have plenty of 'Pro' features</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3840px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="EuB89rgWQ2icAdo6z8WSae" name="Apple iPhone 17 review" alt="Apple iPhone 17 playing 4K HDR video." src="https://cdn.mos.cms.futurecdn.net/EuB89rgWQ2icAdo6z8WSae-1920-80.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / John Velasco)</span></figcaption></figure><p>The biggest appeal for the iPhone Pro series to me was always the bigger screen and the top-level features. As my life evolved, though, I realized that I didn’t need a huge screen. Moving away from the iPhone 15’s Pro Max 6.7-inch screen to iPhone 17’s base 6.3-inch screen was surprisingly seamless to me, and my new phone still felt like an iPhone Pro.</p><p>Those 0.4 inches in screen real estate didn’t make a huge difference for me. With super thin bezels on the iPhone 17, I still see the same content on screen in social media and work apps that I had before. And even better, the base iPhone 17 features ProMotion, so I got the same 120Hz refresh rates I am used to from my old phone. </p><p>I even got display upgrades! With the iPhone 17 topping out at 3,000 nits vs the 2,000 nits, my new phone was brighter and better to use outdoors. The new ceramic Ceramic Shield 2 screen also gives the screen better durability, since I go for a case and screen protector free look.</p><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="hdvETEDBB4obJDurMJnJKe" name="Apple iPhone 17 review" alt="Apple iPhone 17 running Diablo Immortal." src="https://cdn.mos.cms.futurecdn.net/hdvETEDBB4obJDurMJnJKe-1920-80.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / John Velasco)</span></figcaption></figure><p>Performance and battery life improvements were there, too. The new A19 chip also made things feel snappier than before. And despite the iPhone 17 having a slightly smaller 3,692 mAh battery against the iPhone 15 Pro Max’s 4,422 mAh, I am now able to charge my phone only once every two days, something I never was able to do with my 15 Pro Max’s degraded battery. </p><p>I never realized that the base model iPhone could bring this much performance, display tech, and battery optimization from an older Pro phone, it doesn't just feel like a great value, it still feels like a Pro-level experience.</p><h2 id="the-camera-is-just-fine">The camera is just fine</h2><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="Gr6qkNuJhJL7hDjWWVddDe" name="Apple iPhone 17 review" alt="Apple iPhone 17 review." src="https://cdn.mos.cms.futurecdn.net/Gr6qkNuJhJL7hDjWWVddDe-1920-80.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / John Velasco)</span></figcaption></figure><p>My biggest reason for always buying a Pro iPhone was the extra telephoto lens. The base iPhone 17 lacks that, so I was worried that I would regret losing it, but I didn’t. In fact, the iPhone 17’s camera system was an upgrade. </p><p>Thinking back, the only times I found myself using my telephoto lens was at Mets games or other in-person events. Even then, the photo quality was not as good as a dedicated camera and it was just something I used occasionally. For everything else I do, the dual camera system on the iPhone 17 has been just as good for taking pictures for social media, product shots for work, and everyday video recording. </p><p>What's more notable to me, though, was the <a href="https://www.tomsguide.com/phones/iphones/i-tested-the-iphone-17-vs-iphone-16-selfie-camera-heres-what-i-found">Center Stage front camera</a>. Being able to tap to zoom and rotate made my Facetime calls with my long distance friends more personal. Selfie videos were much more stabilized than on my previous iPhone, and the dual capture feature has been a blast when capturing video moments around the city for my friends in other states. </p><h2 id="you-might-want-to-make-the-switch-too">You might want to make the switch, too</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="a5qRRPnbBiweP8bGf7s7aC" name="iPhone 15 Pro Max vs iPhone 17" alt="iPhone 15 Pro Max vs iPhone 17." src="https://cdn.mos.cms.futurecdn.net/a5qRRPnbBiweP8bGf7s7aC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>With Apple hiking prices across the entire iPhone lineup, trading in an older, degrading iPhone for a new base model might be your best option. You might end up like me: stepping back and considering what you truly need from a phone before buying. Not everyone needs “Pro” features, and given how capable base iPhones have become, the distinction between models is clearer than ever — so a base model might be the upgrade you didn't realize you needed.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-evyZ9X"></div>                            </div>                            <script src="https://kwizly.com/embed/evyZ9X.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="">I tested the iPhone 18 Pro Max vs. iPhone 16 Pro Max side-by-side: Should you upgrade?</a></li><li><a href="https://www.tomsguide.com/entertainment/streaming/9-new-movies-and-shows-to-stream-this-weekend-on-netflix-hbo-max-and-more-oct-2-4">9 new movies and shows to stream this weekend on Netflix, HBO Max and more (Oct. 2-4)</a></li><li><a href="https://www.tomsguide.com/phones/pre-ordering-iphone-duo-3-big-reasons-to-consider-galaxy-z-fold-8-first">4 ways Samsung's Galaxy Z Fold 8 beats Apple iPhone Duo</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/i-downgraded-my-iphone-15-pro-max-to-a-regular-iphone-17-and-i-have-zero-regrets</link>
                                                                            <description>
                            <![CDATA[ Due to Apple's price increases this year, I traded my iPhone 15 Pro Max and ended up buying a base iPhone 17 instead. And I have zero regrets about it. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">rDS7sHMWiMDDpyyfnNRrXh</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/vbjrULH9d7QWErEJs7C43C-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 06 Oct 2026 04:00:00 +0000</pubDate>                                                                                                                                <updated>Tue, 06 Oct 2026 08:20:37 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                                    <dc:creator><![CDATA[ Arif Bacchus ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/45MeDeb7Xn988jfZfHW7UG-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/vbjrULH9d7QWErEJs7C43C-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 15 Pro Max vs iPhone 17.]]></media:description>                                                            <media:text><![CDATA[iPhone 15 Pro Max vs iPhone 17.]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 15 Pro Max vs iPhone 17.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/vbjrULH9d7QWErEJs7C43C-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Every few years, I get trapped in the classic Apple upgrade loop. Three years ago, I jumped up from an <a href="https://www.tomsguide.com/reviews/iphone-12-pro-max">iPhone 12 Pro Max</a> to a 512GB <a href="https://www.tomsguide.com/reviews/iphone-15-pro-max">iPhone 15 Pro Max</a> for its big screen and flagship camera specs. This year I was ready to do the same for the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max</a> — until I saw the insane prices, even with trade-in values added in.</p><p>Making things urgent, my trusty iPhone was aging. Despite my best efforts, the battery health steadily declined over the years and a minor issue with the USB-C port popped up when charging it one day. </p><p>Thinking about having to pay nearly $600 for out-of-warranty repairs, $100 for a new battery, or dropping $1,000 for the latest iPhone 18 Pro Max, I decided to do something I’ve never done before: give up on the iPhone’s Pro tier altogether.  </p><p>I traded in my 15 Pro Max and bought a base 256GB <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-17-review">iPhone 17</a> instead. Sure, I might have given up storage space, camera features, and the screen might be smaller, but moving to a standard iPhone <em>didn't</em> feel like a downgrade from an older iPhone Pro model. Here’s why it was a relief to me, and my wallet.</p><h2 id="the-price-conundrum">The price conundrum </h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="YoXiWMqiePrsfprmyChu3C" name="iPhone 15 Pro Max vs iPhone 17" alt="iPhone 15 Pro Max vs iPhone 17." src="https://cdn.mos.cms.futurecdn.net/YoXiWMqiePrsfprmyChu3C-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Times are tough, and with the cost of living going up in NYC, the biggest factor in my decision was the iPhone pricing. With Apple’s trade-in values, I get a lot for my old iPhone Pro model when trading it in for a base-tier iPhone 17. It almost felt like a steal.</p><p>While it would have been nice to get a new Pro iPhone again, the price didn’t make sense for my wallet. Trading in a 512GB iPhone 15 Pro Max for the same 512GB iPhone 18 Pro Max 512GB would have been $1,044 — with Apple paying me $455 in trade-in value. I had also considered the 512GB iPhone 18 Pro which would have been $944 with the same offer.</p><div><blockquote><p>The biggest factor in my decision was the iPhone pricing.</p></blockquote></div><p>Dropping down to 256GB would have also saved me $200 from that on either model, bringing the 18 Pro Max down to $844 and the standard 18 Pro down to $744 after trade-in, but it was still steep.</p><p>I went for the iPhone 17 256GB instead, it was just $444 with the same $455 trade-in. I might have had to clean up apps and photos from my old iPhone before making the switch to 256GB, but I saved $600 compared to getting the iPhone 18 Pro Max. Or $500 vs getting the iPhone 18 Pro. Considering all the features the base iPhone 17 has to offer, this wasn’t too bad of a choice. </p><h2 id="i-still-have-plenty-of-39-pro-39-features">I still have plenty of 'Pro' features</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3840px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="EuB89rgWQ2icAdo6z8WSae" name="Apple iPhone 17 review" alt="Apple iPhone 17 playing 4K HDR video." src="https://cdn.mos.cms.futurecdn.net/EuB89rgWQ2icAdo6z8WSae-1920-80.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / John Velasco)</span></figcaption></figure><p>The biggest appeal for the iPhone Pro series to me was always the bigger screen and the top-level features. As my life evolved, though, I realized that I didn’t need a huge screen. Moving away from the iPhone 15’s Pro Max 6.7-inch screen to iPhone 17’s base 6.3-inch screen was surprisingly seamless to me, and my new phone still felt like an iPhone Pro.</p><p>Those 0.4 inches in screen real estate didn’t make a huge difference for me. With super thin bezels on the iPhone 17, I still see the same content on screen in social media and work apps that I had before. And even better, the base iPhone 17 features ProMotion, so I got the same 120Hz refresh rates I am used to from my old phone. </p><p>I even got display upgrades! With the iPhone 17 topping out at 3,000 nits vs the 2,000 nits, my new phone was brighter and better to use outdoors. The new ceramic Ceramic Shield 2 screen also gives the screen better durability, since I go for a case and screen protector free look.</p><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="hdvETEDBB4obJDurMJnJKe" name="Apple iPhone 17 review" alt="Apple iPhone 17 running Diablo Immortal." src="https://cdn.mos.cms.futurecdn.net/hdvETEDBB4obJDurMJnJKe-1920-80.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / John Velasco)</span></figcaption></figure><p>Performance and battery life improvements were there, too. The new A19 chip also made things feel snappier than before. And despite the iPhone 17 having a slightly smaller 3,692 mAh battery against the iPhone 15 Pro Max’s 4,422 mAh, I am now able to charge my phone only once every two days, something I never was able to do with my 15 Pro Max’s degraded battery. </p><p>I never realized that the base model iPhone could bring this much performance, display tech, and battery optimization from an older Pro phone, it doesn't just feel like a great value, it still feels like a Pro-level experience.</p><h2 id="the-camera-is-just-fine">The camera is just fine</h2><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="Gr6qkNuJhJL7hDjWWVddDe" name="Apple iPhone 17 review" alt="Apple iPhone 17 review." src="https://cdn.mos.cms.futurecdn.net/Gr6qkNuJhJL7hDjWWVddDe-1920-80.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / John Velasco)</span></figcaption></figure><p>My biggest reason for always buying a Pro iPhone was the extra telephoto lens. The base iPhone 17 lacks that, so I was worried that I would regret losing it, but I didn’t. In fact, the iPhone 17’s camera system was an upgrade. </p><p>Thinking back, the only times I found myself using my telephoto lens was at Mets games or other in-person events. Even then, the photo quality was not as good as a dedicated camera and it was just something I used occasionally. For everything else I do, the dual camera system on the iPhone 17 has been just as good for taking pictures for social media, product shots for work, and everyday video recording. </p><p>What's more notable to me, though, was the <a href="https://www.tomsguide.com/phones/iphones/i-tested-the-iphone-17-vs-iphone-16-selfie-camera-heres-what-i-found">Center Stage front camera</a>. Being able to tap to zoom and rotate made my Facetime calls with my long distance friends more personal. Selfie videos were much more stabilized than on my previous iPhone, and the dual capture feature has been a blast when capturing video moments around the city for my friends in other states. </p><h2 id="you-might-want-to-make-the-switch-too">You might want to make the switch, too</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="a5qRRPnbBiweP8bGf7s7aC" name="iPhone 15 Pro Max vs iPhone 17" alt="iPhone 15 Pro Max vs iPhone 17." src="https://cdn.mos.cms.futurecdn.net/a5qRRPnbBiweP8bGf7s7aC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>With Apple hiking prices across the entire iPhone lineup, trading in an older, degrading iPhone for a new base model might be your best option. You might end up like me: stepping back and considering what you truly need from a phone before buying. Not everyone needs “Pro” features, and given how capable base iPhones have become, the distinction between models is clearer than ever — so a base model might be the upgrade you didn't realize you needed.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-evyZ9X"></div>                            </div>                            <script src="https://kwizly.com/embed/evyZ9X.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="">I tested the iPhone 18 Pro Max vs. iPhone 16 Pro Max side-by-side: Should you upgrade?</a></li><li><a href="https://www.tomsguide.com/entertainment/streaming/9-new-movies-and-shows-to-stream-this-weekend-on-netflix-hbo-max-and-more-oct-2-4">9 new movies and shows to stream this weekend on Netflix, HBO Max and more (Oct. 2-4)</a></li><li><a href="https://www.tomsguide.com/phones/pre-ordering-iphone-duo-3-big-reasons-to-consider-galaxy-z-fold-8-first">4 ways Samsung's Galaxy Z Fold 8 beats Apple iPhone Duo</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Apple and AT&T confirm iPhone 18 Pro Max connectivity issues — here's why you need to go to an Apple or AT&T store to get a hardware replacement ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Late last week, <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-problems-so-far-popping-noises-at-and-t-issues-and-more">we reported on a slew</a> of <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max</a> issues, including one that affected cellular connectivity for AT&T versions of Apple's newest phone.</p><p>Unfortunately, in an update from Apple, you might need to replace an affected <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max</a> at the Apple Store.</p><p>Simply put, brand-new Pro Max phones were starting in SOS mode and not connecting to <a href="https://www.tomsguide.com/deals/best-atandt-phone-deals">AT&T's network</a>, or they were operating slowly when they did connect. AT&T acknowledged the problem and told Tom's Guide that the carrier was working with Apple on it.</p>                    <div class= "tiktok-wrapper" style="min-height: 750px;"><blockquote class="tiktok-embed" cite="https://www.tiktok.com/@tomsguide/video/7683725116030700813" data-video-id="7683725116030700813" style="max-width: 605px; min-width: 325px;">                        <section>                            <a target="_blank" title="@tomsguide" href="https://www.tiktok.com/@tomsguide">@tomsguide</a>                            <p></p><a target="_blank" title="♬ Court of Funk - Taped Onto Plastic" href="https://www.tiktok.com/music/Court-of-Funk-7682222858525575178">♬ Court of Funk - Taped Onto Plastic</a></section>                    </blockquote></div>                <p>"Our top priority is ensuring customers can stay connected when they need it most, and we are working with Apple to make it right," an AT&T spokesperson said.</p><p>At the time, both Apple and AT&T were encouraging iPhone 18 Pro Max owners to update to iOS 27.0.1, which was meant to fix the issue.</p><p>"We released iOS 27.0.1 earlier this week and strongly encourage all iPhone 18 Pro Max users to update now, and are also issuing a carrier settings update today," an Apple spokesperson told Tom's Guide. "These updates together are meant to help prevent this issue from occurring.”</p><p>However, if you already have an affected device without service, you can't reactivate it via software. Apple confirmed that you will need to go to an Apple or AT&T store to get a hardware replacement.</p><p>Tom's Guide was told that this issue has only been observed with the iPhone 18 Pro Max on the AT&T network. We have reached out to AT&T to confirm the information that we received from Apple.</p><p>Notably, the US version of the Pro Max is the only new iPhone that utilizes a <a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20">Qualcomm cellular modem</a>. The Pro model and <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> feature Apple's in-house-designed <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-teardown-reveals-the-ins-and-outs-of-the-latest-iphone-models-including-one-annoying-repair-issue">C2 modem</a>. However, it's unclear whether that is causing the problems, since no other carrier appears to be affected.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/computing/online-security/apple-issues-emergency-update-for-millions-of-iphones-ipads-and-macs-update-your-devices-now"><strong>Apple issues emergency update for millions of iPhones, iPads, and Macs — update your devices now</strong></a></li><li><a href="https://www.tomsguide.com/home/smart-home/apples-homepad-reportedly-coming-oct-13-7-features-you-need-to-know"><strong>Apple's HomePad reportedly coming Oct. 13 — 7 features you need to know</strong></a></li><li><a href="https://www.tomsguide.com/phones/apple-gave-the-notes-app-massive-upgrades-in-ios-27-and-now-its-a-legitimate-writing-tool"><strong>4 new iOS 27 features that turn Apple Notes into a productivity powerhouse</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/apple-and-at-and-t-confirm-iphone-18-pro-max-connectivity-issues-heres-why-you-need-to-go-to-an-apple-or-at-and-t-store-to-get-a-hardware-replacement</link>
                                                                            <description>
                            <![CDATA[ Apple has confirmed that iPhone 18 Pro Max devices on AT&T may need replacement because of a connectivity bug. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">aq46ZNzsLqwxaMg5SjWGaP</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/MNt6boVo4QsPRZW9F5qafB-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 05 Oct 2026 17:27:54 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ scott.younker@futurenet.com (Scott Younker) ]]></author>                    <dc:creator><![CDATA[ Scott Younker ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/RZsUpqcJ6Uj2q83oCUwNhQ-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Scott Younker is the West Coast Reporter at Tom’s Guide. He covers all the latest tech news, including phones, computing and more. He’s been involved in tech since 2011 covering everything from cameras and swimming pool equipment to the latest gaming consoles and smart TVs. He is on a seemingly never ending hunt to build the easiest to use home media system. &lt;/p&gt;&lt;p&gt;Before Tom’s Guide, Scott worked for publications like &lt;em&gt;Digital Trends, Outdoor Photographer, Dead Beats Panel&lt;/em&gt;, and in a brief detour, &lt;em&gt;America’s Funniest Home Videos&lt;/em&gt;. Yes, he has seen more pratfalls, silly pets and ridiculous home movie fails than is reasonably healthy. &lt;/p&gt;&lt;p&gt;When not writing about the latest devices or advances in chipsets, be sure to ask about Scott about disc golf and sustainability, or just if you’re being cheeky, ask about his noodle arm. If you truly want to get nerdy, bring up board games and his ongoing losing streak. &lt;/p&gt;&lt;p&gt;Scott joined Tom&#039;s Guide in 2024 as the West Coast Reporter. He graduated from the School of Journalism at the University of Oregon with a degree in magazine journalism and a minor in communications. While there he blogged or wrote for several magazines including the Fluxx, Ethos and the Oregon Commentator. He briefly wrote and managed a moderately successful blog focused on web comics. &lt;br&gt;Send secure tips on Signal: scyo1.55.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/MNt6boVo4QsPRZW9F5qafB-1920-80.jpg">
                                                            <media:credit><![CDATA[John Velasco / Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 18 Pro Max camera.]]></media:description>                                                            <media:text><![CDATA[iPhone 18 Pro Max camera.]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 18 Pro Max camera.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/MNt6boVo4QsPRZW9F5qafB-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Late last week, <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-problems-so-far-popping-noises-at-and-t-issues-and-more">we reported on a slew</a> of <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max</a> issues, including one that affected cellular connectivity for AT&T versions of Apple's newest phone.</p><p>Unfortunately, in an update from Apple, you might need to replace an affected <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max</a> at the Apple Store.</p><p>Simply put, brand-new Pro Max phones were starting in SOS mode and not connecting to <a href="https://www.tomsguide.com/deals/best-atandt-phone-deals">AT&T's network</a>, or they were operating slowly when they did connect. AT&T acknowledged the problem and told Tom's Guide that the carrier was working with Apple on it.</p>                    <div class= "tiktok-wrapper" style="min-height: 750px;"><blockquote class="tiktok-embed" cite="https://www.tiktok.com/@tomsguide/video/7683725116030700813" data-video-id="7683725116030700813" style="max-width: 605px; min-width: 325px;">                        <section>                            <a target="_blank" title="@tomsguide" href="https://www.tiktok.com/@tomsguide">@tomsguide</a>                            <p></p><a target="_blank" title="♬ Court of Funk - Taped Onto Plastic" href="https://www.tiktok.com/music/Court-of-Funk-7682222858525575178">♬ Court of Funk - Taped Onto Plastic</a></section>                    </blockquote></div>                <p>"Our top priority is ensuring customers can stay connected when they need it most, and we are working with Apple to make it right," an AT&T spokesperson said.</p><p>At the time, both Apple and AT&T were encouraging iPhone 18 Pro Max owners to update to iOS 27.0.1, which was meant to fix the issue.</p><p>"We released iOS 27.0.1 earlier this week and strongly encourage all iPhone 18 Pro Max users to update now, and are also issuing a carrier settings update today," an Apple spokesperson told Tom's Guide. "These updates together are meant to help prevent this issue from occurring.”</p><p>However, if you already have an affected device without service, you can't reactivate it via software. Apple confirmed that you will need to go to an Apple or AT&T store to get a hardware replacement.</p><p>Tom's Guide was told that this issue has only been observed with the iPhone 18 Pro Max on the AT&T network. We have reached out to AT&T to confirm the information that we received from Apple.</p><p>Notably, the US version of the Pro Max is the only new iPhone that utilizes a <a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20">Qualcomm cellular modem</a>. The Pro model and <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> feature Apple's in-house-designed <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-teardown-reveals-the-ins-and-outs-of-the-latest-iphone-models-including-one-annoying-repair-issue">C2 modem</a>. However, it's unclear whether that is causing the problems, since no other carrier appears to be affected.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/computing/online-security/apple-issues-emergency-update-for-millions-of-iphones-ipads-and-macs-update-your-devices-now"><strong>Apple issues emergency update for millions of iPhones, iPads, and Macs — update your devices now</strong></a></li><li><a href="https://www.tomsguide.com/home/smart-home/apples-homepad-reportedly-coming-oct-13-7-features-you-need-to-know"><strong>Apple's HomePad reportedly coming Oct. 13 — 7 features you need to know</strong></a></li><li><a href="https://www.tomsguide.com/phones/apple-gave-the-notes-app-massive-upgrades-in-ios-27-and-now-its-a-legitimate-writing-tool"><strong>4 new iOS 27 features that turn Apple Notes into a productivity powerhouse</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tested the iPhone 18 Pro vs iPhone 16 Pro to see if a two-year upgrade makes sense ]]></title>
                                                                                                <dc:content><![CDATA[ <p>The <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-16-pro-review">iPhone 16 Pro</a> is only a couple of years old and remains a very capable handset. But with the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review#section-iphone-18-pro-and-pro-max-price-and-release-date">iPhone 18 Pro</a> now out in the wild and offering several big performance improvements, many people may be weighing up whether it’s time to upgrade.</p><p>A good general rule of thumb is to upgrade every 3 or 4 years, but owners switching from an iPhone 16 Pro to Apple’s latest effort will immediately see a few changes. The camera island has become a camera plateau, the chassis has ditched titanium for aluminum and the Dynamic Island has noticeably shrunk.</p><p>Having used both phones, I can give you the full breakdown on how they compare in my iPhone 18 Pro vs iPhone 16 Pro face-off. Back in 2024, the 16 Pro impressed on its debut with features like an upgraded 48MP ultra-wide camera, 4K 120 fps slow-mo videos and Audio Mix. In 2026, the 18 Pro takes things to an even higher level — albeit <a href="https://www.tomsguide.com/phones/iphones/verizon-is-practically-giving-away-the-iphone-18-pro-heres-how-to-get-it">for an increased cost</a>. So, is it worth making the switch? </p><p>Read my full breakdown below to find out.</p><h2 class="article-body__section" id="section-iphone-18-pro-vs-iphone-16-pro-specifications"><span>iPhone 18 Pro vs. iPhone 16 Pro: Specifications</span></h2><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>iPhone 18 Pro</strong></p></th><th  ><p><strong>iPhone 16 Pro</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p>From $1199/£1,199/AU$2,099</p></td><td  ><p>From $999/£999/AU$1,799</p></td></tr><tr><td class="firstcol " ><p><strong>Main Display</strong></p></td><td  ><p>6.3-inch Super Retina XDR display (2,622 x 1,206)</p></td><td  ><p>6.3-inch Super Retina XDR display (2,622 x 1,206)</p></td></tr><tr><td class="firstcol " ><p><strong>Refresh Rate</strong></p></td><td  ><p>1-120Hz ProMotion</p></td><td  ><p>1-120Hz ProMotion</p></td></tr><tr><td class="firstcol " ><p><strong>Processor</strong></p></td><td  ><p>A20 Pro</p></td><td  ><p>A18 Pro</p></td></tr><tr><td class="firstcol " ><p><strong>Storage</strong></p></td><td  ><p>256GB, 512GB, 1TB, 2TB</p></td><td  ><p>256GB, 512GB, 1TB</p></td></tr><tr><td class="firstcol " ><p><strong>RAM</strong></p></td><td  ><p>12GB</p></td><td  ><p>12GB</p></td></tr><tr><td class="firstcol " ><p><strong>Front Camera</strong></p></td><td  ><p>18MP Center Stage camera (f/1.9)</p></td><td  ><p>12MP (f/1.9)</p></td></tr><tr><td class="firstcol " ><p><strong>Rear Cameras</strong></p></td><td  ><p>48MP main with variable aperture (f/1.48, f/1.8, f/2.8, f/4), 48MP ultrawide (f/2.2), 48MP telephoto w/4x optical zoom (f/2.8)</p></td><td  ><p>48MP main (f/1.78), 48MP ultrawide (f/2.2), 12MP telephoto w/5x optical zoom (f/2.8)</p></td></tr><tr><td class="firstcol " ><p><strong>Battery Capacity</strong></p></td><td  ><p>4,056 mAh </p></td><td  ><p>3,582 mAh</p></td></tr><tr><td class="firstcol " ><p><strong>Charging</strong></p></td><td  ><p>60W wired, 25W wireless</p></td><td  ><p>30W wired, 25W wireless</p></td></tr><tr><td class="firstcol " ><p><strong>Size</strong></p></td><td  ><p>5.91 x 2.83 x 0.35 inches (150 x 71.9 x 8.8 mm)</p></td><td  ><p>5.89 x 2.81 x 0.33 inches (149.6 x 71.5 x 8.3 mm)</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>7.44 ounces (211 grams)</p></td><td  ><p>7.02 ounces (199 grams)</p></td></tr><tr><td class="firstcol " ><p><strong>IP Rating</strong></p></td><td  ><p>IP68</p></td><td  ><p>IP68</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Black, Silver, Glacier, Burgundy</p></td><td  ><p>Black, White, Desert, Natural Titanium</p></td></tr></tbody></table></div><div class="youtube-video" data-nosnippet ><div class="video-aspect-box"><iframe data-lazy-priority="low" data-lazy-src="https://www.youtube-nocookie.com/embed/sqaV5mFJav8" allowfullscreen></iframe></div></div><h2 class="article-body__section" id="section-iphone-18-pro-vs-iphone-16-pro-price-release"><span>iPhone 18 Pro vs. iPhone 16 Pro: Price & Release</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:58.91%;"><img id="AY9NwAjk8jcNPWGbnkLnBi" name="iPhone 18 Pro vs iPhone 16 Pro" alt="iPhone 18 Pro vs iPhone 16 Pro" src="https://cdn.mos.cms.futurecdn.net/AY9NwAjk8jcNPWGbnkLnBi-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1508" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>If you’re looking for pure value, then sticking with your older iPhone 16 Pro (or picking one up at a discount) is easily your best bet. When Apple launched it back in 2024, it came with a starting price of $999/£999/AU$1,799, which was the same price as the previous year. </p><p>Unfortunately, we can’t say the same for the iPhone 18 Pro. This year, Apple added an extra $100/£100/AU$100 to the price to account for<a href="https://www.tomsguide.com/phones/iphones/apple-confirms-significantly-higher-memory-costs-and-that-means-iphone-and-mac-price-hikes-are-almost-certainly-on-the-way"> rising DRAM costs</a> as well as manufacturing costs associated with moving to a new chip architecture. </p><p>That’s slightly offset in this comparison because Apple raised base storage in 2025 from 128GB to 256GB. So although the iPhone 18 Pro is more expensive, you’re getting double the storage from the start. Regardless, if keeping costs down is your chief concern, then I’d advise holding onto the iPhone 16 Pro for another year at least — especially as Apple may have something <a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20">interesting planned for the iPhone’s 20th anniversary next year</a>.  </p><h2 class="article-body__section" id="section-iphone-18-pro-vs-iphone-16-pro-design"><span>iPhone 18 Pro vs. iPhone 16 Pro: Design</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="PLU2EBSfRMRxqcrZGRtr4k" name="iPhone 18 Pro vs iPhone 16 Pro-4" alt="iPhone 18 Pro vs iPhone 16 Pro" src="https://cdn.mos.cms.futurecdn.net/PLU2EBSfRMRxqcrZGRtr4k-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>Apple made some notable changes last year, and while the changes between last year’s flagship and this year’s model are hard to spot, that’s not the case if you’re comparing the 18 Pro with the 16 Pro.</p><p>The two biggest design changes are the shift away from a titanium frame back to an anodized aluminum unibody used in the past and a new camera plateau. Let’s talk aluminum first. Abandoning titanium means the iPhone 18 Pro is liable to be more affected by scratches and scuffs than the older device. Also, because it’s a softer metal, you can expect the iPhone 18 Pro to be more prone to dents or dings if you happen to drop it and you don’t have it shielded by one of the best iPhone 18 Pro cases. Apple likely anticipated this, which is why the company has added Ceramic Shield toughened glass to the back of the iPhone 18 Pro.  </p><p>However, Apple is able to do a lot more optimizing by switching back to anodized aluminum. For starters, the iPhone 18 Pro is lighter at 199g / 7.03 ounces compared to the 211g / 7.44 ounces iPhone 16 Pro. Secondly, because aluminum is a better heat conductor, Apple can use the entire chassis as a heat sink to manage the thermal output of the chip. To double down on this, Apple also added a vapor chamber as part of the design change that helps the phone achieve 40% better sustained CPU/GPU performance compared to a titanium frame.</p><p>In practice, I don’t notice the difference in hand between the aluminum and titanium construction. Although titanium has that “premium” connotation, I’m happy to trade that for better performance. Time will tell if the iPhone 18 Pro chassis holds up to scratches or <a href="https://www.tomsguide.com/phones/iphones/sketchy-or-real-iphone-17-pro-in-cosmic-orange-reportedly-fading-to-rose-gold">any potential discoloration</a>, but for the most part I keep my phone in a case so it’s unlikely to be an issue for me.</p><p>The camera plateau makes the iPhone 18 Pro ever so slightly more top-heavy in the hand than the iPhone 16 Pro, but Apple has balanced the weight evenly so you quickly become used to the upgrade. I personally don’t think it looks as good as a camera island but, as we’ll see, the camera upgrades that necessitated it are more than worth having a design that looks like it’s <a href="https://www.tomsguide.com/phones/google-pixel-phones/i-checked-out-the-pixel-11-pixel-11-pro-and-pixel-11-pro-xl-heres-the-one-i-recommend">copying Google’s Pixel phones</a>.</p><p>Finally, you get a fresh set of colors for the iPhone 18 Pro that some people may appreciate. I personally really liked the Desert Titanium color on the iPhone 16 Pro, but the Burgundy colorway is also growing on me. It looks a bit more refined in the flesh and, for those who have been wanting it for years, the iPhone 18 Pro finally comes with a matte black color option. </p><h3 class="article-body__section" id="section-iphone-18-pro-vs-iphone-16-pro-display"><span>iPhone 18 Pro vs. iPhone 16 Pro: Display</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Ui3mJNktBZSXLxEFY2e53k" name="iPhone 18 Pro vs iPhone 16 Pro-5" alt="iPhone 18 Pro vs iPhone 16 Pro" src="https://cdn.mos.cms.futurecdn.net/Ui3mJNktBZSXLxEFY2e53k-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">iPhone 18 Pro (L) vs iPhone 16 Pro (R) </span><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro</strong></p></td><td  ><p><strong>iPhone 16 Pro</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Display</strong></p></td><td  ><p>6.3-inch Super Retina XDR display (2,622 x 1,206)</p></td><td  ><p>6.3-inch Super Retina XDR display (2,622 x 1,206)</p></td></tr><tr><td class="firstcol " ><p><strong>Peak Brightness (tested)</strong></p></td><td  ><p>2,314 nits</p></td><td  ><p>1,510 nits</p></td></tr><tr><td class="firstcol " ><p><strong>sRGB</strong></p></td><td  ><p>115.2%</p></td><td  ><p>113.5%</p></td></tr><tr><td class="firstcol " ><p><strong>DCI-P3</strong></p></td><td  ><p>81.6%</p></td><td  ><p>80.4%</p></td></tr><tr><td class="firstcol " ><p><strong>Delta-E</strong></p></td><td  ><p>0.19</p></td><td  ><p>0.24</p></td></tr></tbody></table></div><p>The iPhone 18 Pro has the same 6.3-inch display size as the iPhone 16 Pro, with the same resolution (2622 x 1206) and pixel density (~460 ppi). However, the newer device has a higher peak brightness of up to 3,000 nits (compared to 2,000 nits on the 16 Pro), which is noticeable when outside and in direct sunlight. That's Apple's own numbers, you can see our testing results showing peak brightness with adaptive brightness switched on in the table below. </p><p>The extra brightness is made more effective by a specialized anti-reflective display coating Apple added for the 18 Pro. It reduces ambient glare and increases contrast in bright environments, and I appreciated it when I had both phones side-by-side outdoors.</p><p>As mentioned, you also get a smaller Dynamic Island on the 18 Pro that can give you up to three Live Activities at once. In practice, this didn’t impact much on my day-to-day interaction with the phone, but it’s nice to have that pill cutout made a little bit less invasive.</p><p>Otherwise, these are the exact same screens with Apple’s ProMotion technology with adaptive refresh rates up to 120Hz. So although in this regard, I’d hand the win to the iPhone 18 Pro, I wouldn’t consider the screen itself a reason to upgrade from the iPhone 16 Pro. </p><h3 class="article-body__section" id="section-iphone-18-pro-vs-iphone-16-pro-cameras"><span>iPhone 18 Pro vs. iPhone 16 Pro: Cameras</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="AJYcftRHTd5dYsDXHMU6kj" name="iPhone 18 Pro vs iPhone 16 Pro-7" alt="iPhone 18 Pro vs iPhone 16 Pro" src="https://cdn.mos.cms.futurecdn.net/AJYcftRHTd5dYsDXHMU6kj-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>If you’re a frequent photographer, you’re going to find the upgrades present in the iPhone 18 Pro the most tempting. For starters, Apple has upgraded the 12MP Telephoto camera from the 16 Pro into a full 48MP Fusion Telephoto camera that’s now capable of up to 8x optical zoom and 40x digital zoom.</p><p>Much of the excitement around the 18 Pro comes from mechanical variable aperture and native Pro-level controls in an iPhone for the first time. Unlike the iPhone 16 Pro, which has a main camera fixed at f/1.78, the 18 Pro can move through four physical stops: f/1.48, f/1.8, f/2.8, and f/4. This means you can manually open the aperture in low light for a better shot or close it down to keep multiple subjects sharp across depths.</p><p>Accessing these controls is also now possible because Apple has, for the first time with the 18 Pro, added Pro Controls to its default camera app. Photographers can now make adjustments to things like shutter speed, ISO, white balance and manual focus. And that’s just in Apple’s own camera app. The company has said that third-party app developers will be able to utilize the mechanical aperture to offer a sliding scale rather than just the four physical stops Apple has predetermined.</p><p>Meanwhile, the 12MP selfie camera on the iPhone 16 Pro is also bested by the 18MP Center Stage camera on the 18 Pro that supports tap-to-zoom, rotation and Dual Capture, where you can record from the front and rear cameras simultaneously.</p><p>Here's how the two phones stack up across a few different pictures side-by-side.</p><iframe allow="" height="1440" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=fcbc872c-be68-11f1-ba1b-0e6f42328d7d"></iframe><p>Starting with the main shooter, there's not a whole lot of difference to my eye between the two. Colors are nicely repurposed, but the iPhone 18 smooths out some of the crispness around the petals.   </p><iframe allow="" height="1440" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=c7a7e086-be68-11f1-ba1b-0e6f42328d7d"></iframe><p>In this image, taken with each flagship's selfie camera, you can see the iPhone 18 Pro's 18MP Center Stage camera provides a wider field of view. While I think my skin tone is more even in the iPhone 18 Pro's shot, and the dynamic range is also better, I feel like the detail on my sweater is closer to true life on the iPhone 16 Pro image.</p><iframe allow="" height="1440" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=7e35bb62-be6d-11f1-ba1b-0e6f42328d7d"></iframe><iframe allow="" height="1440" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=bc561fe0-be6d-11f1-ba1b-0e6f42328d7d"></iframe><p>The two images above show the telephoto shooters on both phones. When you push the cameras to their limits — 40x on the iPhone 18 Pro and 25x on the 16 Pro — you can continue to see detail, like the outline of the brickwork around the lettering and the cracks in the wall. </p><p>The iPhone 18 Pro's zoom is obviously better but when the benefits of a digital zoom are up for debate and camera fans better informed than I will be able to speak to that. What I do think is that there's a washed out look to the iPhone 18 Pro's picture at that increased magnification that I don't see on the iPhone 16 Pro.</p><p>These are just a few small examples, and I still have more photos to take — particularly in low-light situations and experimenting with the iPhone 18 Pro's variable aperture. I'll update this article with more images when I have them, but it's clear both phones offer great dynamic range, detail, and color fidelity even before you start playing with the features.</p><h3 class="article-body__section" id="section-iphone-18-pro-vs-iphone-16-pro-performance"><span>iPhone 18 Pro vs. iPhone 16 Pro: Performance</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="kZ4Qi3Aw6CZxG3h75J5T2k" name="iPhone 18 Pro vs iPhone 16 Pro-3" alt="iPhone 18 Pro vs iPhone 16 Pro" src="https://cdn.mos.cms.futurecdn.net/kZ4Qi3Aw6CZxG3h75J5T2k-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">iPhone 18 Pro (L) vs iPhone 16 Pro (R) </span><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>Our review process has already shown that the <a href="https://www.tomsguide.com/phones/iphones/apple-a20-pro-chip-why-its-such-a-big-deal-for-the-iphone-ultra-and-iphone-18-pro-max">new 2nm A20 Pro silicon</a> inside the iPhone 18 Pro is a step-up in performance. If you’re regularly pushing an iPhone into demanding territory — like gaming or photo editing — you’ll notice faster loading times or quicker rendering. That’s not to say the A18 Pro inside the iPhone 16 Pro is sluggish, but as our testing results below show, there’s a huge gain, especially in graphical performance.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro</strong></p></td><td  ><p><strong>iPhone 16 Pro</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Chipset</strong></p></td><td  ><p>A20 Pro</p></td><td  ><p>A18 Pro</p></td></tr><tr><td class="firstcol " ><p><strong>Geekbench 6 (single / multi-core)</strong></p></td><td  ><p>4,735 / 12,800</p></td><td  ><p>3,400 / 8,391</p></td></tr><tr><td class="firstcol " ><p><strong>3DMark Solar Bay Unlimited (fps / score)</strong></p></td><td  ><p>61.9 fps / 16,288</p></td><td  ><p>28.6 fps / 7,519</p></td></tr></tbody></table></div><p>That being said, the iPhone 16 Pro was a performance powerhouse when it launched and it still carries some muscle. While interacting with apps is fast and painless with the iPhone 18 Pro, many users will be happy with the performance still offered by the older iPhone.</p><h3 class="article-body__section" id="section-iphone-18-pro-vs-iphone-16-pro-battery-charging"><span>iPhone 18 Pro vs. iPhone 16 Pro: Battery & Charging</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="tKXsdsZNHooWzHyPLbgRHi" name="iPhone 18 Pro vs iPhone 16 Pro-2" alt="iPhone 18 Pro vs iPhone 16 Pro" src="https://cdn.mos.cms.futurecdn.net/tKXsdsZNHooWzHyPLbgRHi-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>Apple increased the battery size for the iPhone 18 Pro to 4,056mAh over the 3,582mAh cell inside the iPhone 16 Pro. That’s a relatively minor 13% increase in capacity, but our real-world tests show that it makes a meaningful difference when you’re using the phone.</p><p>Apple was quick to point out during its keynote presentation that the iPhone 18 Pro contains the same battery longevity as the iPhone 17 Pro Max. So when you stack it up against a handset two years older, the difference is clear.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro </strong></p></td><td  ><p><strong>iPhone 16 Pro </strong></p></td></tr><tr><td class="firstcol " ><p><strong>Battery Size</strong></p></td><td  ><p>4,056 mAh </p></td><td  ><p>3,582 mAh</p></td></tr><tr><td class="firstcol " ><p><strong>Battery Life (hours:minutes)</strong></p></td><td  ><p>16:17 </p></td><td  ><p>14:07</p></td></tr><tr><td class="firstcol " ><p><strong>Charging level in 15 minutes</strong></p></td><td  ><p>53%</p></td><td  ><p>29%</p></td></tr><tr><td class="firstcol " ><p><strong>Charging level in 30 minutes</strong></p></td><td  ><p>80%</p></td><td  ><p>56%</p></td></tr></tbody></table></div><p>Our testing showed the iPhone 18 Pro averaged 16 hours and 17 minutes, substantially outlasting the 14 hours and 7 minutes from the iPhone 16 Pro. Not only do you get over two hours of extra power from the newer device, but you also get faster charging speeds.</p><p>The iPhone 18 Pro features upgraded 60W wired charging, nearly doubling the speed of the 16 Pro. In our tests, the 18 Pro took 15 minutes to reach 53% and 30 minutes to hit 80%. In those same timeframes, the 16 Pro charged to just 29% and 56%, respectively.</p><h2 class="article-body__section" id="section-iphone-18-pro-vs-iphone-16-pro-software-ai"><span>iPhone 18 Pro vs. iPhone 16 Pro: Software & AI</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:2667px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="BK6wAHZvbvvt9kZyzEVG96" name="iOS 27 Siri AI" alt="iOS 27 Siri AI running on iPhone 17 Pro." src="https://cdn.mos.cms.futurecdn.net/BK6wAHZvbvvt9kZyzEVG96-1920-80.jpg" mos="" align="middle" fullscreen="" width="2667" height="1500" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>The iPhone 16 Pro and iPhone 18 Pro are both capable of running<a href="https://www.tomsguide.com/phones/iphones/ios-27-is-live-heres-how-to-download-and-install-it-now"> iOS 27</a> (the latter ships with it preinstalled) so there’s almost no difference in software. All of Apple’s AI tools, like <a href="https://www.tomsguide.com/phones/i-tried-ios-27-clean-up-vs-galaxy-ai-photo-assist-in-a-7-round-test-and-i-was-surprised-with-how-close-it-was">Clean Up</a> photo editing, <a href="https://www.tomsguide.com/phones/iphones/i-just-installed-the-ios-27-beta-and-reframe-is-unlike-any-other-ai-feature-ive-come-across">Reframe</a>, and<a href="https://www.tomsguide.com/phones/iphones/how-to-create-polls-in-imessage-with-ios-26"> interactive polls in Messages</a>, are available on both phones. </p><p>It’s too early to definitively say that <a href="https://www.tomsguide.com/ai/siri-just-got-a-major-ai-upgrade-here-are-5-things-to-try-first">Siri AI</a> is <a href="https://www.tomsguide.com/ai/i-replaced-chatgpt-with-siri-ai-for-a-day-heres-what-surprised-me">preferable to ChatGPT</a> or Claude, but Apple has made Siri into a conversational assistant that answers questions and can respond to what’s on your iPhone screen. The most important thing is that it can tap into all the information on your phone to help you organize content, interact with apps and websites and respond to notifications. It’s a stepping stone towards agentic AI that anyone baked into the Apple ecosystem may appreciate.</p><h2 class="article-body__section" id="section-iphone-18-pro-vs-iphone-16-pro-verdict"><span>iPhone 18 Pro vs. iPhone 16 Pro: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="FTZVnpavjFgNYskqYktjkj" name="iPhone 18 Pro vs iPhone 16 Pro-6" alt="iPhone 18 Pro vs iPhone 16 Pro" src="https://cdn.mos.cms.futurecdn.net/FTZVnpavjFgNYskqYktjkj-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>Although I can see some very worthwhile reasons for upgrading, notably the improvements in photography controls and a performance increase for mobile gaming, I’m not convinced you need to ditch the iPhone 16 Pro for the iPhone 18 Pro. </p><p>It’s wonderful to have manual photography controls on a Pro model iPhone, as well as better battery life and the benefits of the A20 Performance. But you could look at this in the context of an “S” model iPhone. Next year will likely be an even bigger upgrade, and with the iPhone 16 Pro hitting three years old, the case for switching up at that point will be much more enticing.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ODmRmX"></div>                            </div>                            <script src="https://kwizly.com/embed/ODmRmX.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/phones/iphones/scammers-are-using-iphone-duo-pre-orders-to-try-and-steal-your-passwords-heres-how-to-stay-safe">Scammers are using iPhone Duo pre-orders to try and steal your passwords — here's how to stay safe</a></li><li><a href="https://www.tomsguide.com/phones/i-tore-my-living-room-apart-looking-for-the-apple-tv-remote-my-son-hid-but-this-hidden-iphone-feature-saved-the-day">I tore my living room apart looking for the Apple TV remote my son hid — until this iPhone feature saved the day</a></li><li><a href="https://www.tomsguide.com/phones/i-checked-out-the-new-samsung-smarttag3-heres-why-this-tracker-could-be-a-game-changer">I checked out the new Samsung SmartTag3 — here’s why this tracker could be a game-changer</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/i-put-the-iphone-18-pro-vs-iphone-16-pro-through-a-7-round-face-off-is-the-upgrade-worth-it</link>
                                                                            <description>
                            <![CDATA[ The iPhone 18 Pro offers a powerful new processor and improved photography performance, but the two-year-old iPhone 16 Pro still has a lot left to give. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">EFwaYYB8JEaGw9RXzmB9eV</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/FTZVnpavjFgNYskqYktjkj-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 05 Oct 2026 04:30:00 +0000</pubDate>                                                                                                                                <updated>Mon, 05 Oct 2026 20:04:31 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ jeff.parsons@futurenet.com (Jeff Parsons) ]]></author>                    <dc:creator><![CDATA[ Jeff Parsons ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/7z3UTGGrmSokMKxTWHmhjX-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Jeff is U.K. Editor-in-Chief for Tom’s Guide looking after the day-to-day output of the site’s British contingent. &lt;/p&gt;&lt;p&gt;Rising early and heading straight for the coffee machine, Jeff loves nothing more than dialling into the zeitgeist of the day’s tech news. A journalist for over a decade, he&#039;s travelled around the world testing and reviewing any gadget he can get his hands on.&lt;/p&gt;&lt;p&gt;Before joining the team at Tom’s Guide, Jeff covered technology and science for two of the U.K.’s biggest national news sites: Metro.co.uk and the Daily Mirror. Memorable moments include getting lost in Vienna in an electric Audi, touring Lockheed Martin’s mile-long jet factory in Fort Worth and filming a Netflix documentary about Elon Musk in West London.&lt;/p&gt;&lt;p&gt;When not plugged into the current news agenda, editing or commissioning a series of articles or debating the merits of Apple vs Android, Jeff can usually be found out for a run trying to shave precious seconds off his PB. Or lifting weights in a vain attempt to offset the ageing process.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/FTZVnpavjFgNYskqYktjkj-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide / Jeff Parsons]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 18 Pro vs iPhone 16 Pro]]></media:description>                                                            <media:text><![CDATA[iPhone 18 Pro vs iPhone 16 Pro]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 18 Pro vs iPhone 16 Pro]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/FTZVnpavjFgNYskqYktjkj-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-16-pro-review">iPhone 16 Pro</a> is only a couple of years old and remains a very capable handset. But with the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review#section-iphone-18-pro-and-pro-max-price-and-release-date">iPhone 18 Pro</a> now out in the wild and offering several big performance improvements, many people may be weighing up whether it’s time to upgrade.</p><p>A good general rule of thumb is to upgrade every 3 or 4 years, but owners switching from an iPhone 16 Pro to Apple’s latest effort will immediately see a few changes. The camera island has become a camera plateau, the chassis has ditched titanium for aluminum and the Dynamic Island has noticeably shrunk.</p><p>Having used both phones, I can give you the full breakdown on how they compare in my iPhone 18 Pro vs iPhone 16 Pro face-off. Back in 2024, the 16 Pro impressed on its debut with features like an upgraded 48MP ultra-wide camera, 4K 120 fps slow-mo videos and Audio Mix. In 2026, the 18 Pro takes things to an even higher level — albeit <a href="https://www.tomsguide.com/phones/iphones/verizon-is-practically-giving-away-the-iphone-18-pro-heres-how-to-get-it">for an increased cost</a>. So, is it worth making the switch? </p><p>Read my full breakdown below to find out.</p><h2 class="article-body__section" id="section-iphone-18-pro-vs-iphone-16-pro-specifications"><span>iPhone 18 Pro vs. iPhone 16 Pro: Specifications</span></h2><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>iPhone 18 Pro</strong></p></th><th  ><p><strong>iPhone 16 Pro</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p>From $1199/£1,199/AU$2,099</p></td><td  ><p>From $999/£999/AU$1,799</p></td></tr><tr><td class="firstcol " ><p><strong>Main Display</strong></p></td><td  ><p>6.3-inch Super Retina XDR display (2,622 x 1,206)</p></td><td  ><p>6.3-inch Super Retina XDR display (2,622 x 1,206)</p></td></tr><tr><td class="firstcol " ><p><strong>Refresh Rate</strong></p></td><td  ><p>1-120Hz ProMotion</p></td><td  ><p>1-120Hz ProMotion</p></td></tr><tr><td class="firstcol " ><p><strong>Processor</strong></p></td><td  ><p>A20 Pro</p></td><td  ><p>A18 Pro</p></td></tr><tr><td class="firstcol " ><p><strong>Storage</strong></p></td><td  ><p>256GB, 512GB, 1TB, 2TB</p></td><td  ><p>256GB, 512GB, 1TB</p></td></tr><tr><td class="firstcol " ><p><strong>RAM</strong></p></td><td  ><p>12GB</p></td><td  ><p>12GB</p></td></tr><tr><td class="firstcol " ><p><strong>Front Camera</strong></p></td><td  ><p>18MP Center Stage camera (f/1.9)</p></td><td  ><p>12MP (f/1.9)</p></td></tr><tr><td class="firstcol " ><p><strong>Rear Cameras</strong></p></td><td  ><p>48MP main with variable aperture (f/1.48, f/1.8, f/2.8, f/4), 48MP ultrawide (f/2.2), 48MP telephoto w/4x optical zoom (f/2.8)</p></td><td  ><p>48MP main (f/1.78), 48MP ultrawide (f/2.2), 12MP telephoto w/5x optical zoom (f/2.8)</p></td></tr><tr><td class="firstcol " ><p><strong>Battery Capacity</strong></p></td><td  ><p>4,056 mAh </p></td><td  ><p>3,582 mAh</p></td></tr><tr><td class="firstcol " ><p><strong>Charging</strong></p></td><td  ><p>60W wired, 25W wireless</p></td><td  ><p>30W wired, 25W wireless</p></td></tr><tr><td class="firstcol " ><p><strong>Size</strong></p></td><td  ><p>5.91 x 2.83 x 0.35 inches (150 x 71.9 x 8.8 mm)</p></td><td  ><p>5.89 x 2.81 x 0.33 inches (149.6 x 71.5 x 8.3 mm)</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>7.44 ounces (211 grams)</p></td><td  ><p>7.02 ounces (199 grams)</p></td></tr><tr><td class="firstcol " ><p><strong>IP Rating</strong></p></td><td  ><p>IP68</p></td><td  ><p>IP68</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Black, Silver, Glacier, Burgundy</p></td><td  ><p>Black, White, Desert, Natural Titanium</p></td></tr></tbody></table></div><div class="youtube-video" data-nosnippet ><div class="video-aspect-box"><iframe data-lazy-priority="low" data-lazy-src="https://www.youtube-nocookie.com/embed/sqaV5mFJav8" allowfullscreen></iframe></div></div><h2 class="article-body__section" id="section-iphone-18-pro-vs-iphone-16-pro-price-release"><span>iPhone 18 Pro vs. iPhone 16 Pro: Price & Release</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:58.91%;"><img id="AY9NwAjk8jcNPWGbnkLnBi" name="iPhone 18 Pro vs iPhone 16 Pro" alt="iPhone 18 Pro vs iPhone 16 Pro" src="https://cdn.mos.cms.futurecdn.net/AY9NwAjk8jcNPWGbnkLnBi-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1508" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>If you’re looking for pure value, then sticking with your older iPhone 16 Pro (or picking one up at a discount) is easily your best bet. When Apple launched it back in 2024, it came with a starting price of $999/£999/AU$1,799, which was the same price as the previous year. </p><p>Unfortunately, we can’t say the same for the iPhone 18 Pro. This year, Apple added an extra $100/£100/AU$100 to the price to account for<a href="https://www.tomsguide.com/phones/iphones/apple-confirms-significantly-higher-memory-costs-and-that-means-iphone-and-mac-price-hikes-are-almost-certainly-on-the-way"> rising DRAM costs</a> as well as manufacturing costs associated with moving to a new chip architecture. </p><p>That’s slightly offset in this comparison because Apple raised base storage in 2025 from 128GB to 256GB. So although the iPhone 18 Pro is more expensive, you’re getting double the storage from the start. Regardless, if keeping costs down is your chief concern, then I’d advise holding onto the iPhone 16 Pro for another year at least — especially as Apple may have something <a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20">interesting planned for the iPhone’s 20th anniversary next year</a>.  </p><h2 class="article-body__section" id="section-iphone-18-pro-vs-iphone-16-pro-design"><span>iPhone 18 Pro vs. iPhone 16 Pro: Design</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="PLU2EBSfRMRxqcrZGRtr4k" name="iPhone 18 Pro vs iPhone 16 Pro-4" alt="iPhone 18 Pro vs iPhone 16 Pro" src="https://cdn.mos.cms.futurecdn.net/PLU2EBSfRMRxqcrZGRtr4k-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>Apple made some notable changes last year, and while the changes between last year’s flagship and this year’s model are hard to spot, that’s not the case if you’re comparing the 18 Pro with the 16 Pro.</p><p>The two biggest design changes are the shift away from a titanium frame back to an anodized aluminum unibody used in the past and a new camera plateau. Let’s talk aluminum first. Abandoning titanium means the iPhone 18 Pro is liable to be more affected by scratches and scuffs than the older device. Also, because it’s a softer metal, you can expect the iPhone 18 Pro to be more prone to dents or dings if you happen to drop it and you don’t have it shielded by one of the best iPhone 18 Pro cases. Apple likely anticipated this, which is why the company has added Ceramic Shield toughened glass to the back of the iPhone 18 Pro.  </p><p>However, Apple is able to do a lot more optimizing by switching back to anodized aluminum. For starters, the iPhone 18 Pro is lighter at 199g / 7.03 ounces compared to the 211g / 7.44 ounces iPhone 16 Pro. Secondly, because aluminum is a better heat conductor, Apple can use the entire chassis as a heat sink to manage the thermal output of the chip. To double down on this, Apple also added a vapor chamber as part of the design change that helps the phone achieve 40% better sustained CPU/GPU performance compared to a titanium frame.</p><p>In practice, I don’t notice the difference in hand between the aluminum and titanium construction. Although titanium has that “premium” connotation, I’m happy to trade that for better performance. Time will tell if the iPhone 18 Pro chassis holds up to scratches or <a href="https://www.tomsguide.com/phones/iphones/sketchy-or-real-iphone-17-pro-in-cosmic-orange-reportedly-fading-to-rose-gold">any potential discoloration</a>, but for the most part I keep my phone in a case so it’s unlikely to be an issue for me.</p><p>The camera plateau makes the iPhone 18 Pro ever so slightly more top-heavy in the hand than the iPhone 16 Pro, but Apple has balanced the weight evenly so you quickly become used to the upgrade. I personally don’t think it looks as good as a camera island but, as we’ll see, the camera upgrades that necessitated it are more than worth having a design that looks like it’s <a href="https://www.tomsguide.com/phones/google-pixel-phones/i-checked-out-the-pixel-11-pixel-11-pro-and-pixel-11-pro-xl-heres-the-one-i-recommend">copying Google’s Pixel phones</a>.</p><p>Finally, you get a fresh set of colors for the iPhone 18 Pro that some people may appreciate. I personally really liked the Desert Titanium color on the iPhone 16 Pro, but the Burgundy colorway is also growing on me. It looks a bit more refined in the flesh and, for those who have been wanting it for years, the iPhone 18 Pro finally comes with a matte black color option. </p><h3 class="article-body__section" id="section-iphone-18-pro-vs-iphone-16-pro-display"><span>iPhone 18 Pro vs. iPhone 16 Pro: Display</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Ui3mJNktBZSXLxEFY2e53k" name="iPhone 18 Pro vs iPhone 16 Pro-5" alt="iPhone 18 Pro vs iPhone 16 Pro" src="https://cdn.mos.cms.futurecdn.net/Ui3mJNktBZSXLxEFY2e53k-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">iPhone 18 Pro (L) vs iPhone 16 Pro (R) </span><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro</strong></p></td><td  ><p><strong>iPhone 16 Pro</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Display</strong></p></td><td  ><p>6.3-inch Super Retina XDR display (2,622 x 1,206)</p></td><td  ><p>6.3-inch Super Retina XDR display (2,622 x 1,206)</p></td></tr><tr><td class="firstcol " ><p><strong>Peak Brightness (tested)</strong></p></td><td  ><p>2,314 nits</p></td><td  ><p>1,510 nits</p></td></tr><tr><td class="firstcol " ><p><strong>sRGB</strong></p></td><td  ><p>115.2%</p></td><td  ><p>113.5%</p></td></tr><tr><td class="firstcol " ><p><strong>DCI-P3</strong></p></td><td  ><p>81.6%</p></td><td  ><p>80.4%</p></td></tr><tr><td class="firstcol " ><p><strong>Delta-E</strong></p></td><td  ><p>0.19</p></td><td  ><p>0.24</p></td></tr></tbody></table></div><p>The iPhone 18 Pro has the same 6.3-inch display size as the iPhone 16 Pro, with the same resolution (2622 x 1206) and pixel density (~460 ppi). However, the newer device has a higher peak brightness of up to 3,000 nits (compared to 2,000 nits on the 16 Pro), which is noticeable when outside and in direct sunlight. That's Apple's own numbers, you can see our testing results showing peak brightness with adaptive brightness switched on in the table below. </p><p>The extra brightness is made more effective by a specialized anti-reflective display coating Apple added for the 18 Pro. It reduces ambient glare and increases contrast in bright environments, and I appreciated it when I had both phones side-by-side outdoors.</p><p>As mentioned, you also get a smaller Dynamic Island on the 18 Pro that can give you up to three Live Activities at once. In practice, this didn’t impact much on my day-to-day interaction with the phone, but it’s nice to have that pill cutout made a little bit less invasive.</p><p>Otherwise, these are the exact same screens with Apple’s ProMotion technology with adaptive refresh rates up to 120Hz. So although in this regard, I’d hand the win to the iPhone 18 Pro, I wouldn’t consider the screen itself a reason to upgrade from the iPhone 16 Pro. </p><h3 class="article-body__section" id="section-iphone-18-pro-vs-iphone-16-pro-cameras"><span>iPhone 18 Pro vs. iPhone 16 Pro: Cameras</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="AJYcftRHTd5dYsDXHMU6kj" name="iPhone 18 Pro vs iPhone 16 Pro-7" alt="iPhone 18 Pro vs iPhone 16 Pro" src="https://cdn.mos.cms.futurecdn.net/AJYcftRHTd5dYsDXHMU6kj-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>If you’re a frequent photographer, you’re going to find the upgrades present in the iPhone 18 Pro the most tempting. For starters, Apple has upgraded the 12MP Telephoto camera from the 16 Pro into a full 48MP Fusion Telephoto camera that’s now capable of up to 8x optical zoom and 40x digital zoom.</p><p>Much of the excitement around the 18 Pro comes from mechanical variable aperture and native Pro-level controls in an iPhone for the first time. Unlike the iPhone 16 Pro, which has a main camera fixed at f/1.78, the 18 Pro can move through four physical stops: f/1.48, f/1.8, f/2.8, and f/4. This means you can manually open the aperture in low light for a better shot or close it down to keep multiple subjects sharp across depths.</p><p>Accessing these controls is also now possible because Apple has, for the first time with the 18 Pro, added Pro Controls to its default camera app. Photographers can now make adjustments to things like shutter speed, ISO, white balance and manual focus. And that’s just in Apple’s own camera app. The company has said that third-party app developers will be able to utilize the mechanical aperture to offer a sliding scale rather than just the four physical stops Apple has predetermined.</p><p>Meanwhile, the 12MP selfie camera on the iPhone 16 Pro is also bested by the 18MP Center Stage camera on the 18 Pro that supports tap-to-zoom, rotation and Dual Capture, where you can record from the front and rear cameras simultaneously.</p><p>Here's how the two phones stack up across a few different pictures side-by-side.</p><iframe allow="" height="1440" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=fcbc872c-be68-11f1-ba1b-0e6f42328d7d"></iframe><p>Starting with the main shooter, there's not a whole lot of difference to my eye between the two. Colors are nicely repurposed, but the iPhone 18 smooths out some of the crispness around the petals.   </p><iframe allow="" height="1440" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=c7a7e086-be68-11f1-ba1b-0e6f42328d7d"></iframe><p>In this image, taken with each flagship's selfie camera, you can see the iPhone 18 Pro's 18MP Center Stage camera provides a wider field of view. While I think my skin tone is more even in the iPhone 18 Pro's shot, and the dynamic range is also better, I feel like the detail on my sweater is closer to true life on the iPhone 16 Pro image.</p><iframe allow="" height="1440" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=7e35bb62-be6d-11f1-ba1b-0e6f42328d7d"></iframe><iframe allow="" height="1440" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=bc561fe0-be6d-11f1-ba1b-0e6f42328d7d"></iframe><p>The two images above show the telephoto shooters on both phones. When you push the cameras to their limits — 40x on the iPhone 18 Pro and 25x on the 16 Pro — you can continue to see detail, like the outline of the brickwork around the lettering and the cracks in the wall. </p><p>The iPhone 18 Pro's zoom is obviously better but when the benefits of a digital zoom are up for debate and camera fans better informed than I will be able to speak to that. What I do think is that there's a washed out look to the iPhone 18 Pro's picture at that increased magnification that I don't see on the iPhone 16 Pro.</p><p>These are just a few small examples, and I still have more photos to take — particularly in low-light situations and experimenting with the iPhone 18 Pro's variable aperture. I'll update this article with more images when I have them, but it's clear both phones offer great dynamic range, detail, and color fidelity even before you start playing with the features.</p><h3 class="article-body__section" id="section-iphone-18-pro-vs-iphone-16-pro-performance"><span>iPhone 18 Pro vs. iPhone 16 Pro: Performance</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="kZ4Qi3Aw6CZxG3h75J5T2k" name="iPhone 18 Pro vs iPhone 16 Pro-3" alt="iPhone 18 Pro vs iPhone 16 Pro" src="https://cdn.mos.cms.futurecdn.net/kZ4Qi3Aw6CZxG3h75J5T2k-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">iPhone 18 Pro (L) vs iPhone 16 Pro (R) </span><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>Our review process has already shown that the <a href="https://www.tomsguide.com/phones/iphones/apple-a20-pro-chip-why-its-such-a-big-deal-for-the-iphone-ultra-and-iphone-18-pro-max">new 2nm A20 Pro silicon</a> inside the iPhone 18 Pro is a step-up in performance. If you’re regularly pushing an iPhone into demanding territory — like gaming or photo editing — you’ll notice faster loading times or quicker rendering. That’s not to say the A18 Pro inside the iPhone 16 Pro is sluggish, but as our testing results below show, there’s a huge gain, especially in graphical performance.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro</strong></p></td><td  ><p><strong>iPhone 16 Pro</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Chipset</strong></p></td><td  ><p>A20 Pro</p></td><td  ><p>A18 Pro</p></td></tr><tr><td class="firstcol " ><p><strong>Geekbench 6 (single / multi-core)</strong></p></td><td  ><p>4,735 / 12,800</p></td><td  ><p>3,400 / 8,391</p></td></tr><tr><td class="firstcol " ><p><strong>3DMark Solar Bay Unlimited (fps / score)</strong></p></td><td  ><p>61.9 fps / 16,288</p></td><td  ><p>28.6 fps / 7,519</p></td></tr></tbody></table></div><p>That being said, the iPhone 16 Pro was a performance powerhouse when it launched and it still carries some muscle. While interacting with apps is fast and painless with the iPhone 18 Pro, many users will be happy with the performance still offered by the older iPhone.</p><h3 class="article-body__section" id="section-iphone-18-pro-vs-iphone-16-pro-battery-charging"><span>iPhone 18 Pro vs. iPhone 16 Pro: Battery & Charging</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="tKXsdsZNHooWzHyPLbgRHi" name="iPhone 18 Pro vs iPhone 16 Pro-2" alt="iPhone 18 Pro vs iPhone 16 Pro" src="https://cdn.mos.cms.futurecdn.net/tKXsdsZNHooWzHyPLbgRHi-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>Apple increased the battery size for the iPhone 18 Pro to 4,056mAh over the 3,582mAh cell inside the iPhone 16 Pro. That’s a relatively minor 13% increase in capacity, but our real-world tests show that it makes a meaningful difference when you’re using the phone.</p><p>Apple was quick to point out during its keynote presentation that the iPhone 18 Pro contains the same battery longevity as the iPhone 17 Pro Max. So when you stack it up against a handset two years older, the difference is clear.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro </strong></p></td><td  ><p><strong>iPhone 16 Pro </strong></p></td></tr><tr><td class="firstcol " ><p><strong>Battery Size</strong></p></td><td  ><p>4,056 mAh </p></td><td  ><p>3,582 mAh</p></td></tr><tr><td class="firstcol " ><p><strong>Battery Life (hours:minutes)</strong></p></td><td  ><p>16:17 </p></td><td  ><p>14:07</p></td></tr><tr><td class="firstcol " ><p><strong>Charging level in 15 minutes</strong></p></td><td  ><p>53%</p></td><td  ><p>29%</p></td></tr><tr><td class="firstcol " ><p><strong>Charging level in 30 minutes</strong></p></td><td  ><p>80%</p></td><td  ><p>56%</p></td></tr></tbody></table></div><p>Our testing showed the iPhone 18 Pro averaged 16 hours and 17 minutes, substantially outlasting the 14 hours and 7 minutes from the iPhone 16 Pro. Not only do you get over two hours of extra power from the newer device, but you also get faster charging speeds.</p><p>The iPhone 18 Pro features upgraded 60W wired charging, nearly doubling the speed of the 16 Pro. In our tests, the 18 Pro took 15 minutes to reach 53% and 30 minutes to hit 80%. In those same timeframes, the 16 Pro charged to just 29% and 56%, respectively.</p><h2 class="article-body__section" id="section-iphone-18-pro-vs-iphone-16-pro-software-ai"><span>iPhone 18 Pro vs. iPhone 16 Pro: Software & AI</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:2667px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="BK6wAHZvbvvt9kZyzEVG96" name="iOS 27 Siri AI" alt="iOS 27 Siri AI running on iPhone 17 Pro." src="https://cdn.mos.cms.futurecdn.net/BK6wAHZvbvvt9kZyzEVG96-1920-80.jpg" mos="" align="middle" fullscreen="" width="2667" height="1500" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>The iPhone 16 Pro and iPhone 18 Pro are both capable of running<a href="https://www.tomsguide.com/phones/iphones/ios-27-is-live-heres-how-to-download-and-install-it-now"> iOS 27</a> (the latter ships with it preinstalled) so there’s almost no difference in software. All of Apple’s AI tools, like <a href="https://www.tomsguide.com/phones/i-tried-ios-27-clean-up-vs-galaxy-ai-photo-assist-in-a-7-round-test-and-i-was-surprised-with-how-close-it-was">Clean Up</a> photo editing, <a href="https://www.tomsguide.com/phones/iphones/i-just-installed-the-ios-27-beta-and-reframe-is-unlike-any-other-ai-feature-ive-come-across">Reframe</a>, and<a href="https://www.tomsguide.com/phones/iphones/how-to-create-polls-in-imessage-with-ios-26"> interactive polls in Messages</a>, are available on both phones. </p><p>It’s too early to definitively say that <a href="https://www.tomsguide.com/ai/siri-just-got-a-major-ai-upgrade-here-are-5-things-to-try-first">Siri AI</a> is <a href="https://www.tomsguide.com/ai/i-replaced-chatgpt-with-siri-ai-for-a-day-heres-what-surprised-me">preferable to ChatGPT</a> or Claude, but Apple has made Siri into a conversational assistant that answers questions and can respond to what’s on your iPhone screen. The most important thing is that it can tap into all the information on your phone to help you organize content, interact with apps and websites and respond to notifications. It’s a stepping stone towards agentic AI that anyone baked into the Apple ecosystem may appreciate.</p><h2 class="article-body__section" id="section-iphone-18-pro-vs-iphone-16-pro-verdict"><span>iPhone 18 Pro vs. iPhone 16 Pro: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="FTZVnpavjFgNYskqYktjkj" name="iPhone 18 Pro vs iPhone 16 Pro-6" alt="iPhone 18 Pro vs iPhone 16 Pro" src="https://cdn.mos.cms.futurecdn.net/FTZVnpavjFgNYskqYktjkj-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>Although I can see some very worthwhile reasons for upgrading, notably the improvements in photography controls and a performance increase for mobile gaming, I’m not convinced you need to ditch the iPhone 16 Pro for the iPhone 18 Pro. </p><p>It’s wonderful to have manual photography controls on a Pro model iPhone, as well as better battery life and the benefits of the A20 Performance. But you could look at this in the context of an “S” model iPhone. Next year will likely be an even bigger upgrade, and with the iPhone 16 Pro hitting three years old, the case for switching up at that point will be much more enticing.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ODmRmX"></div>                            </div>                            <script src="https://kwizly.com/embed/ODmRmX.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/phones/iphones/scammers-are-using-iphone-duo-pre-orders-to-try-and-steal-your-passwords-heres-how-to-stay-safe">Scammers are using iPhone Duo pre-orders to try and steal your passwords — here's how to stay safe</a></li><li><a href="https://www.tomsguide.com/phones/i-tore-my-living-room-apart-looking-for-the-apple-tv-remote-my-son-hid-but-this-hidden-iphone-feature-saved-the-day">I tore my living room apart looking for the Apple TV remote my son hid — until this iPhone feature saved the day</a></li><li><a href="https://www.tomsguide.com/phones/i-checked-out-the-new-samsung-smarttag3-heres-why-this-tracker-could-be-a-game-changer">I checked out the new Samsung SmartTag3 — here’s why this tracker could be a game-changer</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I was skeptical about the iPhone Duo nano-texture display — but here's why I've changed my mind ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Ever since Apple unveiled the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> last month, just about everyone who’s seen and held it hasn’t stopped raving about the hardware. Between its thin profile and that seamless-looking inner display, the iPhone Duo could really be the one to convince people to make the <a href="https://www.tomsguide.com/phones/iphones/i-spent-30-minutes-with-the-iphone-duo-3-things-you-just-dont-get-from-the-pictures">upgrade to a foldable phone</a>.</p><p>Yet, there’s one particular characteristic that has been stealing the conversation: the nano-texture coating on its 7.6-inch main display. I’ve watched enough <a href="https://www.tiktok.com/@gregsgadgets/video/7685858427007962398?is_from_webapp=1&sender_device=pc" target="_blank">videos</a> in the past couple of weeks to know that its visibility can wash out, or appear unviewable, if it’s slightly off-axis. On camera, it looks like a catastrophic design flaw for a premium device. </p><p>I was concerned at first, but the more I thought about this intentional design, the less worried I became. Here’s why.</p><h2 id="reflection-versus-diffusion">Reflection versus diffusion</h2><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="4edCqgzDe6Geozici7QFqK" name="iPhone 18 Pro and Pro Max-14" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/4edCqgzDe6Geozici7QFqK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The matte versus glossy conversation has been around for ages, but considering how the <a href="https://www.tomsguide.com/best-picks/best-phones">best phones</a> are practically all fashioned with glossy panels, coming across one that has a matte display undoubtedly evokes surprise. But honestly, it boils down to how each handles ambient light: reflection versus diffusion.</p><p>Glossy displays, like the Super AMOLED panel Samsung’s leaned on for years with its phones, offer outstanding contrast, punchy colors, ultra-wide viewing angles, and most notably deep blacks, making it hard to tell if the panel’s on or not. </p><p>While they’re certainly vibrant, the major drawback is their reflectivity. Like a mirror, glossy glass bounces light sources and causes harsh glare under direct sunlight or overhead light fixtures.</p><p>Matte screens, by contrast, incorporate a textured or chemically treated surface designed to break up incoming light rays and diffuse them. </p><p>Obviously, the immediate benefit of matte displays is glare reduction — which inherently reduces eye strain in bright environments. The trade-off is that there can be a subtle loss of contrast, slightly raised black levels in bright rooms, and reduced clarity or color pop when viewed off-axis.</p><h2 id="it-s-a-proven-tech">It’s a proven tech</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="s3KjMTgkD74XVkVFRam9Bo" name="MacBook Pro matte display-3" alt="MacBook Pro 14-inch M4 with nano-texture display on right next to M1 MacBook Pro with glossy display showing reflections" src="https://cdn.mos.cms.futurecdn.net/s3KjMTgkD74XVkVFRam9Bo-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>While seeing a matte finish on a flagship smartphone feels novel, this isn't Apple experimenting with a piece of new tech just to see if it works. </p><p>In fact, Apple has refined its nano-texture displays across its hardware lineup for years now, consistently proving that it can mitigate reflections far better than glossy screens — all without sacrificing display performance.</p><p>For example, my colleagues tested the nano-texture option on the <a href="https://www.tomsguide.com/computing/macbooks/the-new-macbook-pro-m4-is-a-game-changer-for-how-i-work-and-it-has-nothing-to-do-with-apple-intelligence">M4 MacBook Pro</a>, and it proved to be an absolute game-changer, especially under direct sunlight. Just look at the side-by-side of the two competing display technologies above. When you’re interacting directly with these devices, your vantage point is of the utmost importance — not someone’s way off to your side.</p><p>We’ve seen similar payoffs across other Apple devices, like the premium <a href="https://www.tomsguide.com/computing/monitors/i-spent-a-week-with-dual-apple-studio-displays-and-realized-ive-been-lying-to-myself-about-glossy-screens-for-years">Studio Display</a> and high-end configurations of the <a href="https://www.tomsguide.com/computing/ipads/apple-ipad-air-m4-review-small-tweaks-to-the-gold-standard">iPad Pro</a>. In just about every implementation, Apple has demonstrated that its nano-texture process avoids the muddy, low-contrast haziness typical of cheap matte films. </p><p>By bringing what it has developed and refined over the years to the iPhone Duo, Apple isn’t taking an experimental gamble.</p><h2 id="iphone-duo-will-still-be-a-test">iPhone Duo will still be a test</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:4573px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="tszeKHQnfPPM5b6CnmnYvd" name="iPhone Duo-3" alt="iPhone Duo hands on" src="https://cdn.mos.cms.futurecdn.net/tszeKHQnfPPM5b6CnmnYvd-1920-80.jpg" mos="" align="middle" fullscreen="" width="4573" height="2572" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Apple faces a steep hurdle with the iPhone Duo because it needs to convince loyalists that a matte finish is an upgrade — not a downgrade. </p><p>For nearly two decades, every iPhone has relied on glossy glass to deliver the vibrant saturation, deep blacks, and eye-popping contrast users associate with Apple's Retina displays.</p><p>I completely understand the decision Apple made here. User visibility is paramount under harsh lighting conditions, especially when there’s far more screen real estate prone to glare and reflections. </p><p>By choosing a nano-texture display, Apple ensures that visibility won’t be an issue for anyone using its upcoming foldable. That’s a big reason why I appreciate gadgets with matte screens, like <a href="https://www.tomsguide.com/phones/i-spent-a-month-with-this-usd330-smartphone-with-a-paper-like-display-and-it-completely-changed-my-mind-on-budget-phones">TCL’s NXTPAPER 70 Pro</a> and <a href="https://www.tomsguide.com/computing/android-tablets/i-thought-smaller-was-better-until-i-tried-a-massive-14-inch-tablet-that-feels-like-a-clipboard">NXTPAPER 14 tablet</a>.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Wn8BAX"></div>                            </div>                            <script src="https://kwizly.com/embed/Wn8BAX.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/phones/iphones/apple-reveals-iphone-duo-has-a-replaceable-display-layer-what-it-means-for-you"><strong>Apple reveals iPhone Duo has a 'replaceable' display layer — what it means for you</strong></a></li><li><a href="https://www.tomsguide.com/phones/apple-gave-the-notes-app-massive-upgrades-in-ios-27-and-now-its-a-legitimate-writing-tool"><strong>4 new iOS 27 features that turn Apple Notes into a productivity powerhouse</strong></a></li><li><a href="https://www.tomsguide.com/phones/pre-ordering-iphone-duo-3-big-reasons-to-consider-galaxy-z-fold-8-first"><strong>4 ways Samsung's Galaxy Z Fold 8 beats Apple iPhone Duo</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/i-was-skeptical-about-the-iphone-duo-nano-texture-display-but-heres-why-ive-changed-my-mind</link>
                                                                            <description>
                            <![CDATA[ Despite viral videos showing severe washout with the iPhone Duo’s nano-texture display, Apple's anti-glare finish is a proven technology that has real results. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">SnorwuKtALdMTMpDmaciMH</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/DdfZBhuhYSV4kGWEe54Wvd-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 03 Oct 2026 04:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[MacBooks]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                    <category><![CDATA[Laptops]]></category>
                                                                                                <author><![CDATA[ john.velasco@futurenet.com (John Velasco) ]]></author>                    <dc:creator><![CDATA[ John Velasco ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/TSj224oX8d5ERXaDs8pDGd-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/DdfZBhuhYSV4kGWEe54Wvd-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone Duo hands on]]></media:description>                                                            <media:text><![CDATA[iPhone Duo hands on]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone Duo hands on]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/DdfZBhuhYSV4kGWEe54Wvd-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Ever since Apple unveiled the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> last month, just about everyone who’s seen and held it hasn’t stopped raving about the hardware. Between its thin profile and that seamless-looking inner display, the iPhone Duo could really be the one to convince people to make the <a href="https://www.tomsguide.com/phones/iphones/i-spent-30-minutes-with-the-iphone-duo-3-things-you-just-dont-get-from-the-pictures">upgrade to a foldable phone</a>.</p><p>Yet, there’s one particular characteristic that has been stealing the conversation: the nano-texture coating on its 7.6-inch main display. I’ve watched enough <a href="https://www.tiktok.com/@gregsgadgets/video/7685858427007962398?is_from_webapp=1&sender_device=pc" target="_blank">videos</a> in the past couple of weeks to know that its visibility can wash out, or appear unviewable, if it’s slightly off-axis. On camera, it looks like a catastrophic design flaw for a premium device. </p><p>I was concerned at first, but the more I thought about this intentional design, the less worried I became. Here’s why.</p><h2 id="reflection-versus-diffusion">Reflection versus diffusion</h2><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="4edCqgzDe6Geozici7QFqK" name="iPhone 18 Pro and Pro Max-14" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/4edCqgzDe6Geozici7QFqK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The matte versus glossy conversation has been around for ages, but considering how the <a href="https://www.tomsguide.com/best-picks/best-phones">best phones</a> are practically all fashioned with glossy panels, coming across one that has a matte display undoubtedly evokes surprise. But honestly, it boils down to how each handles ambient light: reflection versus diffusion.</p><p>Glossy displays, like the Super AMOLED panel Samsung’s leaned on for years with its phones, offer outstanding contrast, punchy colors, ultra-wide viewing angles, and most notably deep blacks, making it hard to tell if the panel’s on or not. </p><p>While they’re certainly vibrant, the major drawback is their reflectivity. Like a mirror, glossy glass bounces light sources and causes harsh glare under direct sunlight or overhead light fixtures.</p><p>Matte screens, by contrast, incorporate a textured or chemically treated surface designed to break up incoming light rays and diffuse them. </p><p>Obviously, the immediate benefit of matte displays is glare reduction — which inherently reduces eye strain in bright environments. The trade-off is that there can be a subtle loss of contrast, slightly raised black levels in bright rooms, and reduced clarity or color pop when viewed off-axis.</p><h2 id="it-s-a-proven-tech">It’s a proven tech</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="s3KjMTgkD74XVkVFRam9Bo" name="MacBook Pro matte display-3" alt="MacBook Pro 14-inch M4 with nano-texture display on right next to M1 MacBook Pro with glossy display showing reflections" src="https://cdn.mos.cms.futurecdn.net/s3KjMTgkD74XVkVFRam9Bo-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>While seeing a matte finish on a flagship smartphone feels novel, this isn't Apple experimenting with a piece of new tech just to see if it works. </p><p>In fact, Apple has refined its nano-texture displays across its hardware lineup for years now, consistently proving that it can mitigate reflections far better than glossy screens — all without sacrificing display performance.</p><p>For example, my colleagues tested the nano-texture option on the <a href="https://www.tomsguide.com/computing/macbooks/the-new-macbook-pro-m4-is-a-game-changer-for-how-i-work-and-it-has-nothing-to-do-with-apple-intelligence">M4 MacBook Pro</a>, and it proved to be an absolute game-changer, especially under direct sunlight. Just look at the side-by-side of the two competing display technologies above. When you’re interacting directly with these devices, your vantage point is of the utmost importance — not someone’s way off to your side.</p><p>We’ve seen similar payoffs across other Apple devices, like the premium <a href="https://www.tomsguide.com/computing/monitors/i-spent-a-week-with-dual-apple-studio-displays-and-realized-ive-been-lying-to-myself-about-glossy-screens-for-years">Studio Display</a> and high-end configurations of the <a href="https://www.tomsguide.com/computing/ipads/apple-ipad-air-m4-review-small-tweaks-to-the-gold-standard">iPad Pro</a>. In just about every implementation, Apple has demonstrated that its nano-texture process avoids the muddy, low-contrast haziness typical of cheap matte films. </p><p>By bringing what it has developed and refined over the years to the iPhone Duo, Apple isn’t taking an experimental gamble.</p><h2 id="iphone-duo-will-still-be-a-test">iPhone Duo will still be a test</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:4573px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="tszeKHQnfPPM5b6CnmnYvd" name="iPhone Duo-3" alt="iPhone Duo hands on" src="https://cdn.mos.cms.futurecdn.net/tszeKHQnfPPM5b6CnmnYvd-1920-80.jpg" mos="" align="middle" fullscreen="" width="4573" height="2572" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Apple faces a steep hurdle with the iPhone Duo because it needs to convince loyalists that a matte finish is an upgrade — not a downgrade. </p><p>For nearly two decades, every iPhone has relied on glossy glass to deliver the vibrant saturation, deep blacks, and eye-popping contrast users associate with Apple's Retina displays.</p><p>I completely understand the decision Apple made here. User visibility is paramount under harsh lighting conditions, especially when there’s far more screen real estate prone to glare and reflections. </p><p>By choosing a nano-texture display, Apple ensures that visibility won’t be an issue for anyone using its upcoming foldable. That’s a big reason why I appreciate gadgets with matte screens, like <a href="https://www.tomsguide.com/phones/i-spent-a-month-with-this-usd330-smartphone-with-a-paper-like-display-and-it-completely-changed-my-mind-on-budget-phones">TCL’s NXTPAPER 70 Pro</a> and <a href="https://www.tomsguide.com/computing/android-tablets/i-thought-smaller-was-better-until-i-tried-a-massive-14-inch-tablet-that-feels-like-a-clipboard">NXTPAPER 14 tablet</a>.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Wn8BAX"></div>                            </div>                            <script src="https://kwizly.com/embed/Wn8BAX.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/phones/iphones/apple-reveals-iphone-duo-has-a-replaceable-display-layer-what-it-means-for-you"><strong>Apple reveals iPhone Duo has a 'replaceable' display layer — what it means for you</strong></a></li><li><a href="https://www.tomsguide.com/phones/apple-gave-the-notes-app-massive-upgrades-in-ios-27-and-now-its-a-legitimate-writing-tool"><strong>4 new iOS 27 features that turn Apple Notes into a productivity powerhouse</strong></a></li><li><a href="https://www.tomsguide.com/phones/pre-ordering-iphone-duo-3-big-reasons-to-consider-galaxy-z-fold-8-first"><strong>4 ways Samsung's Galaxy Z Fold 8 beats Apple iPhone Duo</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ iPhone 18 Pro problems so far — 'popping' noises, AT&T issues and more ]]></title>
                                                                                                <dc:content><![CDATA[ <p>We praised the iPhone 18 Pro and Pro Max as "obscenely powerful phones" in <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review#section-verdict">our full review</a> of the new Apple flagship phones, but two weeks after they hit store shelves, the newest iPhone is launching with problems.</p><p>Two separate issues are reportedly affecting cellular connectivity and the speakers on the iPhone 18 Pro models. Fortunately, one of them already appears to have a fix.  </p><p>And these are separate from the already-fixed <a href="https://www.tomsguide.com/phones/iphones/apple-confirms-iphone-18-pro-face-id-freezing-bug-what-you-need-to-know">iPhone 18 Pro Face ID </a>freezing bug.</p><h2 id="at-amp-t-cellular-connectivity-issues">AT&T Cellular Connectivity issues</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1995px;"><p class="vanilla-image-block" style="padding-top:54.39%;"><img id="vV6kYTFqMFvhACjdSTB8UQ" name="AT&T logo.jpg" alt="AT&T logo" src="https://cdn.mos.cms.futurecdn.net/vV6kYTFqMFvhACjdSTB8UQ-1920-80.jpg" mos="" align="middle" fullscreen="" width="1995" height="1085" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Lester Balajadia/Shutterstock)</span></figcaption></figure><p>Last week, reports of cellular connectivity issues for AT&T customers started popping up on <a href="https://www.reddit.com/r/ATT/comments/1wn54ip/anyone_else_getting_sos_on_iphone_18_pro_max_this/" target="_blank">Reddit </a>and the <a href="https://discussions.apple.com/thread/256360691?sortBy=rank" target="_blank">Apple Support Community forums</a>. Basically, the new iPhones, especially the iPhone 18 Pro Max, were starting in SOS mode and not connecting to the AT&T network or were operating extremely slowly if they did manage to connect.</p><p>It appeared that some of the problems were with eSIM transferring from older phones or between accounts.</p><p>AT&T acknowledged the problem via a text message sent to impacted customers. The network carrier is urging customers to update to iOS 27.0.1.</p><p>An AT&T spokesperson confirmed the message to Tom's Guide.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-W5E63W"></div>                            </div>                            <script src="https://kwizly.com/embed/W5E63W.js" async></script><p>Here's what the text says:</p><p>"<em>Hi, it's AT&T. Action needed: An important Apple software update for your iPhone 18 Pro Max is available. Some phones may be unable to complete calls/text/data, including to 911. Update to iOS 27.0.1 immediately — Settings > General > Software Update. Please contact AT&T or Apple if you have questions." </em></p><p>The spokesperson added, "Our top priority is ensuring customers can stay connected when they need it most, and we are working with Apple to make it right.”</p><p>Some users said that the iOS 27 update didn't fix the problem, but I've seen several comments suggesting that AT&T will swap your phone. Though that's <a href="https://www.reddit.com/r/ATT/comments/1wn54ip/comment/pbscow8/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button" target="_blank">proved contentious</a> on whether Apple or AT&T will take responsibility for the swap.</p><p>Interestingly, the Pro Max is the only new iPhone featuring a <a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20">Qualcomm cellular modem</a>, while the Pro and<a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice"> iPhone Duo</a> come with Apple's in-house-designed <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-teardown-reveals-the-ins-and-outs-of-the-latest-iphone-models-including-one-annoying-repair-issue">C2 modem</a>. However, it's not clear if that's what is causing issues or if it's a software issue.</p><p>Tom's Guide was told that if you've experienced issues, you can go to an Apple or AT&T store for additional support. We've also reached out to Apple about the issue and will update this article if the company responds.</p><h2 id="popping-speakers">Popping speakers</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="S8VCNwUf4CeCFFtLAWtVmK" name="iPhone 18 Pro and Pro Max-8" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/S8VCNwUf4CeCFFtLAWtVmK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The other issue that we can't confirm is a potential audio or speaker problem in the iPhone 18 Pro models.</p><p>Users on <a href="https://www.reddit.com/r/iphone/comments/1wkrxv8/iphone_18pro_max_speaker_issue/" target="_blank">Reddit </a>and the<a href="https://forums.macrumors.com/threads/iphone-18-pro-max-speaker-issue.2489836/" target="_blank"> MacRumors forums</a> are reporting a crackling or "popping noise" emanating from the iPhone's speakers. One theory involves the earpiece speaker. One person described the sound as if someone is "pulling out a aux cord and you hear a brief click pop noise.</p><p>To be upfront, at Tom's Guide we have both the iPhone 18 Pro and iPhone 18 Pro Max in for testing and were unable to recreate this issue on either phone.</p><p>"When setting it up I could hear a crackling sound coming from the speakers a few times and exchanged it," one person wrote. "I set up the second one all seemed good but i heard it again. This happen to anyone else?" </p><p>Some people reported that Apple and Best Buy told them it's likely a software issue. </p><p>We've also asked Apple about the speaker popping problem and will update if the company says anything.</p><h2 id="other-issues">Other issues</h2><p>We've seen other reports of <a href="https://www.pcmag.com/news/apples-latest-ios-27-update-fixes-face-id-bug-on-iphone-18-pro" target="_blank">Control Center freezing</a>, springboard and <a href="https://zeerawireless.com/blogs/news/ios-27-0-1-widget-crash-iphone-18-pro" target="_blank">widget crashes,</a> overheating and<a href="https://www.reddit.com/r/iphone18pro/comments/1wrnvlk/some_unique_issue_with_iphone_18_pro_heating_and/" target="_blank"> rapid battery draining,</a> as well as <a href="https://www.engadget.com/2272713/ios-27-0-1-iphone-update-face-id-touchscreen-issue-fixes/" target="_blank">strange camera colors</a>. </p><p>However, it appears most of the issues have been resolved thanks to iOS 27.0.1. update. </p><p>If you're experiencing any of these problems, or something totally different, let us know in the comments!</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/apple-reveals-iphone-duo-has-a-replaceable-display-layer-what-it-means-for-you"><strong>Apple reveals iPhone Duo has a 'replaceable' display layer — what it means for you</strong></a></li><li><a href="https://www.tomsguide.com/phones/apple-gave-the-notes-app-massive-upgrades-in-ios-27-and-now-its-a-legitimate-writing-tool"><strong>4 new iOS 27 features that turn Apple Notes into a productivity powerhouse</strong></a></li><li><a href="https://www.tomsguide.com/phones/pre-ordering-iphone-duo-3-big-reasons-to-consider-galaxy-z-fold-8-first"><strong>4 ways Samsung's Galaxy Z Fold 8 beats Apple iPhone Duo</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/iphone-18-pro-problems-so-far-popping-noises-at-and-t-issues-and-more</link>
                                                                            <description>
                            <![CDATA[ New iPhone 18 Pro models might have cellular issues as well as strange "popping" noises. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">uMfAfEgfARB9q8kBJnhiLW</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/vkrHAQnia6j8yUVnx2mZfB-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 02 Oct 2026 20:21:24 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ scott.younker@futurenet.com (Scott Younker) ]]></author>                    <dc:creator><![CDATA[ Scott Younker ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/RZsUpqcJ6Uj2q83oCUwNhQ-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Scott Younker is the West Coast Reporter at Tom’s Guide. He covers all the latest tech news, including phones, computing and more. He’s been involved in tech since 2011 covering everything from cameras and swimming pool equipment to the latest gaming consoles and smart TVs. He is on a seemingly never ending hunt to build the easiest to use home media system. &lt;/p&gt;&lt;p&gt;Before Tom’s Guide, Scott worked for publications like &lt;em&gt;Digital Trends, Outdoor Photographer, Dead Beats Panel&lt;/em&gt;, and in a brief detour, &lt;em&gt;America’s Funniest Home Videos&lt;/em&gt;. Yes, he has seen more pratfalls, silly pets and ridiculous home movie fails than is reasonably healthy. &lt;/p&gt;&lt;p&gt;When not writing about the latest devices or advances in chipsets, be sure to ask about Scott about disc golf and sustainability, or just if you’re being cheeky, ask about his noodle arm. If you truly want to get nerdy, bring up board games and his ongoing losing streak. &lt;/p&gt;&lt;p&gt;Scott joined Tom&#039;s Guide in 2024 as the West Coast Reporter. He graduated from the School of Journalism at the University of Oregon with a degree in magazine journalism and a minor in communications. While there he blogged or wrote for several magazines including the Fluxx, Ethos and the Oregon Commentator. He briefly wrote and managed a moderately successful blog focused on web comics. &lt;br&gt;Send secure tips on Signal: scyo1.55.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/vkrHAQnia6j8yUVnx2mZfB-1920-80.jpg">
                                                            <media:credit><![CDATA[John Velasco / Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 18 Pro Max camera.]]></media:description>                                                            <media:text><![CDATA[iPhone 18 Pro Max camera.]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 18 Pro Max camera.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/vkrHAQnia6j8yUVnx2mZfB-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>We praised the iPhone 18 Pro and Pro Max as "obscenely powerful phones" in <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review#section-verdict">our full review</a> of the new Apple flagship phones, but two weeks after they hit store shelves, the newest iPhone is launching with problems.</p><p>Two separate issues are reportedly affecting cellular connectivity and the speakers on the iPhone 18 Pro models. Fortunately, one of them already appears to have a fix.  </p><p>And these are separate from the already-fixed <a href="https://www.tomsguide.com/phones/iphones/apple-confirms-iphone-18-pro-face-id-freezing-bug-what-you-need-to-know">iPhone 18 Pro Face ID </a>freezing bug.</p><h2 id="at-amp-t-cellular-connectivity-issues">AT&T Cellular Connectivity issues</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1995px;"><p class="vanilla-image-block" style="padding-top:54.39%;"><img id="vV6kYTFqMFvhACjdSTB8UQ" name="AT&T logo.jpg" alt="AT&T logo" src="https://cdn.mos.cms.futurecdn.net/vV6kYTFqMFvhACjdSTB8UQ-1920-80.jpg" mos="" align="middle" fullscreen="" width="1995" height="1085" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Lester Balajadia/Shutterstock)</span></figcaption></figure><p>Last week, reports of cellular connectivity issues for AT&T customers started popping up on <a href="https://www.reddit.com/r/ATT/comments/1wn54ip/anyone_else_getting_sos_on_iphone_18_pro_max_this/" target="_blank">Reddit </a>and the <a href="https://discussions.apple.com/thread/256360691?sortBy=rank" target="_blank">Apple Support Community forums</a>. Basically, the new iPhones, especially the iPhone 18 Pro Max, were starting in SOS mode and not connecting to the AT&T network or were operating extremely slowly if they did manage to connect.</p><p>It appeared that some of the problems were with eSIM transferring from older phones or between accounts.</p><p>AT&T acknowledged the problem via a text message sent to impacted customers. The network carrier is urging customers to update to iOS 27.0.1.</p><p>An AT&T spokesperson confirmed the message to Tom's Guide.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-W5E63W"></div>                            </div>                            <script src="https://kwizly.com/embed/W5E63W.js" async></script><p>Here's what the text says:</p><p>"<em>Hi, it's AT&T. Action needed: An important Apple software update for your iPhone 18 Pro Max is available. Some phones may be unable to complete calls/text/data, including to 911. Update to iOS 27.0.1 immediately — Settings > General > Software Update. Please contact AT&T or Apple if you have questions." </em></p><p>The spokesperson added, "Our top priority is ensuring customers can stay connected when they need it most, and we are working with Apple to make it right.”</p><p>Some users said that the iOS 27 update didn't fix the problem, but I've seen several comments suggesting that AT&T will swap your phone. Though that's <a href="https://www.reddit.com/r/ATT/comments/1wn54ip/comment/pbscow8/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button" target="_blank">proved contentious</a> on whether Apple or AT&T will take responsibility for the swap.</p><p>Interestingly, the Pro Max is the only new iPhone featuring a <a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20">Qualcomm cellular modem</a>, while the Pro and<a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice"> iPhone Duo</a> come with Apple's in-house-designed <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-teardown-reveals-the-ins-and-outs-of-the-latest-iphone-models-including-one-annoying-repair-issue">C2 modem</a>. However, it's not clear if that's what is causing issues or if it's a software issue.</p><p>Tom's Guide was told that if you've experienced issues, you can go to an Apple or AT&T store for additional support. We've also reached out to Apple about the issue and will update this article if the company responds.</p><h2 id="popping-speakers">Popping speakers</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="S8VCNwUf4CeCFFtLAWtVmK" name="iPhone 18 Pro and Pro Max-8" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/S8VCNwUf4CeCFFtLAWtVmK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The other issue that we can't confirm is a potential audio or speaker problem in the iPhone 18 Pro models.</p><p>Users on <a href="https://www.reddit.com/r/iphone/comments/1wkrxv8/iphone_18pro_max_speaker_issue/" target="_blank">Reddit </a>and the<a href="https://forums.macrumors.com/threads/iphone-18-pro-max-speaker-issue.2489836/" target="_blank"> MacRumors forums</a> are reporting a crackling or "popping noise" emanating from the iPhone's speakers. One theory involves the earpiece speaker. One person described the sound as if someone is "pulling out a aux cord and you hear a brief click pop noise.</p><p>To be upfront, at Tom's Guide we have both the iPhone 18 Pro and iPhone 18 Pro Max in for testing and were unable to recreate this issue on either phone.</p><p>"When setting it up I could hear a crackling sound coming from the speakers a few times and exchanged it," one person wrote. "I set up the second one all seemed good but i heard it again. This happen to anyone else?" </p><p>Some people reported that Apple and Best Buy told them it's likely a software issue. </p><p>We've also asked Apple about the speaker popping problem and will update if the company says anything.</p><h2 id="other-issues">Other issues</h2><p>We've seen other reports of <a href="https://www.pcmag.com/news/apples-latest-ios-27-update-fixes-face-id-bug-on-iphone-18-pro" target="_blank">Control Center freezing</a>, springboard and <a href="https://zeerawireless.com/blogs/news/ios-27-0-1-widget-crash-iphone-18-pro" target="_blank">widget crashes,</a> overheating and<a href="https://www.reddit.com/r/iphone18pro/comments/1wrnvlk/some_unique_issue_with_iphone_18_pro_heating_and/" target="_blank"> rapid battery draining,</a> as well as <a href="https://www.engadget.com/2272713/ios-27-0-1-iphone-update-face-id-touchscreen-issue-fixes/" target="_blank">strange camera colors</a>. </p><p>However, it appears most of the issues have been resolved thanks to iOS 27.0.1. update. </p><p>If you're experiencing any of these problems, or something totally different, let us know in the comments!</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/apple-reveals-iphone-duo-has-a-replaceable-display-layer-what-it-means-for-you"><strong>Apple reveals iPhone Duo has a 'replaceable' display layer — what it means for you</strong></a></li><li><a href="https://www.tomsguide.com/phones/apple-gave-the-notes-app-massive-upgrades-in-ios-27-and-now-its-a-legitimate-writing-tool"><strong>4 new iOS 27 features that turn Apple Notes into a productivity powerhouse</strong></a></li><li><a href="https://www.tomsguide.com/phones/pre-ordering-iphone-duo-3-big-reasons-to-consider-galaxy-z-fold-8-first"><strong>4 ways Samsung's Galaxy Z Fold 8 beats Apple iPhone Duo</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Pre-ordering iPhone Duo? 4 reasons to consider Galaxy Z Fold 8 first ]]></title>
                                                                                                <dc:content><![CDATA[ <p>The <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice"><u>iPhone Duo</u></a> is almost here, and there are lots of reasons to snatch up Apple’s first foldable phone come October 16 when pre-orders begin. It gives you a compact 5.4-inch phone and 7.6-inch mini tablet in one device, and it looks like an awesome option for those who want a more immersive viewing experience on the go along with dual-app multitasking — finally!</p><p>But as many in our comments have reminded me, Samsung has been making foldable phones for seven years. And that experience shows in the <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-review-wide-for-the-win"><u>Galaxy Z Fold 8</u></a>. It has a similar passport-style design to the iPhone Duo, but it offers some pretty unique advantages over Apple’s device and could be the <a href="https://www.tomsguide.com/best-picks/best-foldable-phones"><u>best foldable phone</u></a> for you. If you’re on the fence about getting an iPhone Duo or Galaxy Z Fold 8, here’s where Samsung’s device could sway you.</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/EiAmyzzVhts" allowfullscreen></iframe></div></div><h2 id="1-it-s-considerably-thinner-and-lighter">1. It’s considerably thinner and lighter</h2><p>I only played around with the iPhone Duo for about an hour between various hands-on sessions, but it definitely feels heftier than the Galaxy Z Fold 8. Sure, the iPhone Duo is technically the “thinnest iPhone ever,” at just 5.2 mm unfolded. That’s even less than the <a href="https://www.tomsguide.com/phones/iphones/iphone-air-review"><u>iPhone Air</u></a>’s 5.64mm. However, the Galaxy Z Fold 8 is only 4.5 mm. </p><div class="product"><a data-dimension112="32275f7e-bde0-11f1-82e6-313effd2b2ae" data-action="Deal Block" data-label="Galaxy Z Fold 8" data-dimension48="Galaxy Z Fold 8" data-dimension25="$1649" href="https://www.bestbuy.com/product/samsung-galaxy-z-fold8-256gb-unlocked-graphite/JJGRF3FS98/sku/6681692" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1327px;"><p class="vanilla-image-block" style="padding-top:64.28%;"><img id="9Rhpe6TtrVFSNo9Vtn27Tm" name="Galaxy Z Fold 8 Ultra deal block" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/9Rhpe6TtrVFSNo9Vtn27Tm-1920-80.jpg" mos="" align="middle" fullscreen="" width="1327" height="853" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Galaxy Z Fold 8 is one of the best foldable phones we've tested, giving you a 5.5-inch cover display and a huge 7.6-inch main screen in a super light design. Samsung has also done a great job minimizing the crease. Key specs include a Snapdragon 8 Elite CPU, 12GB of RAM, and 256GB of storage. On the rear you get a 50MP main wide-angle lens and 50MP ultra-wide lens. In our <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-review-wide-for-the-win" data-dimension112="32275f7e-bde0-11f1-82e6-313effd2b2ae" data-action="Deal Block" data-label="Galaxy Z Fold 8" data-dimension48="Galaxy Z Fold 8" data-dimension25="$1649">Galaxy Z Fold 8 review</a>, we called it our favorite Android foldable to date. <a class="view-deal button" href="https://www.bestbuy.com/product/samsung-galaxy-z-fold8-256gb-unlocked-graphite/JJGRF3FS98/sku/6681692" target="_blank" rel="nofollow" data-dimension112="32275f7e-bde0-11f1-82e6-313effd2b2ae" data-action="Deal Block" data-label="Galaxy Z Fold 8" data-dimension48="Galaxy Z Fold 8" data-dimension25="$1649">View Deal</a></p></div><p>When folded, the iPhone Duo measures 11.3mm thick, compared to 9.7mm for the Fold 8. For context, the iPhone 18 Pro Max is 8.75mm thick. So while the Duo will slip into a pocket with ease, it will take up some room. </p><p>In addition, the iPhone Duo weighs 8.96 ounces or 254 grams, while the Fold 8 is a feather light 7.09 ounces (201 grams). Samsung’s foldable is even lighter than the regular iPhone 18 Pro (7.44 ounces), which has a relatively tiny 6.3 inch display compared to the 7.6-inch panel on the Fold 8.</p><h2 id="2-you-can-run-more-apps-at-once">2. You can run more apps at once</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="XFCxXSuM9ujaXaBT7dqk2g" name="iphone duo software-2" alt="iPhone Duo software" src="https://cdn.mos.cms.futurecdn.net/XFCxXSuM9ujaXaBT7dqk2g-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I give Apple plenty of credit for making running two apps at once so seamless and intuitive on the iPhone Duo. You just select an app and then place it on the left or right side of the display. From there you can easily create app pairs and go back to them at any time. And it’s also a cinch to switch out apps; you just swipe up and go back to the home screen — it’s like having two distinct desktops.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2879px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="77ZTA3cHAT3JoQVSNWAUNW" name="Galaxy Z Fold 8-15" alt="Galaxy Z Fold 8 shown in hand" src="https://cdn.mos.cms.futurecdn.net/77ZTA3cHAT3JoQVSNWAUNW-1920-80.jpg" mos="" align="middle" fullscreen="" width="2879" height="1619" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>However, the Galaxy Z Fold 8 can let you run three tiled apps at the same time on screen. So, for example, I could have Gmail in one window, Slack in another and Spotify in another. It’s pretty cool. Plus, Samsung lets you put up to five floating windows on top. Now, eight apps at once seems like overkill to me, but it’s pretty amazing that you have that flexibility.</p><h2 id="3-gemini-ai-is-more-advanced">3. Gemini AI is more advanced</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3236px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="LGcJBsBE5WEHrumKKBqpSV" name="Galaxy Z Fold 8-40" alt="Galaxy Z Fold 8 shown in hand" src="https://cdn.mos.cms.futurecdn.net/LGcJBsBE5WEHrumKKBqpSV-1920-80.jpg" mos="" align="middle" fullscreen="" width="3236" height="1820" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p><a href="https://www.tomsguide.com/ai/siri-just-got-a-major-ai-upgrade-here-are-5-things-to-try-first"><u>Siri AI</u></a> is definitely improved in iOS 27, and it lets you do some pretty cool things on the iPhone Duo. You get better personal context understanding in all sorts of apps, including Messages and Notes. And there’s on-screen awareness, so you can say things like “add these items to my shopping list.” And I also appreciate that there’s finally a Siri mode in the camera app, so you don’t have to think about performing any shortcuts.</p><p>However, I think Galaxy AI and Gemini on the Galaxy Z Fold 8 are not only more advanced but more tailored to the foldable experience. For example, <a href="https://www.tomsguide.com/phones/samsung-phones/how-to-turn-on-galaxy-s26s-now-nudge-and-how-it-works"><u>Now Nudge</u></a> gives you suggestions in Messages for apps that you can open in split-screen mode, such as Calendar. </p><p>And Gemini itself is just more versatile than Siri AI. You can share your live camera video in real time and get advice and troubleshooting tips. I did this when trying to figure out how to clean out battery corrosion from an outdoor flood light.</p><h2 id="4-it-s-100-cheaper">4. It’s $100 cheaper</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2080px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="bPd7ZTJvXjFWH9MbVievUY" name="Galaxy Z Fold 8 review-13" alt="Galaxy Z Fold 8 shown held in-hand" src="https://cdn.mos.cms.futurecdn.net/bPd7ZTJvXjFWH9MbVievUY-1920-80.jpg" mos="" align="middle" fullscreen="" width="2080" height="1170" attribution="" endorsement="" class="inline"></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 Galaxy Fold 8 starts at $1,799, which is $100 less than the iPhone Duo. Plus, there are already some pretty good deals out there. At time of writing I found the <a href="https://www.bestbuy.com/product/samsung-galaxy-z-fold8-256gb-unlocked-graphite/JJGRF3FS98"><u>Fold 8 for just $1,649 on Best Buy</u></a>, which is $250 off.</p><p>I’m sure there will be plenty of <a href="https://www.tomsguide.com/phones/iphones/how-to-save-up-to-usd885-on-the-new-iphone-duo"><u>iPhone Duo pre-order deals</u></a> around Apple’s launch as well, so you should be able to get it at a discount. But as of now the Fold 8 is a better value.</p><h2 id="where-the-iphone-duo-wins">Where the iPhone Duo wins</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="5G5fArauMU9aMKnbuB9Dtb" name="iPhone duo edit 2" alt="iPhone Duo hands on" src="https://cdn.mos.cms.futurecdn.net/5G5fArauMU9aMKnbuB9Dtb-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>As good as Samsung’s foldable is, there are several ways the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-vs-samsung-galaxy-z-fold-8-7-ways-apples-foldable-beats-its-rival-from-ip68-to-faster-charging-and-more"><u>iPhone Duo beats the Fold 8</u></a>. For example, the iPhone Duo offers an IP68 rating for durability, which means it’s protected from both water and dust. Samsung’s phone is only water resistant.</p><p>In addition, the iPhone Duo offers MagSafe built in for wireless charging, Apple Pencil support and vapor chamber cooling, which will presumably help with sustained performance for Apple’s <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen"><u>faster A20 chip</u></a>.</p><p>But Apple’s biggest advantage will likely come with software and apps. The iPhone Duo’s software can react based on the position of the hinge while the Fold 8 lacks Samsung’s Flex Mode. And I expect a sizable wave of Duo optimized apps at launch, including Slack, Netflix and Zoom.</p><h2 id="bottom-line">Bottom line</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="DFXjpwrQUPfAW54nMm3Zv9" name="Samsung Galaxy Z Fold 8" alt="In-hand image of Samsung Galaxy Z Fold 8 in folded mode" src="https://cdn.mos.cms.futurecdn.net/DFXjpwrQUPfAW54nMm3Zv9-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The iPhone Duo clearly has the most buzz, and it makes sense because Apple is entering a new category. But I wouldn’t overlook the Galaxy Z Fold 8. It feels so light and thin that it almost seems like Samsung cheated physics. And if you like the idea of multitasking on a big screen, the Fold 8 lets you run more apps at once. And while Siri is smarter than ever, Samsung and Google are in the lead with AI features.</p><p>So which foldable has your interest? Let us know in the comments.</p> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/pre-ordering-iphone-duo-3-big-reasons-to-consider-galaxy-z-fold-8-first</link>
                                                                            <description>
                            <![CDATA[ The iPhone Duo looks great, but the Samsung Galaxy Z Fold 8 has some key advantages over Apple’s first foldable. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Xr4iwawborCaiP3HNuhR3C</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/VGUHEv7t6SSUdQpiN4xMkf-1920-80.png" type="image/png" length="0"></enclosure>
                                                                        <pubDate>Fri, 02 Oct 2026 06:30:00 +0000</pubDate>                                                                                                                                <updated>Fri, 02 Oct 2026 18:35:06 +0000</updated>
                                                                                                                                            <category><![CDATA[Phones]]></category>
                                                    <category><![CDATA[Samsung Phones]]></category>
                                                    <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Android Phones]]></category>
                                                                                                                    <dc:creator><![CDATA[ Mark Spoonauer ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/wtAspSzVfcKLB4JEd39AMo-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Mark Spoonauer is the global editor in chief of Tom&#039;s Guide and has covered technology for over 20 years. He oversees the direction of Tom&#039;s Guide and leads a team of over 25 journalists to bring you our expert buying guides, reviews, news, how-to articles, deals and other coverage.&lt;/p&gt;&lt;p&gt;Mark has a passion for covering all things mobile, having reviewed dozens of smartphones and other gadgets. He enjoys testing the top mobile devices and putting them up against each other in our in-depth face-offs. He also works hand in hand with our editors and testing team to continually improve how we evaluate products. &lt;/p&gt;&lt;p&gt;Having led Tom&#039;s Guide since 2013, Mark has focused on growing the core tech coverage of the site while also expanding into new areas, such as entertainment, fitness and home, recruiting talented writers and editors to help our readers figure out what to buy and how to get the most out of the products and services they use every day. &lt;/p&gt;&lt;p&gt;Mark has spoken at key industry events and appears regularly on TV to discuss the latest trends, including &lt;a href=&quot;https://cheddar.com/media/pixel-watch-gets-a-release-date-at-google-i-o-2022&quot;&gt;Cheddar&lt;/a&gt;, Fox 5, &lt;a href=&quot;https://www.foxbusiness.com/technology/apple-march-event-5g-iphone&quot;&gt;Fox Business&lt;/a&gt; and other outlets. Mark was previously editor in chief of Laptop Mag, and his work has appeared in Wired, Popular Science and Inc. Follow him on Twitter at @mspoonauer.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/png" url="https://cdn.mos.cms.futurecdn.net/VGUHEv7t6SSUdQpiN4xMkf-1920-80.png">
                                                            <media:credit><![CDATA[Apple/Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone Duo and Galaxy Z Fold 8]]></media:description>                                                            <media:text><![CDATA[iPhone Duo and Galaxy Z Fold 8]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone Duo and Galaxy Z Fold 8]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/VGUHEv7t6SSUdQpiN4xMkf-1920-80.png" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice"><u>iPhone Duo</u></a> is almost here, and there are lots of reasons to snatch up Apple’s first foldable phone come October 16 when pre-orders begin. It gives you a compact 5.4-inch phone and 7.6-inch mini tablet in one device, and it looks like an awesome option for those who want a more immersive viewing experience on the go along with dual-app multitasking — finally!</p><p>But as many in our comments have reminded me, Samsung has been making foldable phones for seven years. And that experience shows in the <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-review-wide-for-the-win"><u>Galaxy Z Fold 8</u></a>. It has a similar passport-style design to the iPhone Duo, but it offers some pretty unique advantages over Apple’s device and could be the <a href="https://www.tomsguide.com/best-picks/best-foldable-phones"><u>best foldable phone</u></a> for you. If you’re on the fence about getting an iPhone Duo or Galaxy Z Fold 8, here’s where Samsung’s device could sway you.</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/EiAmyzzVhts" allowfullscreen></iframe></div></div><h2 id="1-it-s-considerably-thinner-and-lighter">1. It’s considerably thinner and lighter</h2><p>I only played around with the iPhone Duo for about an hour between various hands-on sessions, but it definitely feels heftier than the Galaxy Z Fold 8. Sure, the iPhone Duo is technically the “thinnest iPhone ever,” at just 5.2 mm unfolded. That’s even less than the <a href="https://www.tomsguide.com/phones/iphones/iphone-air-review"><u>iPhone Air</u></a>’s 5.64mm. However, the Galaxy Z Fold 8 is only 4.5 mm. </p><div class="product"><a data-dimension112="32275f7e-bde0-11f1-82e6-313effd2b2ae" data-action="Deal Block" data-label="Galaxy Z Fold 8" data-dimension48="Galaxy Z Fold 8" data-dimension25="$1649" href="https://www.bestbuy.com/product/samsung-galaxy-z-fold8-256gb-unlocked-graphite/JJGRF3FS98/sku/6681692" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1327px;"><p class="vanilla-image-block" style="padding-top:64.28%;"><img id="9Rhpe6TtrVFSNo9Vtn27Tm" name="Galaxy Z Fold 8 Ultra deal block" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/9Rhpe6TtrVFSNo9Vtn27Tm-1920-80.jpg" mos="" align="middle" fullscreen="" width="1327" height="853" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Galaxy Z Fold 8 is one of the best foldable phones we've tested, giving you a 5.5-inch cover display and a huge 7.6-inch main screen in a super light design. Samsung has also done a great job minimizing the crease. Key specs include a Snapdragon 8 Elite CPU, 12GB of RAM, and 256GB of storage. On the rear you get a 50MP main wide-angle lens and 50MP ultra-wide lens. In our <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-review-wide-for-the-win" data-dimension112="32275f7e-bde0-11f1-82e6-313effd2b2ae" data-action="Deal Block" data-label="Galaxy Z Fold 8" data-dimension48="Galaxy Z Fold 8" data-dimension25="$1649">Galaxy Z Fold 8 review</a>, we called it our favorite Android foldable to date. <a class="view-deal button" href="https://www.bestbuy.com/product/samsung-galaxy-z-fold8-256gb-unlocked-graphite/JJGRF3FS98/sku/6681692" target="_blank" rel="nofollow" data-dimension112="32275f7e-bde0-11f1-82e6-313effd2b2ae" data-action="Deal Block" data-label="Galaxy Z Fold 8" data-dimension48="Galaxy Z Fold 8" data-dimension25="$1649">View Deal</a></p></div><p>When folded, the iPhone Duo measures 11.3mm thick, compared to 9.7mm for the Fold 8. For context, the iPhone 18 Pro Max is 8.75mm thick. So while the Duo will slip into a pocket with ease, it will take up some room. </p><p>In addition, the iPhone Duo weighs 8.96 ounces or 254 grams, while the Fold 8 is a feather light 7.09 ounces (201 grams). Samsung’s foldable is even lighter than the regular iPhone 18 Pro (7.44 ounces), which has a relatively tiny 6.3 inch display compared to the 7.6-inch panel on the Fold 8.</p><h2 id="2-you-can-run-more-apps-at-once">2. You can run more apps at once</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="XFCxXSuM9ujaXaBT7dqk2g" name="iphone duo software-2" alt="iPhone Duo software" src="https://cdn.mos.cms.futurecdn.net/XFCxXSuM9ujaXaBT7dqk2g-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I give Apple plenty of credit for making running two apps at once so seamless and intuitive on the iPhone Duo. You just select an app and then place it on the left or right side of the display. From there you can easily create app pairs and go back to them at any time. And it’s also a cinch to switch out apps; you just swipe up and go back to the home screen — it’s like having two distinct desktops.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2879px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="77ZTA3cHAT3JoQVSNWAUNW" name="Galaxy Z Fold 8-15" alt="Galaxy Z Fold 8 shown in hand" src="https://cdn.mos.cms.futurecdn.net/77ZTA3cHAT3JoQVSNWAUNW-1920-80.jpg" mos="" align="middle" fullscreen="" width="2879" height="1619" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>However, the Galaxy Z Fold 8 can let you run three tiled apps at the same time on screen. So, for example, I could have Gmail in one window, Slack in another and Spotify in another. It’s pretty cool. Plus, Samsung lets you put up to five floating windows on top. Now, eight apps at once seems like overkill to me, but it’s pretty amazing that you have that flexibility.</p><h2 id="3-gemini-ai-is-more-advanced">3. Gemini AI is more advanced</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3236px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="LGcJBsBE5WEHrumKKBqpSV" name="Galaxy Z Fold 8-40" alt="Galaxy Z Fold 8 shown in hand" src="https://cdn.mos.cms.futurecdn.net/LGcJBsBE5WEHrumKKBqpSV-1920-80.jpg" mos="" align="middle" fullscreen="" width="3236" height="1820" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p><a href="https://www.tomsguide.com/ai/siri-just-got-a-major-ai-upgrade-here-are-5-things-to-try-first"><u>Siri AI</u></a> is definitely improved in iOS 27, and it lets you do some pretty cool things on the iPhone Duo. You get better personal context understanding in all sorts of apps, including Messages and Notes. And there’s on-screen awareness, so you can say things like “add these items to my shopping list.” And I also appreciate that there’s finally a Siri mode in the camera app, so you don’t have to think about performing any shortcuts.</p><p>However, I think Galaxy AI and Gemini on the Galaxy Z Fold 8 are not only more advanced but more tailored to the foldable experience. For example, <a href="https://www.tomsguide.com/phones/samsung-phones/how-to-turn-on-galaxy-s26s-now-nudge-and-how-it-works"><u>Now Nudge</u></a> gives you suggestions in Messages for apps that you can open in split-screen mode, such as Calendar. </p><p>And Gemini itself is just more versatile than Siri AI. You can share your live camera video in real time and get advice and troubleshooting tips. I did this when trying to figure out how to clean out battery corrosion from an outdoor flood light.</p><h2 id="4-it-s-100-cheaper">4. It’s $100 cheaper</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2080px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="bPd7ZTJvXjFWH9MbVievUY" name="Galaxy Z Fold 8 review-13" alt="Galaxy Z Fold 8 shown held in-hand" src="https://cdn.mos.cms.futurecdn.net/bPd7ZTJvXjFWH9MbVievUY-1920-80.jpg" mos="" align="middle" fullscreen="" width="2080" height="1170" attribution="" endorsement="" class="inline"></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 Galaxy Fold 8 starts at $1,799, which is $100 less than the iPhone Duo. Plus, there are already some pretty good deals out there. At time of writing I found the <a href="https://www.bestbuy.com/product/samsung-galaxy-z-fold8-256gb-unlocked-graphite/JJGRF3FS98"><u>Fold 8 for just $1,649 on Best Buy</u></a>, which is $250 off.</p><p>I’m sure there will be plenty of <a href="https://www.tomsguide.com/phones/iphones/how-to-save-up-to-usd885-on-the-new-iphone-duo"><u>iPhone Duo pre-order deals</u></a> around Apple’s launch as well, so you should be able to get it at a discount. But as of now the Fold 8 is a better value.</p><h2 id="where-the-iphone-duo-wins">Where the iPhone Duo wins</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="5G5fArauMU9aMKnbuB9Dtb" name="iPhone duo edit 2" alt="iPhone Duo hands on" src="https://cdn.mos.cms.futurecdn.net/5G5fArauMU9aMKnbuB9Dtb-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>As good as Samsung’s foldable is, there are several ways the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-vs-samsung-galaxy-z-fold-8-7-ways-apples-foldable-beats-its-rival-from-ip68-to-faster-charging-and-more"><u>iPhone Duo beats the Fold 8</u></a>. For example, the iPhone Duo offers an IP68 rating for durability, which means it’s protected from both water and dust. Samsung’s phone is only water resistant.</p><p>In addition, the iPhone Duo offers MagSafe built in for wireless charging, Apple Pencil support and vapor chamber cooling, which will presumably help with sustained performance for Apple’s <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen"><u>faster A20 chip</u></a>.</p><p>But Apple’s biggest advantage will likely come with software and apps. The iPhone Duo’s software can react based on the position of the hinge while the Fold 8 lacks Samsung’s Flex Mode. And I expect a sizable wave of Duo optimized apps at launch, including Slack, Netflix and Zoom.</p><h2 id="bottom-line">Bottom line</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="DFXjpwrQUPfAW54nMm3Zv9" name="Samsung Galaxy Z Fold 8" alt="In-hand image of Samsung Galaxy Z Fold 8 in folded mode" src="https://cdn.mos.cms.futurecdn.net/DFXjpwrQUPfAW54nMm3Zv9-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The iPhone Duo clearly has the most buzz, and it makes sense because Apple is entering a new category. But I wouldn’t overlook the Galaxy Z Fold 8. It feels so light and thin that it almost seems like Samsung cheated physics. And if you like the idea of multitasking on a big screen, the Fold 8 lets you run more apps at once. And while Siri is smarter than ever, Samsung and Google are in the lead with AI features.</p><p>So which foldable has your interest? Let us know in the comments.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tested the iPhone 18 Pro Max vs. iPhone 16 Pro Max side-by-side: Should you upgrade? ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Around this time of year, many iPhone owners ask themselves the same question: is it time to upgrade? That’s what I set out to answer in my iPhone 18 Pro Max vs. iPhone 16 Pro Max face-off. The two-year gap between models might tempt some current 16 Pro Max owners to make the jump, even though I generally recommend waiting at least three years.</p><p>In our <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-16-pro-max-review">iPhone 16 Pro Max review</a>, we highlighted standout additions like <a href="https://www.tomsguide.com/phones/iphones/snap-faster-with-iphone-16-how-to-use-the-camera-control-button">Camera Control</a>, an expansive 6.9-inch Super Retina XDR display, and Apple Intelligence right out of the box — along with what turned out to be the lineup’s final 5x optical telephoto lens.</p><p>Fast-forward two years, and there are even more substantial changes detailed in our <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max review</a>, including a new <a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">variable-aperture main camera</a>, the 2nm <a href="https://www.tomsguide.com/phones/iphones/apple-a20-pro-chip-why-its-such-a-big-deal-for-the-iphone-ultra-and-iphone-18-pro-max">A20 Pro silicon</a>, and next-gen Siri AI. But does a two-year cycle offer enough of a generational leap to justify retiring your trusty flagship?</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-16-pro-max-specifications"><span>iPhone 18 Pro Max vs. iPhone 16 Pro Max: Specifications</span></h2><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>iPhone 18 Pro Max</strong></p></th><th  ><p><strong>iPhone 16 Pro Max</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p>From $1,299</p></td><td  ><p>From $1,199*</p></td></tr><tr><td class="firstcol " ><p><strong>Main Display</strong></p></td><td  ><p>6.9-inch Super Retina XDR display (2,868 x 1,320)</p></td><td  ><p>6.9-inch Super Retina XDR display (2,868 x 1,320)</p></td></tr><tr><td class="firstcol " ><p><strong>Refresh Rate</strong></p></td><td  ><p>1-120Hz ProMotion</p></td><td  ><p>1-120Hz ProMotion</p></td></tr><tr><td class="firstcol " ><p><strong>Processor</strong></p></td><td  ><p>A20 Pro</p></td><td  ><p>A18 Pro</p></td></tr><tr><td class="firstcol " ><p><strong>Storage</strong></p></td><td  ><p>256GB, 512GB, 1TB, 2TB</p></td><td  ><p>256GB, 512GB, 1TB</p></td></tr><tr><td class="firstcol " ><p><strong>RAM</strong></p></td><td  ><p>12GB</p></td><td  ><p>12GB</p></td></tr><tr><td class="firstcol " ><p><strong>Front Camera</strong></p></td><td  ><p>18MP Center Stage camera (f/1.9)</p></td><td  ><p>12MP (f/1.9)</p></td></tr><tr><td class="firstcol " ><p><strong>Rear Cameras</strong></p></td><td  ><p>48MP main with variable aperture (f/1.48, f/1.8, f/2.8, f/4), 48MP ultrawide (f/2.2), 48MP telephoto w/4x optical zoom (f/2.8)</p></td><td  ><p>48MP main (f/1.78), 48MP ultrawide (f/2.2), 12MP telephoto w/5x optical zoom (f/2.8)</p></td></tr><tr><td class="firstcol " ><p><strong>Battery Capacity</strong></p></td><td  ><p>5,391 mAh </p></td><td  ><p>4,685 mAh</p></td></tr><tr><td class="firstcol " ><p><strong>Charging</strong></p></td><td  ><p>60W wired, 25W wireless</p></td><td  ><p>30W wired, 25W wireless</p></td></tr><tr><td class="firstcol " ><p><strong>Size</strong></p></td><td  ><p>6.43 x 3.07 x 0.34 inches (163.4 x 78.0 x 8.75 mm)</p></td><td  ><p>6.42 x 3.06 x 0.32 inches (163 x 77.6 x 8.25 mm)</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>8.78 ounces (249 grams)</p></td><td  ><p>8 ounces (227 grams)</p></td></tr><tr><td class="firstcol " ><p><strong>IP Rating</strong></p></td><td  ><p>IP68</p></td><td  ><p>IP68</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Black, Silver, Glacier, Burgundy</p></td><td  ><p>Black, White, Desert, Natural Titanium</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-16-pro-max-cameras"><span>iPhone 18 Pro Max vs. iPhone 16 Pro Max: Cameras</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="B6wwZBtkwHjDPGN452dQsP" name="iPhone 18 Pro Max vs iPhone 16 Pro Max-4" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" src="https://cdn.mos.cms.futurecdn.net/B6wwZBtkwHjDPGN452dQsP-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Let me cut to the chase and focus on what matters most in this matchup: the cameras. There are several significant hardware leaps that make a compelling case for the iPhone 18 Pro Max. First and foremost is the new 48MP main sensor featuring a <a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">mechanical variable aperture</a>, giving photographers physical control over how much light hits the sensor.</p><p>That means more natural, optical bokeh without relying solely on software processing, along with the creative flexibility to dial in motion blur on fast-moving subjects or stop down to keep large group shots in razor-sharp focus from front to back.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/SGfp5XiUJsGDo2kUU43cob-1920-80.jpg" alt="iPhone 18 Pro Max aperture f/4.0" /><figcaption>iPhone 18 Pro Max - Aperture f/4.0<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/QVLjmGvb9JGFx8FxZ8ByVb-1920-80.jpg" alt="iPhone 18 Pro Max aperture f/1.8" /><figcaption>iPhone 18 Pro Max - Aperture f/1.8<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>The iPhone 18 Pro Max also boasts a faster maximum f/1.48 aperture, handing the new iPhone an inherent hardware advantage in challenging low-light conditions. Up front, you get an upgraded 18MP Center Stage selfie camera, a noticeable bump over the 16 Pro Max’s 12MP shooter. Even though the telephoto reach remains at 5x optical zoom across both phones, the 16 Pro Max is clearly out-spec'd across the rest of the camera array.</p><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="CnomJi87LGPQMYz3JC6Qx7" name="iPhone 18 Pro - Pro Controls" alt="iPhone 18 Pro showing Pro Controls." src="https://cdn.mos.cms.futurecdn.net/CnomJi87LGPQMYz3JC6Qx7-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>Beyond the optics, the real game-changer for the 18 Pro Max is the addition of native <a href="https://www.tomsguide.com/phones/iphones/forget-variable-aperture-the-real-upgrade-with-the-iphone-18-pro-max-is-pro-controls">Pro Controls</a> — which I consider just as big an upgrade as the hardware itself. Having manual exposure, shutter speed, and focus tools baked right into the stock camera app is a massive workflow win, sparing you the hassle of jumping into third-party apps just to take full control of your shot.</p><p>Based on all the snapshots I captured, I wouldn’t say that the iPhone 18 Pro Max has an overwhelming advantage purely on performance. Well, not enough to convince me to upgrade. Here’s why.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/EgUESeahegMftQYUN5Swn3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/guzBqtaNZHTBhVHQDyCDo3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 16 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>The beachfront shot above proves my point exactly. Both cameras handle the scene admirably, balancing the highlights and shadows without blowing out the sky. They also resolve nearly identical detail throughout the frame, from the sign along the railing to the grassy dunes in the far background.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/9FEbrAg2evJhjCjd58FNy3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max (4x zoom)<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/jTLAQ3TWE7XwT99MGbEet3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 16 Pro Max (4x zoom)<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>At 4x zoom, it’s pretty clear that the iPhone 18 Pro Max holds a significant advantage. Finer details around the apartment building, like the bricks and graffiti, look sharper with more definition.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/nqwcuE3ufEgK9suEyWbQo3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max (40x zoom)<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/FrizJyDyAEM8N99CYB6Eo3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 16 Pro Max (40x zoom)<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>But when pushed to their outer limits — 40x on the iPhone 18 Pro Max and 25x on the 16 Pro Max — both manage to clearly resolve individual bricks surrounding the graffiti. Despite relying on an older 12MP sensor, the 16 Pro Max’s 5x optical reach holds its own, delivering enough clarity to closely match the 18 Pro Max’s upgraded 48MP telephoto shooter.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/BBx9BrVZ7PduaPKMT72bs3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max.<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/76SEMqHeGrrEGoV6BCrqHf-1920-80.jpg" alt="1 - daytime - iPhone 16 Pro Max.JPG" /><figcaption>iPhone 16 Pro Max.<small role="credit">Future</small></figcaption></figure></figure><p>In broad daylight, both primary cameras consistently impress with wide dynamic range, crisp detail, and dependable color fidelity.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/psi2qb5YtRY2XQyqZHR9v3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/VueEJmQuGs6EBBHmRpQWv3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 16 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>Speaking of dynamic range, you can see how cleanly shadows are lifted against the bright afternoon sky in my Bryant Park test shots above.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/mDx64pvC9jtrGFYZrSiqv3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/omypJK4EK8DsH5AvY7jwt3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 16 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>There are subtle variances in color reproduction: red bell peppers take on a deeper, punchier tone on the iPhone 18 Pro Max, though other shades across the Whole Foods produce display look nearly identical between the two.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/KRw4ArgFLVCWdn6TfTSEp3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/xwfzo84z7B6543kJMGkbq3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 16 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>Macro photography is well-handled on both handsets, provided you keep the phone steady and nail your focus point. That said, I give the nod to the 18 Pro Max for producing richer saturation and sharper petal textures.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/3tbbF4z5EZqgnmVEXJ2UL7-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/CMCWHSZgZQoFpKdtkoCDM7-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 16 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>Despite drastic lighting shifts across the panoramic scene, both phones stitch the frame cleanly into a seamless-looking panorama, balancing highlights and shadow areas to ensure an even final exposure.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/A9tLpCEbe4YyogfhqUKwt3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/wGBsCUXSyucTjxq7feF6w3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 16 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>For selfies, the iPhone 18 Pro Max’s new 18MP Center Stage camera delivers a noticeably wider field of view, making it ideal for group shots. Beyond that expanded framing, however, there’s very little difference in detail or processing to give the newer flagship a runaway victory.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/qyGkSCsRn6GFQBNKef2fo3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/SAcM7ae98F4UDQBRrLwX83-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 16 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>When shooting in portrait mode, Apple’s subject-separation algorithms do an exceptional job cutting me out from the background while rendering a convincing, progressive optical falloff. Notice, for instance, how my foreground arm closest to the lens softens naturally into the blur.</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-16-pro-max-battery-and-charging"><span>iPhone 18 Pro Max vs. iPhone 16 Pro Max: Battery and charging</span></h2><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro Max </strong></p></td><td  ><p><strong>iPhone 16 Pro Max </strong></p></td></tr><tr><td class="firstcol " ><p><strong>Battery Size</strong></p></td><td  ><p>5,391 mAh </p></td><td  ><p>4,685 mAh</p></td></tr><tr><td class="firstcol " ><p><strong>Battery Life (hours:minutes)</strong></p></td><td  ><p>18:27 </p></td><td  ><p>17:38</p></td></tr><tr><td class="firstcol " ><p><strong>Charging level in 15 minutes</strong></p></td><td  ><p>53%</p></td><td  ><p>29%</p></td></tr><tr><td class="firstcol " ><p><strong>Charging level in 30 minutes</strong></p></td><td  ><p>80%</p></td><td  ><p>55%</p></td></tr></tbody></table></div><p>Apple packs a substantially larger 5,391 mAh battery into the iPhone 18 Pro Max — roughly a <strong>15% increase in capacity</strong> over the 4,685 mAh cell in the iPhone 16 Pro Max. While a bigger battery doesn’t always guarantee a proportional leap in endurance, our proprietary battery drain test proves it does yield real-world gains.  </p><p>That extra capacity helped the iPhone 18 Pro Max average 18 hours and 27 minutes, outlasting the 16 Pro Max’s already impressive 17 hours and 38 minutes by nearly an hour. Still, across a two-year generational gap, that works out to a modest <strong>4.63% improvement in overall endurance</strong>.   Where you’ll notice a much more dramatic difference is charging speed.</p><p>Thanks to upgraded 60W wired charging, the iPhone 18 Pro Max nearly doubles the charging pace of its older ancestor. In just 15 minutes the 18 Pro Max reaches 53% compared to the 16 Pro Max’s 29%. By the 30-minute mark, the 18 Pro Max surges to 80%, while the 16 Pro Max trails at 55%.   </p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-16-pro-max-performance"><span>iPhone 18 Pro Max vs. iPhone 16 Pro Max: 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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Hzid7dYyFD6su5JduhmMwP" name="iPhone 18 Pro Max vs iPhone 16 Pro Max-8" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" src="https://cdn.mos.cms.futurecdn.net/Hzid7dYyFD6su5JduhmMwP-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Frankly, there has never been an instance where I felt an iPhone was sluggish. Still, looking across our suite of synthetic benchmarks, it is undeniable that the A20 Pro is significantly more capable than the A18 Pro.</p><p>In Geekbench 6, the iPhone 18 Pro Max clocked a single-core score of 4,741 and a multi-core mark of 12,789 — outpacing the 16 Pro Max (3,386 and 8,306) by <strong>40% in single-core and an impressive 54% with multi-core</strong>.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro Max</strong></p></td><td  ><p><strong>iPhone 16 Pro Max</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Chipset</strong></p></td><td  ><p>A20 Pro</p></td><td  ><p>A18 Pro</p></td></tr><tr><td class="firstcol " ><p><strong>Geekbench 6 (single / multi-core)</strong></p></td><td  ><p>4,741 / 12,789</p></td><td  ><p>3,386 / 8,306</p></td></tr><tr><td class="firstcol " ><p><strong>3DMark Solar Bay Unlimited (fps / score)</strong></p></td><td  ><p>67.9 fps / 17,850</p></td><td  ><p>28.1 fps / 7,396</p></td></tr></tbody></table></div><p>While those numbers highlight a substantial CPU leap between generations, graphics testing is where the iPhone 18 Pro Max truly pulls away. Running 3DMark’s Solar Bay Unlimited test, the 18 Pro Max hit an average frame rate of 67.9 fps (17,850 score) versus the 16 Pro Max’s 28.1 fps (7,396 score) — representing a massive <strong>141% surge in graphical performance.</strong> </p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-16-pro-max-software-and-ai"><span>iPhone 18 Pro Max vs. iPhone 16 Pro Max: Software and AI</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="UHFLgbZkizWAuzbea6ATRH" name="iPhone 18 Pro and Pro Max" alt="Siri AI on an iPhone 18 Pro" src="https://cdn.mos.cms.futurecdn.net/UHFLgbZkizWAuzbea6ATRH-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Because both phones run <a href="https://www.tomsguide.com/phones/iphones/ios-27-is-live-heres-how-to-download-and-install-it-now">iOS 27</a>, they offer practically the same everyday experience, core tools, and customizations. That means foundational Apple Intelligence perks — including <a href="https://www.tomsguide.com/phones/i-tried-ios-27-clean-up-vs-galaxy-ai-photo-assist-in-a-7-round-test-and-i-was-surprised-with-how-close-it-was">Clean Up</a> photo editing, <a href="https://www.tomsguide.com/phones/iphones/i-just-installed-the-ios-27-beta-and-reframe-is-unlike-any-other-ai-feature-ive-come-across">Reframe</a>, and <a href="https://www.tomsguide.com/phones/iphones/how-to-create-polls-in-imessage-with-ios-26">interactive polls in Messages</a> — are available across both devices.</p><p>The arrival of <a href="https://www.tomsguide.com/phones/iphones/i-spent-a-week-with-siri-ai-here-are-my-honest-pros-and-cons">Siri AI</a> in iOS 27 signals a major shift for Apple, making the assistant far more proactive with broader automation. For instance, it intelligently suggests creating reminders or calendar entries when someone mentions an upcoming event in Messages.</p><p>I’ve also been genuinely impressed with <a href="https://www.tomsguide.com/phones/iphones/i-just-tried-siri-ai-in-the-ios-27-carplay-beta-and-this-assistant-is-way-more-helpful-than-before">Siri AI in CarPlay</a> because it lets me tackle hands-free tasks I previously couldn't manage safely, such as dictating quick impressions of a vehicle I’m testing from behind the wheel and reopening that same note later to add more details.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1280px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="gEtj6Knu3kZnoSeCRH6ZnQ" name="iOS 27 beta.GIF" alt="iOS 27 beta showing Reframe tool." src="https://cdn.mos.cms.futurecdn.net/gEtj6Knu3kZnoSeCRH6ZnQ-1920-80.gif" mos="" align="middle" fullscreen="" width="1280" height="720" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>However, the <a href="https://www.tomsguide.com/phones/iphones/your-phone-may-run-ios-27-but-only-these-devices-run-everything-siri-ai-can-do">most advanced Siri AI capabilities are exclusive to the iPhone 18 Pro Max</a> and leave the iPhone 16 Pro Max behind. Specifically, Siri’s new Expressive Voices and the upgraded advanced dictation system require hardware that only six iPhone models currently possess. The former gives Siri a far more human, conversational cadence, while the latter dramatically enhances voice-to-text accuracy by smartly filtering out vocal filler words like “ums” and “ahs”.</p><p>Ultimately, the beauty of Apple’s software ecosystem is that the core user experience remains remarkably consistent across generations — even in a two-year flagship matchup like this one.</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-16-pro-max-displays"><span>iPhone 18 Pro Max vs. iPhone 16 Pro Max: Displays</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dgQFoMHqkAGoahKiFKYdrd" name="iPhone 18 Pro and Pro Max-19" alt="Apple iPhone 18 Pro Max" src="https://cdn.mos.cms.futurecdn.net/dgQFoMHqkAGoahKiFKYdrd-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>On paper, both flagships look evenly matched. Each sports an expansive 6.9-inch Super Retina XDR OLED display with a 120Hz ProMotion refresh rate that keeps animations looking buttery smooth. In the real world, however, the iPhone 18 Pro Max delivers an unmistakable visual upgrade the moment you step outdoors into direct sunlight.</p><p>In our lab testing, the iPhone 18 Pro Max reached an eye-searing 2,326 nits of peak brightness — the highest we’ve ever recorded on an iPhone, and a massive 68% jump over the iPhone 16 Pro Max’s 1,385 nits. The practical advantage is immediate: web pages, camera framing, and video playback remain effortlessly legible with far fewer washed-out reflections bouncing off the glass.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro Max</strong></p></td><td  ><p><strong>iPhone 16 Pro Max</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Display</strong></p></td><td  ><p>6.9-inch Super Retina XDR display (2,868 x 1,320)</p></td><td  ><p>6.9-inch Super Retina XDR display (2,868 x 1,320)</p></td></tr><tr><td class="firstcol " ><p><strong>Peak Brightness</strong></p></td><td  ><p>2,326 nits</p></td><td  ><p>1,385 nits</p></td></tr><tr><td class="firstcol " ><p><strong>sRGB</strong></p></td><td  ><p>115.4%</p></td><td  ><p>114.1%</p></td></tr><tr><td class="firstcol " ><p><strong>DCI-P3</strong></p></td><td  ><p>81.8%</p></td><td  ><p>80.9%</p></td></tr><tr><td class="firstcol " ><p><strong>Delta-E</strong></p></td><td  ><p>0.26</p></td><td  ><p>0.26</p></td></tr></tbody></table></div><p>Another welcomed change is the redesigned Dynamic Island, featuring a noticeably more compact cutout on the iPhone 18 Pro Max. Apple also expanded its software utility, allowing up to three simultaneous Live Activities on the 18 Pro Max versus just two on the 16 Pro Max. While that extra Live Activity slot isn't a massive game-changer on its own, pairing it with such an immensely brighter panel makes the display a decisive win for the 18 Pro Max. </p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-16-pro-max-verdict"><span>iPhone 18 Pro Max vs. iPhone 16 Pro Max: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="FUzJLt6VCjCryFcaixddtP" name="iPhone 18 Pro Max vs iPhone 16 Pro Max-9" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" src="https://cdn.mos.cms.futurecdn.net/FUzJLt6VCjCryFcaixddtP-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I know firsthand how enticing a shiny new phone can be, but even with a two-year gap between these flagships, the case to ditch the iPhone 16 Pro Max for the 18 Pro Max isn’t entirely convincing. That’s even harder to stomach knowing you’ll have to pay more out of pocket thanks to a $100 price hike that pushes the iPhone 18 Pro Max to $1,299.</p><p>In my testing, the biggest areas of improvement come down to the A20 Pro’s exceptional processing muscle, along with key camera additions like the variable aperture and native Pro Controls. Beyond that, there simply isn't an overwhelming reason to justify making the leap.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XZqwAO"></div>                            </div>                            <script src="https://kwizly.com/embed/XZqwAO.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/phones/iphones/scammers-are-using-iphone-duo-pre-orders-to-try-and-steal-your-passwords-heres-how-to-stay-safe">Scammers are using iPhone Duo pre-orders to try and steal your passwords — here's how to stay safe</a></li><li><a href="https://www.tomsguide.com/phones/i-tore-my-living-room-apart-looking-for-the-apple-tv-remote-my-son-hid-but-this-hidden-iphone-feature-saved-the-day">I tore my living room apart looking for the Apple TV remote my son hid — until this iPhone feature saved the day</a></li><li><a href="https://www.tomsguide.com/phones/i-checked-out-the-new-samsung-smarttag3-heres-why-this-tracker-could-be-a-game-changer">I checked out the new Samsung SmartTag3 — here’s why this tracker could be a game-changer</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/i-tested-the-iphone-18-pro-max-vs-iphone-16-pro-max-side-by-side-should-you-upgrade</link>
                                                                            <description>
                            <![CDATA[ In my iPhone 18 Pro Max vs. iPhone 16 Pro Max face-off, I'll tell you if it's worth upgrading to the latest model despite the short 2-year gap between them. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">iGo6NZRa8pKtWGxJoQpc6A</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/X6UQ2Zru45ngm4vmAStyvP-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 02 Oct 2026 04:30:00 +0000</pubDate>                                                                                                                                <updated>Fri, 02 Oct 2026 08:23:37 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ john.velasco@futurenet.com (John Velasco) ]]></author>                    <dc:creator><![CDATA[ John Velasco ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/TSj224oX8d5ERXaDs8pDGd-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/X6UQ2Zru45ngm4vmAStyvP-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 18 Pro Max vs iPhone 16 Pro Max]]></media:description>                                                            <media:text><![CDATA[iPhone 18 Pro Max vs iPhone 16 Pro Max]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 18 Pro Max vs iPhone 16 Pro Max]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/X6UQ2Zru45ngm4vmAStyvP-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Around this time of year, many iPhone owners ask themselves the same question: is it time to upgrade? That’s what I set out to answer in my iPhone 18 Pro Max vs. iPhone 16 Pro Max face-off. The two-year gap between models might tempt some current 16 Pro Max owners to make the jump, even though I generally recommend waiting at least three years.</p><p>In our <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-16-pro-max-review">iPhone 16 Pro Max review</a>, we highlighted standout additions like <a href="https://www.tomsguide.com/phones/iphones/snap-faster-with-iphone-16-how-to-use-the-camera-control-button">Camera Control</a>, an expansive 6.9-inch Super Retina XDR display, and Apple Intelligence right out of the box — along with what turned out to be the lineup’s final 5x optical telephoto lens.</p><p>Fast-forward two years, and there are even more substantial changes detailed in our <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max review</a>, including a new <a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">variable-aperture main camera</a>, the 2nm <a href="https://www.tomsguide.com/phones/iphones/apple-a20-pro-chip-why-its-such-a-big-deal-for-the-iphone-ultra-and-iphone-18-pro-max">A20 Pro silicon</a>, and next-gen Siri AI. But does a two-year cycle offer enough of a generational leap to justify retiring your trusty flagship?</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-16-pro-max-specifications"><span>iPhone 18 Pro Max vs. iPhone 16 Pro Max: Specifications</span></h2><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>iPhone 18 Pro Max</strong></p></th><th  ><p><strong>iPhone 16 Pro Max</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p>From $1,299</p></td><td  ><p>From $1,199*</p></td></tr><tr><td class="firstcol " ><p><strong>Main Display</strong></p></td><td  ><p>6.9-inch Super Retina XDR display (2,868 x 1,320)</p></td><td  ><p>6.9-inch Super Retina XDR display (2,868 x 1,320)</p></td></tr><tr><td class="firstcol " ><p><strong>Refresh Rate</strong></p></td><td  ><p>1-120Hz ProMotion</p></td><td  ><p>1-120Hz ProMotion</p></td></tr><tr><td class="firstcol " ><p><strong>Processor</strong></p></td><td  ><p>A20 Pro</p></td><td  ><p>A18 Pro</p></td></tr><tr><td class="firstcol " ><p><strong>Storage</strong></p></td><td  ><p>256GB, 512GB, 1TB, 2TB</p></td><td  ><p>256GB, 512GB, 1TB</p></td></tr><tr><td class="firstcol " ><p><strong>RAM</strong></p></td><td  ><p>12GB</p></td><td  ><p>12GB</p></td></tr><tr><td class="firstcol " ><p><strong>Front Camera</strong></p></td><td  ><p>18MP Center Stage camera (f/1.9)</p></td><td  ><p>12MP (f/1.9)</p></td></tr><tr><td class="firstcol " ><p><strong>Rear Cameras</strong></p></td><td  ><p>48MP main with variable aperture (f/1.48, f/1.8, f/2.8, f/4), 48MP ultrawide (f/2.2), 48MP telephoto w/4x optical zoom (f/2.8)</p></td><td  ><p>48MP main (f/1.78), 48MP ultrawide (f/2.2), 12MP telephoto w/5x optical zoom (f/2.8)</p></td></tr><tr><td class="firstcol " ><p><strong>Battery Capacity</strong></p></td><td  ><p>5,391 mAh </p></td><td  ><p>4,685 mAh</p></td></tr><tr><td class="firstcol " ><p><strong>Charging</strong></p></td><td  ><p>60W wired, 25W wireless</p></td><td  ><p>30W wired, 25W wireless</p></td></tr><tr><td class="firstcol " ><p><strong>Size</strong></p></td><td  ><p>6.43 x 3.07 x 0.34 inches (163.4 x 78.0 x 8.75 mm)</p></td><td  ><p>6.42 x 3.06 x 0.32 inches (163 x 77.6 x 8.25 mm)</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>8.78 ounces (249 grams)</p></td><td  ><p>8 ounces (227 grams)</p></td></tr><tr><td class="firstcol " ><p><strong>IP Rating</strong></p></td><td  ><p>IP68</p></td><td  ><p>IP68</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Black, Silver, Glacier, Burgundy</p></td><td  ><p>Black, White, Desert, Natural Titanium</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-16-pro-max-cameras"><span>iPhone 18 Pro Max vs. iPhone 16 Pro Max: Cameras</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="B6wwZBtkwHjDPGN452dQsP" name="iPhone 18 Pro Max vs iPhone 16 Pro Max-4" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" src="https://cdn.mos.cms.futurecdn.net/B6wwZBtkwHjDPGN452dQsP-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Let me cut to the chase and focus on what matters most in this matchup: the cameras. There are several significant hardware leaps that make a compelling case for the iPhone 18 Pro Max. First and foremost is the new 48MP main sensor featuring a <a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">mechanical variable aperture</a>, giving photographers physical control over how much light hits the sensor.</p><p>That means more natural, optical bokeh without relying solely on software processing, along with the creative flexibility to dial in motion blur on fast-moving subjects or stop down to keep large group shots in razor-sharp focus from front to back.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/SGfp5XiUJsGDo2kUU43cob-1920-80.jpg" alt="iPhone 18 Pro Max aperture f/4.0" /><figcaption>iPhone 18 Pro Max - Aperture f/4.0<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/QVLjmGvb9JGFx8FxZ8ByVb-1920-80.jpg" alt="iPhone 18 Pro Max aperture f/1.8" /><figcaption>iPhone 18 Pro Max - Aperture f/1.8<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>The iPhone 18 Pro Max also boasts a faster maximum f/1.48 aperture, handing the new iPhone an inherent hardware advantage in challenging low-light conditions. Up front, you get an upgraded 18MP Center Stage selfie camera, a noticeable bump over the 16 Pro Max’s 12MP shooter. Even though the telephoto reach remains at 5x optical zoom across both phones, the 16 Pro Max is clearly out-spec'd across the rest of the camera array.</p><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="CnomJi87LGPQMYz3JC6Qx7" name="iPhone 18 Pro - Pro Controls" alt="iPhone 18 Pro showing Pro Controls." src="https://cdn.mos.cms.futurecdn.net/CnomJi87LGPQMYz3JC6Qx7-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>Beyond the optics, the real game-changer for the 18 Pro Max is the addition of native <a href="https://www.tomsguide.com/phones/iphones/forget-variable-aperture-the-real-upgrade-with-the-iphone-18-pro-max-is-pro-controls">Pro Controls</a> — which I consider just as big an upgrade as the hardware itself. Having manual exposure, shutter speed, and focus tools baked right into the stock camera app is a massive workflow win, sparing you the hassle of jumping into third-party apps just to take full control of your shot.</p><p>Based on all the snapshots I captured, I wouldn’t say that the iPhone 18 Pro Max has an overwhelming advantage purely on performance. Well, not enough to convince me to upgrade. Here’s why.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/EgUESeahegMftQYUN5Swn3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/guzBqtaNZHTBhVHQDyCDo3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 16 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>The beachfront shot above proves my point exactly. Both cameras handle the scene admirably, balancing the highlights and shadows without blowing out the sky. They also resolve nearly identical detail throughout the frame, from the sign along the railing to the grassy dunes in the far background.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/9FEbrAg2evJhjCjd58FNy3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max (4x zoom)<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/jTLAQ3TWE7XwT99MGbEet3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 16 Pro Max (4x zoom)<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>At 4x zoom, it’s pretty clear that the iPhone 18 Pro Max holds a significant advantage. Finer details around the apartment building, like the bricks and graffiti, look sharper with more definition.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/nqwcuE3ufEgK9suEyWbQo3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max (40x zoom)<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/FrizJyDyAEM8N99CYB6Eo3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 16 Pro Max (40x zoom)<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>But when pushed to their outer limits — 40x on the iPhone 18 Pro Max and 25x on the 16 Pro Max — both manage to clearly resolve individual bricks surrounding the graffiti. Despite relying on an older 12MP sensor, the 16 Pro Max’s 5x optical reach holds its own, delivering enough clarity to closely match the 18 Pro Max’s upgraded 48MP telephoto shooter.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/BBx9BrVZ7PduaPKMT72bs3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max.<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/76SEMqHeGrrEGoV6BCrqHf-1920-80.jpg" alt="1 - daytime - iPhone 16 Pro Max.JPG" /><figcaption>iPhone 16 Pro Max.<small role="credit">Future</small></figcaption></figure></figure><p>In broad daylight, both primary cameras consistently impress with wide dynamic range, crisp detail, and dependable color fidelity.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/psi2qb5YtRY2XQyqZHR9v3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/VueEJmQuGs6EBBHmRpQWv3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 16 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>Speaking of dynamic range, you can see how cleanly shadows are lifted against the bright afternoon sky in my Bryant Park test shots above.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/mDx64pvC9jtrGFYZrSiqv3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/omypJK4EK8DsH5AvY7jwt3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 16 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>There are subtle variances in color reproduction: red bell peppers take on a deeper, punchier tone on the iPhone 18 Pro Max, though other shades across the Whole Foods produce display look nearly identical between the two.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/KRw4ArgFLVCWdn6TfTSEp3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/xwfzo84z7B6543kJMGkbq3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 16 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>Macro photography is well-handled on both handsets, provided you keep the phone steady and nail your focus point. That said, I give the nod to the 18 Pro Max for producing richer saturation and sharper petal textures.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/3tbbF4z5EZqgnmVEXJ2UL7-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/CMCWHSZgZQoFpKdtkoCDM7-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 16 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>Despite drastic lighting shifts across the panoramic scene, both phones stitch the frame cleanly into a seamless-looking panorama, balancing highlights and shadow areas to ensure an even final exposure.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/A9tLpCEbe4YyogfhqUKwt3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/wGBsCUXSyucTjxq7feF6w3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 16 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>For selfies, the iPhone 18 Pro Max’s new 18MP Center Stage camera delivers a noticeably wider field of view, making it ideal for group shots. Beyond that expanded framing, however, there’s very little difference in detail or processing to give the newer flagship a runaway victory.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/qyGkSCsRn6GFQBNKef2fo3-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 18 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/SAcM7ae98F4UDQBRrLwX83-1920-80.jpg" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" /><figcaption>iPhone 16 Pro Max<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>When shooting in portrait mode, Apple’s subject-separation algorithms do an exceptional job cutting me out from the background while rendering a convincing, progressive optical falloff. Notice, for instance, how my foreground arm closest to the lens softens naturally into the blur.</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-16-pro-max-battery-and-charging"><span>iPhone 18 Pro Max vs. iPhone 16 Pro Max: Battery and charging</span></h2><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro Max </strong></p></td><td  ><p><strong>iPhone 16 Pro Max </strong></p></td></tr><tr><td class="firstcol " ><p><strong>Battery Size</strong></p></td><td  ><p>5,391 mAh </p></td><td  ><p>4,685 mAh</p></td></tr><tr><td class="firstcol " ><p><strong>Battery Life (hours:minutes)</strong></p></td><td  ><p>18:27 </p></td><td  ><p>17:38</p></td></tr><tr><td class="firstcol " ><p><strong>Charging level in 15 minutes</strong></p></td><td  ><p>53%</p></td><td  ><p>29%</p></td></tr><tr><td class="firstcol " ><p><strong>Charging level in 30 minutes</strong></p></td><td  ><p>80%</p></td><td  ><p>55%</p></td></tr></tbody></table></div><p>Apple packs a substantially larger 5,391 mAh battery into the iPhone 18 Pro Max — roughly a <strong>15% increase in capacity</strong> over the 4,685 mAh cell in the iPhone 16 Pro Max. While a bigger battery doesn’t always guarantee a proportional leap in endurance, our proprietary battery drain test proves it does yield real-world gains.  </p><p>That extra capacity helped the iPhone 18 Pro Max average 18 hours and 27 minutes, outlasting the 16 Pro Max’s already impressive 17 hours and 38 minutes by nearly an hour. Still, across a two-year generational gap, that works out to a modest <strong>4.63% improvement in overall endurance</strong>.   Where you’ll notice a much more dramatic difference is charging speed.</p><p>Thanks to upgraded 60W wired charging, the iPhone 18 Pro Max nearly doubles the charging pace of its older ancestor. In just 15 minutes the 18 Pro Max reaches 53% compared to the 16 Pro Max’s 29%. By the 30-minute mark, the 18 Pro Max surges to 80%, while the 16 Pro Max trails at 55%.   </p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-16-pro-max-performance"><span>iPhone 18 Pro Max vs. iPhone 16 Pro Max: 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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Hzid7dYyFD6su5JduhmMwP" name="iPhone 18 Pro Max vs iPhone 16 Pro Max-8" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" src="https://cdn.mos.cms.futurecdn.net/Hzid7dYyFD6su5JduhmMwP-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Frankly, there has never been an instance where I felt an iPhone was sluggish. Still, looking across our suite of synthetic benchmarks, it is undeniable that the A20 Pro is significantly more capable than the A18 Pro.</p><p>In Geekbench 6, the iPhone 18 Pro Max clocked a single-core score of 4,741 and a multi-core mark of 12,789 — outpacing the 16 Pro Max (3,386 and 8,306) by <strong>40% in single-core and an impressive 54% with multi-core</strong>.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro Max</strong></p></td><td  ><p><strong>iPhone 16 Pro Max</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Chipset</strong></p></td><td  ><p>A20 Pro</p></td><td  ><p>A18 Pro</p></td></tr><tr><td class="firstcol " ><p><strong>Geekbench 6 (single / multi-core)</strong></p></td><td  ><p>4,741 / 12,789</p></td><td  ><p>3,386 / 8,306</p></td></tr><tr><td class="firstcol " ><p><strong>3DMark Solar Bay Unlimited (fps / score)</strong></p></td><td  ><p>67.9 fps / 17,850</p></td><td  ><p>28.1 fps / 7,396</p></td></tr></tbody></table></div><p>While those numbers highlight a substantial CPU leap between generations, graphics testing is where the iPhone 18 Pro Max truly pulls away. Running 3DMark’s Solar Bay Unlimited test, the 18 Pro Max hit an average frame rate of 67.9 fps (17,850 score) versus the 16 Pro Max’s 28.1 fps (7,396 score) — representing a massive <strong>141% surge in graphical performance.</strong> </p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-16-pro-max-software-and-ai"><span>iPhone 18 Pro Max vs. iPhone 16 Pro Max: Software and AI</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="UHFLgbZkizWAuzbea6ATRH" name="iPhone 18 Pro and Pro Max" alt="Siri AI on an iPhone 18 Pro" src="https://cdn.mos.cms.futurecdn.net/UHFLgbZkizWAuzbea6ATRH-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Because both phones run <a href="https://www.tomsguide.com/phones/iphones/ios-27-is-live-heres-how-to-download-and-install-it-now">iOS 27</a>, they offer practically the same everyday experience, core tools, and customizations. That means foundational Apple Intelligence perks — including <a href="https://www.tomsguide.com/phones/i-tried-ios-27-clean-up-vs-galaxy-ai-photo-assist-in-a-7-round-test-and-i-was-surprised-with-how-close-it-was">Clean Up</a> photo editing, <a href="https://www.tomsguide.com/phones/iphones/i-just-installed-the-ios-27-beta-and-reframe-is-unlike-any-other-ai-feature-ive-come-across">Reframe</a>, and <a href="https://www.tomsguide.com/phones/iphones/how-to-create-polls-in-imessage-with-ios-26">interactive polls in Messages</a> — are available across both devices.</p><p>The arrival of <a href="https://www.tomsguide.com/phones/iphones/i-spent-a-week-with-siri-ai-here-are-my-honest-pros-and-cons">Siri AI</a> in iOS 27 signals a major shift for Apple, making the assistant far more proactive with broader automation. For instance, it intelligently suggests creating reminders or calendar entries when someone mentions an upcoming event in Messages.</p><p>I’ve also been genuinely impressed with <a href="https://www.tomsguide.com/phones/iphones/i-just-tried-siri-ai-in-the-ios-27-carplay-beta-and-this-assistant-is-way-more-helpful-than-before">Siri AI in CarPlay</a> because it lets me tackle hands-free tasks I previously couldn't manage safely, such as dictating quick impressions of a vehicle I’m testing from behind the wheel and reopening that same note later to add more details.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1280px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="gEtj6Knu3kZnoSeCRH6ZnQ" name="iOS 27 beta.GIF" alt="iOS 27 beta showing Reframe tool." src="https://cdn.mos.cms.futurecdn.net/gEtj6Knu3kZnoSeCRH6ZnQ-1920-80.gif" mos="" align="middle" fullscreen="" width="1280" height="720" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>However, the <a href="https://www.tomsguide.com/phones/iphones/your-phone-may-run-ios-27-but-only-these-devices-run-everything-siri-ai-can-do">most advanced Siri AI capabilities are exclusive to the iPhone 18 Pro Max</a> and leave the iPhone 16 Pro Max behind. Specifically, Siri’s new Expressive Voices and the upgraded advanced dictation system require hardware that only six iPhone models currently possess. The former gives Siri a far more human, conversational cadence, while the latter dramatically enhances voice-to-text accuracy by smartly filtering out vocal filler words like “ums” and “ahs”.</p><p>Ultimately, the beauty of Apple’s software ecosystem is that the core user experience remains remarkably consistent across generations — even in a two-year flagship matchup like this one.</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-16-pro-max-displays"><span>iPhone 18 Pro Max vs. iPhone 16 Pro Max: Displays</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dgQFoMHqkAGoahKiFKYdrd" name="iPhone 18 Pro and Pro Max-19" alt="Apple iPhone 18 Pro Max" src="https://cdn.mos.cms.futurecdn.net/dgQFoMHqkAGoahKiFKYdrd-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>On paper, both flagships look evenly matched. Each sports an expansive 6.9-inch Super Retina XDR OLED display with a 120Hz ProMotion refresh rate that keeps animations looking buttery smooth. In the real world, however, the iPhone 18 Pro Max delivers an unmistakable visual upgrade the moment you step outdoors into direct sunlight.</p><p>In our lab testing, the iPhone 18 Pro Max reached an eye-searing 2,326 nits of peak brightness — the highest we’ve ever recorded on an iPhone, and a massive 68% jump over the iPhone 16 Pro Max’s 1,385 nits. The practical advantage is immediate: web pages, camera framing, and video playback remain effortlessly legible with far fewer washed-out reflections bouncing off the glass.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro Max</strong></p></td><td  ><p><strong>iPhone 16 Pro Max</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Display</strong></p></td><td  ><p>6.9-inch Super Retina XDR display (2,868 x 1,320)</p></td><td  ><p>6.9-inch Super Retina XDR display (2,868 x 1,320)</p></td></tr><tr><td class="firstcol " ><p><strong>Peak Brightness</strong></p></td><td  ><p>2,326 nits</p></td><td  ><p>1,385 nits</p></td></tr><tr><td class="firstcol " ><p><strong>sRGB</strong></p></td><td  ><p>115.4%</p></td><td  ><p>114.1%</p></td></tr><tr><td class="firstcol " ><p><strong>DCI-P3</strong></p></td><td  ><p>81.8%</p></td><td  ><p>80.9%</p></td></tr><tr><td class="firstcol " ><p><strong>Delta-E</strong></p></td><td  ><p>0.26</p></td><td  ><p>0.26</p></td></tr></tbody></table></div><p>Another welcomed change is the redesigned Dynamic Island, featuring a noticeably more compact cutout on the iPhone 18 Pro Max. Apple also expanded its software utility, allowing up to three simultaneous Live Activities on the 18 Pro Max versus just two on the 16 Pro Max. While that extra Live Activity slot isn't a massive game-changer on its own, pairing it with such an immensely brighter panel makes the display a decisive win for the 18 Pro Max. </p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-16-pro-max-verdict"><span>iPhone 18 Pro Max vs. iPhone 16 Pro Max: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="FUzJLt6VCjCryFcaixddtP" name="iPhone 18 Pro Max vs iPhone 16 Pro Max-9" alt="iPhone 18 Pro Max vs iPhone 16 Pro Max" src="https://cdn.mos.cms.futurecdn.net/FUzJLt6VCjCryFcaixddtP-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I know firsthand how enticing a shiny new phone can be, but even with a two-year gap between these flagships, the case to ditch the iPhone 16 Pro Max for the 18 Pro Max isn’t entirely convincing. That’s even harder to stomach knowing you’ll have to pay more out of pocket thanks to a $100 price hike that pushes the iPhone 18 Pro Max to $1,299.</p><p>In my testing, the biggest areas of improvement come down to the A20 Pro’s exceptional processing muscle, along with key camera additions like the variable aperture and native Pro Controls. Beyond that, there simply isn't an overwhelming reason to justify making the leap.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XZqwAO"></div>                            </div>                            <script src="https://kwizly.com/embed/XZqwAO.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/phones/iphones/scammers-are-using-iphone-duo-pre-orders-to-try-and-steal-your-passwords-heres-how-to-stay-safe">Scammers are using iPhone Duo pre-orders to try and steal your passwords — here's how to stay safe</a></li><li><a href="https://www.tomsguide.com/phones/i-tore-my-living-room-apart-looking-for-the-apple-tv-remote-my-son-hid-but-this-hidden-iphone-feature-saved-the-day">I tore my living room apart looking for the Apple TV remote my son hid — until this iPhone feature saved the day</a></li><li><a href="https://www.tomsguide.com/phones/i-checked-out-the-new-samsung-smarttag3-heres-why-this-tracker-could-be-a-game-changer">I checked out the new Samsung SmartTag3 — here’s why this tracker could be a game-changer</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Apple reveals iPhone Duo has a 'replaceable' display layer — what it means for you ]]></title>
                                                                                                <dc:content><![CDATA[ <p>One of the drawbacks of foldable phones is that the interior display develops a more and more visible crease over time. Apple allegedly delayed the release of the<a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice"> iPhone Duo</a> as the company tried to solve this problem.</p><p>Apple's VP of Hardware Engineering, Kate Bergeron, recently revealed one way that the company is combating creasing: replacement layers.</p><p>Per an interview with <a href="https://www.tiktok.com/@angietutorials/video/7690292682513599776?_r=1&_t=ZP-9ACKGJEeWYZ" target="_blank">@angietutorials on TikTok</a>, Apple made a replacement cover layer on the folding screen.</p>                    <div class= "tiktok-wrapper" style="min-height: 750px;"><blockquote class="tiktok-embed" cite="https://www.tiktok.com/@angietutorials/video/7690292682513599776" data-video-id="7690292682513599776" style="max-width: 605px; min-width: 325px;">                        <section>                            <a target="_blank" title="@angietutorials" href="https://www.tiktok.com/@angietutorials">@angietutorials</a>                            <p></p><a target="_blank" title="♬ I Need a Dollar (Instrumental Version) - Beats Nation" href="https://www.tiktok.com/music/I-Need-a-Dollar-Instrumental-Version-6711856401024550913">♬ I Need a Dollar (Instrumental Version) - Beats Nation</a></section>                    </blockquote></div>                <p>“The matte display coating does a really nice job of, I’ll say, minimizing the crease. But there’s a cover layer on top, and we’ve done a significant amount of engineering work to help that wear in as long a manner as we can, and to make sure that you get the most out of that layer’s performance," Bergeron said.</p><p>"It’s actually replaceable, which is a really nice thing for the customer, that you can peel off that layer and get a new one," she continued.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xb8dKW"></div>                            </div>                            <script src="https://kwizly.com/embed/Xb8dKW.js" async></script><p>This layer, referred to as the Nano Texture "cover layer," is actually considered a separate part of the display per an AppleCare service cost listing spotted by <a href="https://x.com/snazzylabs/status/2105675424944779712" target="_blank">tech YouTuber Quinn Nelson</a>. This cover layer costs $19 for service, while inner display damage will set you back $99.</p><p>I have not seen any reporting or releases from Apple detailing replacement prices for uncovered phones though. If you keep the Duo for a while and the crease starts to bother you, it seems like Apple has a solution. </p><p>Let us know if the crease is a concern for you in the comments below and whether an inexpensive to replace cover layer would make a big difference.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/home/smart-home/apples-homepad-reportedly-coming-oct-13-7-features-you-need-to-know"><strong>Apple's HomePad reportedly coming Oct. 13 — 7 features you need to know</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/get-ready-for-iphone-duo-with-12-great-cases-and-accessories-for-apples-first-foldable"><strong>Get ready for iPhone Duo with 12 great cases and accessories for Apple's first foldable</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/your-using-your-iphone-action-button-wrong-how-ios-27-unlocks-three-features-at-once"><strong>You're using your iPhone Action Button wrong — how iOS 27 unlocks three features at once</strong></a><strong></strong></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/apple-reveals-iphone-duo-has-a-replaceable-display-layer-what-it-means-for-you</link>
                                                                            <description>
                            <![CDATA[ Apple execs revealed that the iPhone Duo has a replaceable layer on the foldable display that can help minimize future crease. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">fAQsMFUTrfEgQAUy2yK7Nn</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/JvujTtKZVT9EXJzzqh9FHV-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 01 Oct 2026 22:36:21 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ scott.younker@futurenet.com (Scott Younker) ]]></author>                    <dc:creator><![CDATA[ Scott Younker ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/RZsUpqcJ6Uj2q83oCUwNhQ-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Scott Younker is the West Coast Reporter at Tom’s Guide. He covers all the latest tech news, including phones, computing and more. He’s been involved in tech since 2011 covering everything from cameras and swimming pool equipment to the latest gaming consoles and smart TVs. He is on a seemingly never ending hunt to build the easiest to use home media system. &lt;/p&gt;&lt;p&gt;Before Tom’s Guide, Scott worked for publications like &lt;em&gt;Digital Trends, Outdoor Photographer, Dead Beats Panel&lt;/em&gt;, and in a brief detour, &lt;em&gt;America’s Funniest Home Videos&lt;/em&gt;. Yes, he has seen more pratfalls, silly pets and ridiculous home movie fails than is reasonably healthy. &lt;/p&gt;&lt;p&gt;When not writing about the latest devices or advances in chipsets, be sure to ask about Scott about disc golf and sustainability, or just if you’re being cheeky, ask about his noodle arm. If you truly want to get nerdy, bring up board games and his ongoing losing streak. &lt;/p&gt;&lt;p&gt;Scott joined Tom&#039;s Guide in 2024 as the West Coast Reporter. He graduated from the School of Journalism at the University of Oregon with a degree in magazine journalism and a minor in communications. While there he blogged or wrote for several magazines including the Fluxx, Ethos and the Oregon Commentator. He briefly wrote and managed a moderately successful blog focused on web comics. &lt;br&gt;Send secure tips on Signal: scyo1.55.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/JvujTtKZVT9EXJzzqh9FHV-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide / Jeff Parsons]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone Duo hands-on pictures]]></media:description>                                                            <media:text><![CDATA[iPhone Duo hands-on pictures]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone Duo hands-on pictures]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/JvujTtKZVT9EXJzzqh9FHV-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>One of the drawbacks of foldable phones is that the interior display develops a more and more visible crease over time. Apple allegedly delayed the release of the<a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice"> iPhone Duo</a> as the company tried to solve this problem.</p><p>Apple's VP of Hardware Engineering, Kate Bergeron, recently revealed one way that the company is combating creasing: replacement layers.</p><p>Per an interview with <a href="https://www.tiktok.com/@angietutorials/video/7690292682513599776?_r=1&_t=ZP-9ACKGJEeWYZ" target="_blank">@angietutorials on TikTok</a>, Apple made a replacement cover layer on the folding screen.</p>                    <div class= "tiktok-wrapper" style="min-height: 750px;"><blockquote class="tiktok-embed" cite="https://www.tiktok.com/@angietutorials/video/7690292682513599776" data-video-id="7690292682513599776" style="max-width: 605px; min-width: 325px;">                        <section>                            <a target="_blank" title="@angietutorials" href="https://www.tiktok.com/@angietutorials">@angietutorials</a>                            <p></p><a target="_blank" title="♬ I Need a Dollar (Instrumental Version) - Beats Nation" href="https://www.tiktok.com/music/I-Need-a-Dollar-Instrumental-Version-6711856401024550913">♬ I Need a Dollar (Instrumental Version) - Beats Nation</a></section>                    </blockquote></div>                <p>“The matte display coating does a really nice job of, I’ll say, minimizing the crease. But there’s a cover layer on top, and we’ve done a significant amount of engineering work to help that wear in as long a manner as we can, and to make sure that you get the most out of that layer’s performance," Bergeron said.</p><p>"It’s actually replaceable, which is a really nice thing for the customer, that you can peel off that layer and get a new one," she continued.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xb8dKW"></div>                            </div>                            <script src="https://kwizly.com/embed/Xb8dKW.js" async></script><p>This layer, referred to as the Nano Texture "cover layer," is actually considered a separate part of the display per an AppleCare service cost listing spotted by <a href="https://x.com/snazzylabs/status/2105675424944779712" target="_blank">tech YouTuber Quinn Nelson</a>. This cover layer costs $19 for service, while inner display damage will set you back $99.</p><p>I have not seen any reporting or releases from Apple detailing replacement prices for uncovered phones though. If you keep the Duo for a while and the crease starts to bother you, it seems like Apple has a solution. </p><p>Let us know if the crease is a concern for you in the comments below and whether an inexpensive to replace cover layer would make a big difference.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/home/smart-home/apples-homepad-reportedly-coming-oct-13-7-features-you-need-to-know"><strong>Apple's HomePad reportedly coming Oct. 13 — 7 features you need to know</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/get-ready-for-iphone-duo-with-12-great-cases-and-accessories-for-apples-first-foldable"><strong>Get ready for iPhone Duo with 12 great cases and accessories for Apple's first foldable</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/your-using-your-iphone-action-button-wrong-how-ios-27-unlocks-three-features-at-once"><strong>You're using your iPhone Action Button wrong — how iOS 27 unlocks three features at once</strong></a><strong></strong></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Get ready for iPhone Duo with 12 great cases and accessories for Apple's first foldable ]]></title>
                                                                                                <dc:content><![CDATA[ <p>If, like us, you're excited about the upcoming iPhone Duo, then you're probably already thinking about how you can kit it out. That's where this page may come in handy. I've selected nine essential accessories and cases that will keep your expensive new toy in pristine condition.</p><p>From screen protectors and cases to essential chargers there are a few options to consider here. I've included mostly official Apple products, but there are also a few third party pieces to choose from too. </p><p>We also have a larger round up of <a href="https://www.tomsguide.com/phones/iphones/dont-let-a-drop-ruin-your-day-these-9-iphone-duo-cases-are-total-lifesavers">iPhone Duo cases</a>, and <a href="https://www.tomsguide.com/phones/iphones/keep-your-new-iphone-18-pro-or-iphone-18-pro-max-safe-from-day-one-the-cases-to-buy-right-now">one for iPhone 18 cases</a> too. So, without further ado, here are my nine picks.</p>        <div class="featured_product_block featured_block_hero" data-id="4c08f0fc-bd8f-11f1-80e2-6f2656706acf">            <a href="https://www.apple.com/shop/product/mlh74am/a/polishing-cloth?fnode=b76c43db709f04c6b1401e6db73f6a53818c583b8e1d55f0aa4c26f4cc7d4739dfe30e4ba555f813b47c4afb5e12ea0533bd331e930644b6f8ba9c78dfcc6fcfbbb07910b56f35d81be2243503a6c0212a7d9edea4b5dc989a8f21b251be539f4ad93fa220918c4a67beb749a3b5d9c2&fs=fh%3D4d4fb2%252Bef8147" data-model-name="Polishing Cloth" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/5gmZ7FctBatmggwLzALzMD.jpg" alt="Polishing Cloth"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Apple</div>                                        <div class="featured__title">Polishing Cloth</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="b0375dc6-bdac-11f1-883a-abd92f3a4f73">            <a href="https://www.apple.com/shop/product/shpg3ll/a/applecare-with-theft-and-loss-for-iphone-duo?fnode=211a586c8c0f157f181176ca312c48235f5a870629796117d0934c5f9798d857d384d0ab181dffedb9530a5cc05e678e7d2b40f21ab648e7f4b63092f1ab55327870089f8b329ec5f13cc5a0599d08186f53753b0a2091bf18a4df812c57b18f" data-model-name="AppleCare+ with Theft and Loss" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/LVqw28rpWQbx2ddoYyxT4L.jpg" alt="Applecare+ With Theft and Loss for Iphone duo"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">AppleCare+ with Theft and Loss</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="b0375e3e-bdac-11f1-9f2c-b51699dcb074">            <a href="https://www.amazon.com/Mkeke-iPhone-Duo-Techwoven-Green/dp/B0HB4P6XHB/" data-model-name="Mkeke for iPhone Duo Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/q7Dh65bGHd5QD5xRaawJaR.jpg" alt="Mkeke for Iphone Duo Case Techwoven Green"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">Mkeke for iPhone Duo Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="4c08f1f6-bd8f-11f1-8bb8-bf284902409a">            <a href="https://www.amazon.com/Apple-40W-Dynamic-Power-Adapter/dp/B0FQFPN3WR/" data-model-name="40w Dynamic Power Adapter" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:98.80%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/PkxBDQvSYeP3QGESi9X2qC.jpg" alt="Apple 40w Dynamic Power Adapter With 60w Max"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Apple</div>                                        <div class="featured__title">40w Dynamic Power Adapter</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="4c08f2e6-bd8f-11f1-a7fe-299c057cdca8">            <a href="https://www.apple.com/shop/product/mgd74ll/a/magsafe-charger-1-m" data-model-name="Apple Magsafe Charger" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/pT3PC4hRrHn4FdyuwbAoSD.jpg" alt="Magsafe Charger (1 m)"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">Apple Magsafe Charger</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="4c08f26e-bd8f-11f1-b35d-9dfbe138b5ad">            <a href="https://www.mous.co/products/tempered-glass-screen-protector?variant=41635147743290" data-model-name="Tempered Glass Screen Protector (2 Pack)" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:133.33%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/eFpdu6kguPMcAWAyZwrMwZ.jpg" alt="Screen Protector, Tempered Glass Screen Protector (2 Pack)"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">Tempered Glass Screen Protector (2 Pack)</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="b0375ed4-bdac-11f1-81be-c357f217e0d0">            <a href="https://www.apple.com/shop/product/hrjm2zm/a/bellroy-travel-organizer?fnode=87c05c77cae05729292b0daa8d03397751b4815badd251626edf3f2c425dc55e542ae0325322f536bff5e06e34a93c5345798d3daf1d05115b80ce88cd8e4aa7ac541966666cdd6fda21a7dd6f84461dd24f366f258849e1e2d98b8b70c73b07" data-model-name="Bellroy Travel Organizer" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:98.75%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/zUQpS7aeRxUmvYcJeMJUpL.jpg" alt="Bellroy Travel Organizer"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">Bellroy Travel Organizer</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="b0375f42-bdac-11f1-ac36-1b6fdcb6bbba">            <a href="https://www.amazon.com/Speck-Presidio-iPhone-Obsidian-Black/dp/B0HC8PXZB4/" data-model-name="Speck Presidio Lux Fold Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/yGB5qHJYzgwEiHDkWDYa5L.jpg" alt="Speck Presidio Lux Fold Case for Iphone 18 Duo, Obsidian Black"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">Speck Presidio Lux Fold Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="4c08f3d6-bd8f-11f1-995b-9b24b9ff2df8">            <a href="https://www.amazon.com/Apple-MUWA3AM-A-Pencil-USB-C/dp/B0CL7J12YK/" data-model-name="Apple Pencil (USB-C)" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/cnnuoi32FUyw2W7asSoKhD.jpg" alt="Apple Pencil (usb-C): Device Compatibility Check Required"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">Apple Pencil (USB-C)</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="217613b4-bd9a-11f1-934b-9d955363ecba">            <a href="https://www.apple.com/us/shop/product/mkr84zm/a/iphone-duo-case-navy-blue?fnode=188a997c6417b9b65287273242a74461068385c9d10d186a0ff36489570b229a94b02a9f03c14588a93f09c10fa1cfe650d26c2abbfa14b6bd768155f15f435199ce2ddd077cb3b42a98f7cade0dab226845b84037d698ce0adf8218e8e6bb68d36bdba5d703bb95dee24d5c95884e8b&fs=fh%3D4d4fb2%252Bef8147" data-model-name="Apple iPhone Duo Case (Navy Blue)" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/iKVjc5umsZ6gXcsvyS69H5.jpg" alt="Iphone Duo Case – Navy Blue"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">Apple iPhone Duo Case (Navy Blue)</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="4c08f44e-bd8f-11f1-aeac-f70b9af05fba">            <a href="https://www.apple.com/shop/product/mkr64zm/a/iphone-duo-folio-with-kickstand-taupe?fnode=b76c43db709f04c6b1401e6db73f6a53818c583b8e1d55f0aa4c26f4cc7d4739dfe30e4ba555f813b47c4afb5e12ea0533bd331e930644b6f8ba9c78dfcc6fcfbbb07910b56f35d81be2243503a6c0212a7d9edea4b5dc989a8f21b251be539f4ad93fa220918c4a67beb749a3b5d9c2&fs=fh%3D4d4fb2%252Bef8147" data-model-name="iPhone Duo Folio With Kickstand (Taupe)" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/ZQT8hMb8sN5k3C9Nw3thKF.jpg" alt="Iphone Duo Folio With Kickstand – Taupe"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Apple</div>                                        <div class="featured__title">iPhone Duo Folio With Kickstand (Taupe)</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="4c08f4c6-bd8f-11f1-a5e9-61a93fd9370d">            <a href="https://www.amazon.com/dp/B0HJB69GJL/" data-model-name="Apple AirPods 5 Wireless Earbuds" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/58pTqsRGjzH3FRbxL7s46E.jpg" alt="Apple Airpods 5 Wireless Earbuds"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">Apple AirPods 5 Wireless Earbuds</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/get-ready-for-iphone-duo-with-12-great-cases-and-accessories-for-apples-first-foldable</link>
                                                                            <description>
                            <![CDATA[ Get ready for the iPhone Duo by picking up some of the essential accessories today. From cases to screen protectors and AirPods there's everything you need to outfit your new smartphone here. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">aFxYhDhTQKSVTmEMVdu8iV</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/LWd2X84GvsiVPXQ3GCyWGm-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 01 Oct 2026 16:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                                    <dc:creator><![CDATA[ Will Salmon ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/HpRWP7Mh9ErgRGoTvZBbBJ-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Will Salmon is Tom&#039;s Guide&#039;s Collections Editor, curating advice on the best products to spend your money on. Will has been writing about tech and entertainment for almost 20 years, including stints as GamesRadar+&#039;s Streaming Editor, editing comics website Newsarama, and writing for lots and lots of magazines.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/LWd2X84GvsiVPXQ3GCyWGm-1920-80.jpg">
                                                            <media:credit><![CDATA[Apple / Edited with Gemini]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[A selection of Apple accessories]]></media:description>                                                            <media:text><![CDATA[A selection of Apple accessories]]></media:text>
                                <media:title type="plain"><![CDATA[A selection of Apple accessories]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/LWd2X84GvsiVPXQ3GCyWGm-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>If, like us, you're excited about the upcoming iPhone Duo, then you're probably already thinking about how you can kit it out. That's where this page may come in handy. I've selected nine essential accessories and cases that will keep your expensive new toy in pristine condition.</p><p>From screen protectors and cases to essential chargers there are a few options to consider here. I've included mostly official Apple products, but there are also a few third party pieces to choose from too. </p><p>We also have a larger round up of <a href="https://www.tomsguide.com/phones/iphones/dont-let-a-drop-ruin-your-day-these-9-iphone-duo-cases-are-total-lifesavers">iPhone Duo cases</a>, and <a href="https://www.tomsguide.com/phones/iphones/keep-your-new-iphone-18-pro-or-iphone-18-pro-max-safe-from-day-one-the-cases-to-buy-right-now">one for iPhone 18 cases</a> too. So, without further ado, here are my nine picks.</p>        <div class="featured_product_block featured_block_hero" data-id="4c08f0fc-bd8f-11f1-80e2-6f2656706acf">            <a href="https://www.apple.com/shop/product/mlh74am/a/polishing-cloth?fnode=b76c43db709f04c6b1401e6db73f6a53818c583b8e1d55f0aa4c26f4cc7d4739dfe30e4ba555f813b47c4afb5e12ea0533bd331e930644b6f8ba9c78dfcc6fcfbbb07910b56f35d81be2243503a6c0212a7d9edea4b5dc989a8f21b251be539f4ad93fa220918c4a67beb749a3b5d9c2&fs=fh%3D4d4fb2%252Bef8147" data-model-name="Polishing Cloth" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/5gmZ7FctBatmggwLzALzMD.jpg" alt="Polishing Cloth"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Apple</div>                                        <div class="featured__title">Polishing Cloth</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="b0375dc6-bdac-11f1-883a-abd92f3a4f73">            <a href="https://www.apple.com/shop/product/shpg3ll/a/applecare-with-theft-and-loss-for-iphone-duo?fnode=211a586c8c0f157f181176ca312c48235f5a870629796117d0934c5f9798d857d384d0ab181dffedb9530a5cc05e678e7d2b40f21ab648e7f4b63092f1ab55327870089f8b329ec5f13cc5a0599d08186f53753b0a2091bf18a4df812c57b18f" data-model-name="AppleCare+ with Theft and Loss" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/LVqw28rpWQbx2ddoYyxT4L.jpg" alt="Applecare+ With Theft and Loss for Iphone duo"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">AppleCare+ with Theft and Loss</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="b0375e3e-bdac-11f1-9f2c-b51699dcb074">            <a href="https://www.amazon.com/Mkeke-iPhone-Duo-Techwoven-Green/dp/B0HB4P6XHB/" data-model-name="Mkeke for iPhone Duo Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/q7Dh65bGHd5QD5xRaawJaR.jpg" alt="Mkeke for Iphone Duo Case Techwoven Green"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">Mkeke for iPhone Duo Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="4c08f1f6-bd8f-11f1-8bb8-bf284902409a">            <a href="https://www.amazon.com/Apple-40W-Dynamic-Power-Adapter/dp/B0FQFPN3WR/" data-model-name="40w Dynamic Power Adapter" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:98.80%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/PkxBDQvSYeP3QGESi9X2qC.jpg" alt="Apple 40w Dynamic Power Adapter With 60w Max"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Apple</div>                                        <div class="featured__title">40w Dynamic Power Adapter</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="4c08f2e6-bd8f-11f1-a7fe-299c057cdca8">            <a href="https://www.apple.com/shop/product/mgd74ll/a/magsafe-charger-1-m" data-model-name="Apple Magsafe Charger" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/pT3PC4hRrHn4FdyuwbAoSD.jpg" alt="Magsafe Charger (1 m)"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">Apple Magsafe Charger</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="4c08f26e-bd8f-11f1-b35d-9dfbe138b5ad">            <a href="https://www.mous.co/products/tempered-glass-screen-protector?variant=41635147743290" data-model-name="Tempered Glass Screen Protector (2 Pack)" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:133.33%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/eFpdu6kguPMcAWAyZwrMwZ.jpg" alt="Screen Protector, Tempered Glass Screen Protector (2 Pack)"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">Tempered Glass Screen Protector (2 Pack)</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="b0375ed4-bdac-11f1-81be-c357f217e0d0">            <a href="https://www.apple.com/shop/product/hrjm2zm/a/bellroy-travel-organizer?fnode=87c05c77cae05729292b0daa8d03397751b4815badd251626edf3f2c425dc55e542ae0325322f536bff5e06e34a93c5345798d3daf1d05115b80ce88cd8e4aa7ac541966666cdd6fda21a7dd6f84461dd24f366f258849e1e2d98b8b70c73b07" data-model-name="Bellroy Travel Organizer" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:98.75%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/zUQpS7aeRxUmvYcJeMJUpL.jpg" alt="Bellroy Travel Organizer"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">Bellroy Travel Organizer</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="b0375f42-bdac-11f1-ac36-1b6fdcb6bbba">            <a href="https://www.amazon.com/Speck-Presidio-iPhone-Obsidian-Black/dp/B0HC8PXZB4/" data-model-name="Speck Presidio Lux Fold Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/yGB5qHJYzgwEiHDkWDYa5L.jpg" alt="Speck Presidio Lux Fold Case for Iphone 18 Duo, Obsidian Black"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">Speck Presidio Lux Fold Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="4c08f3d6-bd8f-11f1-995b-9b24b9ff2df8">            <a href="https://www.amazon.com/Apple-MUWA3AM-A-Pencil-USB-C/dp/B0CL7J12YK/" data-model-name="Apple Pencil (USB-C)" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/cnnuoi32FUyw2W7asSoKhD.jpg" alt="Apple Pencil (usb-C): Device Compatibility Check Required"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">Apple Pencil (USB-C)</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="217613b4-bd9a-11f1-934b-9d955363ecba">            <a href="https://www.apple.com/us/shop/product/mkr84zm/a/iphone-duo-case-navy-blue?fnode=188a997c6417b9b65287273242a74461068385c9d10d186a0ff36489570b229a94b02a9f03c14588a93f09c10fa1cfe650d26c2abbfa14b6bd768155f15f435199ce2ddd077cb3b42a98f7cade0dab226845b84037d698ce0adf8218e8e6bb68d36bdba5d703bb95dee24d5c95884e8b&fs=fh%3D4d4fb2%252Bef8147" data-model-name="Apple iPhone Duo Case (Navy Blue)" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/iKVjc5umsZ6gXcsvyS69H5.jpg" alt="Iphone Duo Case – Navy Blue"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">Apple iPhone Duo Case (Navy Blue)</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="4c08f44e-bd8f-11f1-aeac-f70b9af05fba">            <a href="https://www.apple.com/shop/product/mkr64zm/a/iphone-duo-folio-with-kickstand-taupe?fnode=b76c43db709f04c6b1401e6db73f6a53818c583b8e1d55f0aa4c26f4cc7d4739dfe30e4ba555f813b47c4afb5e12ea0533bd331e930644b6f8ba9c78dfcc6fcfbbb07910b56f35d81be2243503a6c0212a7d9edea4b5dc989a8f21b251be539f4ad93fa220918c4a67beb749a3b5d9c2&fs=fh%3D4d4fb2%252Bef8147" data-model-name="iPhone Duo Folio With Kickstand (Taupe)" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/ZQT8hMb8sN5k3C9Nw3thKF.jpg" alt="Iphone Duo Folio With Kickstand – Taupe"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Apple</div>                                        <div class="featured__title">iPhone Duo Folio With Kickstand (Taupe)</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="4c08f4c6-bd8f-11f1-a5e9-61a93fd9370d">            <a href="https://www.amazon.com/dp/B0HJB69GJL/" data-model-name="Apple AirPods 5 Wireless Earbuds" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/58pTqsRGjzH3FRbxL7s46E.jpg" alt="Apple Airpods 5 Wireless Earbuds"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">Apple AirPods 5 Wireless Earbuds</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Scammers are using iPhone Duo pre-orders to try and steal your passwords — here's how to stay safe ]]></title>
                                                                                                <dc:content><![CDATA[ <p>The <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> isn't available yet, and pre-orders aren't set to open until October 16 — but that doesn't mean you won't see ads promising to let you pre-order the foldable. These ads are a scam, and you should avoid them at all costs.</p><p>Spotted by <a href="https://www.malwarebytes.com/blog/threat-intel/2026/09/fake-iphone-duo-preorder-scam-triggers-darksword-attack" target="_blank">Malwarebytes</a>, this scam promises buyers that they can save $500 by pre-ordering an iPhone Duo. I can see the appeal of that when the Duo starts at $2,000, but that's a big red flag. If something seems too good to be true, it probably is, but logic tends to go out the window when hundreds of dollars are on the line. </p><p>This isn't just your ordinary run-of-the-mill scam, though. Malwarebytes reports that the bogus pre-order page is actually using a leaked <a href="https://www.tomsguide.com/phones/iphones/darksword-exploit-just-went-global-millions-of-iphones-now-wide-open-to-hackers">DarkSword exploit</a> chain to try and crack into vulnerable iPhones. A successful version of this exploit attempts to steal any saved credentials, notes and crypto wallet data. This exploit targets iPhones running iOS 18.4 to iOS 18.6.2, but apparently the offending code shouldn't affect iPads or Macs.</p><p>The scary part? The exploit starts when you open the webpage. You don't need to download or click anything, nor do you have to fill out the fake pre-order form for things to start going south.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1440px;"><p class="vanilla-image-block" style="padding-top:59.72%;"><img id="tdEXbaA7Pp8QRBSTQNx9KW" name="iphone-duo-scam" alt="iphone duo pre-order scam from malwarebytes" src="https://cdn.mos.cms.futurecdn.net/tdEXbaA7Pp8QRBSTQNx9KW-1920-80.webp" mos="" align="middle" fullscreen="" width="1440" height="860" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Malwarebytes)</span></figcaption></figure><p>The page certainly looks legitimate. It has Apple's logos, font, copyright information and overall language style. Unlike a lot of scams there aren't any obvious typos or grammatical mistakes . However all the links to things like the privacy policy and terms & conditions don't actually go anywhere.</p><p>The fake pre-order form does feature some red flags, such as the mention of a "Natural titanium" color, despite the fact the iPhone Duo is only available in Start White and Night Sky (black). It also gets the dimensions wrong, listing size options of 6.3- and 6.9-inches, which are the screen sizes on <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro and Pro Max</a>. The Duo only comes in one size, with a 7.6-inch foldable screen and 5.4-inch cover display.</p><p>But by that point it's already too late and the DarkSword exploit has already begun. However, this form does hand over a bunch of your personal data directly to the scammers, letting them use it as they please. That includes selling it for profit, using it to try and scam you even further and all those other risks that come from exposure of your personal data.</p><h2 id="how-to-protect-yourself">How to protect yourself</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1440px;"><p class="vanilla-image-block" style="padding-top:59.72%;"><img id="Rzui5vrScAsfWKcsW47CFW" name="iphone-duo-scam-colors" alt="iphone duo pre-order scam from malwarebytes" src="https://cdn.mos.cms.futurecdn.net/Rzui5vrScAsfWKcsW47CFW-1920-80.webp" mos="" align="middle" fullscreen="" width="1440" height="860" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Malwarebytes)</span></figcaption></figure><p>The first thing you can do to ensure this scam doesn't affect you, is to update your iPhone to the latest version of iOS. Since it only affects certain versions of <a href="https://www.tomsguide.com/phones/iphones/ios-18">iOS 18,</a> updating to the newly-released iOS 27 will ensure that your iPhone is protected from DarkSword. It also means you have access to the <a href="https://www.tomsguide.com/phones/iphones/ios-27-7-features-you-need-to-try-first-after-updating">best new iOS 27 features</a> and updates, some of which are incredibly useful.</p><p>Apple has patched the exploit already, but it can't forcibly send fixes to your phone if you ignore the update notices iOS sends you. It's not pestering you for the sake of being annoying, those patches are important.</p><p>The second is to always be wary about the kind of links you click — especially if you're not keeping your device software up to date. If an ad is offering something a little too unbelievable, steer clear. Odds are it's some kind of honeypot designed to lure you in for other nefarious purposes. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:5439px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="DrnkS3FeWHhXivG9osdVqd" name="iPhone Duo-4" alt="iPhone Duo hands on" src="https://cdn.mos.cms.futurecdn.net/DrnkS3FeWHhXivG9osdVqd-1920-80.jpg" mos="" align="middle" fullscreen="" width="5439" height="3059" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Finally, be sure to only pre-order iPhones from legitimate channels. That means the <a href="https://www.apple.com/shop/buy-iphone/iphone-duo" target="_blank" rel="nofollow">Apple Store</a>, major retailers like <a href="https://www.walmart.com/ip/Verizon-iPhone-Duo-256GB-Star-White/21018956668?classType=VARIANT&from=/search" target="_blank" rel="nofollow">Walmart</a> or <a href="https://www.bestbuy.com/site/all-iphone/iphone-duo/pcmcat1788453178643.c" target="_blank" rel="nofollow">Best Buy</a>, as well as the <a href="https://www.tomsguide.com/best-picks/best-phone-carrier">best phone carriers</a>. Many of those third parties will also have different deals, but for something as new and<a href="https://www.tomsguide.com/phones/iphones/iphone-duo-report-just-revealed-how-many-apple-is-producing-theres-good-and-bad-news"> sought after</a> as the iPhone Duo they're likely to come in the form of enhanced trade-ins or discounted data plans — not money off the phone itself.</p><p>As for Apple, they almost never offer discounts on their devices, certainly not at the start of their life cycle. So any official looking sites offering major discounts is guaranteed to be some sort of scam. And just to reiterate, <a href="https://www.tomsguide.com/phones/iphones/how-to-save-up-to-usd885-on-the-new-iphone-duo">pre-orders for the Duo open on October 16</a>, and won't be available anywhere until that day.</p><p>If you have already accidentally clicked a potentially dangerous link, don't worry, Malwarebytes recommends updating your phone and restarting it. Apparently the exploit doesn't continue stealing data after a reboot, though there's no telling what they may have stolen before that. If that has happened be sure to create a new crypto wallet with a different recovery phrase, and transfer your money over.</p><p>Likewise, you should change any passwords that may have been stolen.  iOS 27 does have a feature that can do this for you in the event of future data breaches, but for now you'll need to do it all manually.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><a href="https://www.tomsguide.com/phones/ios-27-has-a-hidden-anti-scam-setting-heres-why-every-iphone-user-should-turn-it-on">iOS 27 has a hidden anti-scam setting — here’s why every iPhone user should turn it on</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-variable-aperture-lens-just-added-to-apples-final-cut-camera-heres-how-it-works">iPhone 18 Pro variable aperture lens just added to Apple's Final Cut Camera — here's how it works</a></li><li><a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s27-ultra-may-scrap-the-10mp-telephoto-lens-and-theres-no-word-of-a-replacement">Samsung Galaxy S27 Ultra may scrap the 10MP telephoto lens — and there's no word of a replacement</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/scammers-are-using-iphone-duo-pre-orders-to-try-and-steal-your-passwords-heres-how-to-stay-safe</link>
                                                                            <description>
                            <![CDATA[ iPhone Duo pre-order scams are out there, even though pre-orders haven't opened yet. Here's how you can stay safe. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">YGgcHTamUxTYJG78cTa7cf</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/ENFN2u4hpSYiQYfbA6WbcL-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 30 Sep 2026 11:25:47 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ tom.pritchard@futurenet.com (Tom Pritchard) ]]></author>                    <dc:creator><![CDATA[ Tom Pritchard ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/biCewUkKfSA6QnT2HxVc3f-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/ENFN2u4hpSYiQYfbA6WbcL-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Apple iPhone Duo shown in hand]]></media:description>                                                            <media:text><![CDATA[Apple iPhone Duo shown in hand]]></media:text>
                                <media:title type="plain"><![CDATA[Apple iPhone Duo shown in hand]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/ENFN2u4hpSYiQYfbA6WbcL-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> isn't available yet, and pre-orders aren't set to open until October 16 — but that doesn't mean you won't see ads promising to let you pre-order the foldable. These ads are a scam, and you should avoid them at all costs.</p><p>Spotted by <a href="https://www.malwarebytes.com/blog/threat-intel/2026/09/fake-iphone-duo-preorder-scam-triggers-darksword-attack" target="_blank">Malwarebytes</a>, this scam promises buyers that they can save $500 by pre-ordering an iPhone Duo. I can see the appeal of that when the Duo starts at $2,000, but that's a big red flag. If something seems too good to be true, it probably is, but logic tends to go out the window when hundreds of dollars are on the line. </p><p>This isn't just your ordinary run-of-the-mill scam, though. Malwarebytes reports that the bogus pre-order page is actually using a leaked <a href="https://www.tomsguide.com/phones/iphones/darksword-exploit-just-went-global-millions-of-iphones-now-wide-open-to-hackers">DarkSword exploit</a> chain to try and crack into vulnerable iPhones. A successful version of this exploit attempts to steal any saved credentials, notes and crypto wallet data. This exploit targets iPhones running iOS 18.4 to iOS 18.6.2, but apparently the offending code shouldn't affect iPads or Macs.</p><p>The scary part? The exploit starts when you open the webpage. You don't need to download or click anything, nor do you have to fill out the fake pre-order form for things to start going south.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1440px;"><p class="vanilla-image-block" style="padding-top:59.72%;"><img id="tdEXbaA7Pp8QRBSTQNx9KW" name="iphone-duo-scam" alt="iphone duo pre-order scam from malwarebytes" src="https://cdn.mos.cms.futurecdn.net/tdEXbaA7Pp8QRBSTQNx9KW-1920-80.webp" mos="" align="middle" fullscreen="" width="1440" height="860" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Malwarebytes)</span></figcaption></figure><p>The page certainly looks legitimate. It has Apple's logos, font, copyright information and overall language style. Unlike a lot of scams there aren't any obvious typos or grammatical mistakes . However all the links to things like the privacy policy and terms & conditions don't actually go anywhere.</p><p>The fake pre-order form does feature some red flags, such as the mention of a "Natural titanium" color, despite the fact the iPhone Duo is only available in Start White and Night Sky (black). It also gets the dimensions wrong, listing size options of 6.3- and 6.9-inches, which are the screen sizes on <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro and Pro Max</a>. The Duo only comes in one size, with a 7.6-inch foldable screen and 5.4-inch cover display.</p><p>But by that point it's already too late and the DarkSword exploit has already begun. However, this form does hand over a bunch of your personal data directly to the scammers, letting them use it as they please. That includes selling it for profit, using it to try and scam you even further and all those other risks that come from exposure of your personal data.</p><h2 id="how-to-protect-yourself">How to protect yourself</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1440px;"><p class="vanilla-image-block" style="padding-top:59.72%;"><img id="Rzui5vrScAsfWKcsW47CFW" name="iphone-duo-scam-colors" alt="iphone duo pre-order scam from malwarebytes" src="https://cdn.mos.cms.futurecdn.net/Rzui5vrScAsfWKcsW47CFW-1920-80.webp" mos="" align="middle" fullscreen="" width="1440" height="860" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Malwarebytes)</span></figcaption></figure><p>The first thing you can do to ensure this scam doesn't affect you, is to update your iPhone to the latest version of iOS. Since it only affects certain versions of <a href="https://www.tomsguide.com/phones/iphones/ios-18">iOS 18,</a> updating to the newly-released iOS 27 will ensure that your iPhone is protected from DarkSword. It also means you have access to the <a href="https://www.tomsguide.com/phones/iphones/ios-27-7-features-you-need-to-try-first-after-updating">best new iOS 27 features</a> and updates, some of which are incredibly useful.</p><p>Apple has patched the exploit already, but it can't forcibly send fixes to your phone if you ignore the update notices iOS sends you. It's not pestering you for the sake of being annoying, those patches are important.</p><p>The second is to always be wary about the kind of links you click — especially if you're not keeping your device software up to date. If an ad is offering something a little too unbelievable, steer clear. Odds are it's some kind of honeypot designed to lure you in for other nefarious purposes. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:5439px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="DrnkS3FeWHhXivG9osdVqd" name="iPhone Duo-4" alt="iPhone Duo hands on" src="https://cdn.mos.cms.futurecdn.net/DrnkS3FeWHhXivG9osdVqd-1920-80.jpg" mos="" align="middle" fullscreen="" width="5439" height="3059" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Finally, be sure to only pre-order iPhones from legitimate channels. That means the <a href="https://www.apple.com/shop/buy-iphone/iphone-duo" target="_blank" rel="nofollow">Apple Store</a>, major retailers like <a href="https://www.walmart.com/ip/Verizon-iPhone-Duo-256GB-Star-White/21018956668?classType=VARIANT&from=/search" target="_blank" rel="nofollow">Walmart</a> or <a href="https://www.bestbuy.com/site/all-iphone/iphone-duo/pcmcat1788453178643.c" target="_blank" rel="nofollow">Best Buy</a>, as well as the <a href="https://www.tomsguide.com/best-picks/best-phone-carrier">best phone carriers</a>. Many of those third parties will also have different deals, but for something as new and<a href="https://www.tomsguide.com/phones/iphones/iphone-duo-report-just-revealed-how-many-apple-is-producing-theres-good-and-bad-news"> sought after</a> as the iPhone Duo they're likely to come in the form of enhanced trade-ins or discounted data plans — not money off the phone itself.</p><p>As for Apple, they almost never offer discounts on their devices, certainly not at the start of their life cycle. So any official looking sites offering major discounts is guaranteed to be some sort of scam. And just to reiterate, <a href="https://www.tomsguide.com/phones/iphones/how-to-save-up-to-usd885-on-the-new-iphone-duo">pre-orders for the Duo open on October 16</a>, and won't be available anywhere until that day.</p><p>If you have already accidentally clicked a potentially dangerous link, don't worry, Malwarebytes recommends updating your phone and restarting it. Apparently the exploit doesn't continue stealing data after a reboot, though there's no telling what they may have stolen before that. If that has happened be sure to create a new crypto wallet with a different recovery phrase, and transfer your money over.</p><p>Likewise, you should change any passwords that may have been stolen.  iOS 27 does have a feature that can do this for you in the event of future data breaches, but for now you'll need to do it all manually.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><a href="https://www.tomsguide.com/phones/ios-27-has-a-hidden-anti-scam-setting-heres-why-every-iphone-user-should-turn-it-on">iOS 27 has a hidden anti-scam setting — here’s why every iPhone user should turn it on</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-variable-aperture-lens-just-added-to-apples-final-cut-camera-heres-how-it-works">iPhone 18 Pro variable aperture lens just added to Apple's Final Cut Camera — here's how it works</a></li><li><a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s27-ultra-may-scrap-the-10mp-telephoto-lens-and-theres-no-word-of-a-replacement">Samsung Galaxy S27 Ultra may scrap the 10MP telephoto lens — and there's no word of a replacement</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ iPhone 18 Pro variable aperture lens just added to Apple's Final Cut Camera — here's how it works ]]></title>
                                                                                                <dc:content><![CDATA[ <p>If you want to get professional with your videos, you should check out Final Cut Camera on your iPhone. The Apple-owned app features recording and shooting options that you won't find in the normal Camera app, including exposure control and monitoring tools that pros use.</p><p>For those with or planning to get the<a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review"> iPhone 18 Pro or Pro Max</a>, today <a href="https://www.apple.com/newsroom/2026/09/final-cut-camera-now-supports-variable-aperture-on-iphone-18-pro/" target="_blank">Apple released an update</a> to Final Cut Camera that adds support for the new variable lens, a streamlined UI and more. </p><h2 id="what-is-final-cut-camera">What is Final Cut Camera?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vdJEbco2ETrfLhMYWcXPAF" name="Final Cut Camera 2" alt="Final Cut Camera on iPhone 18 Pro" src="https://cdn.mos.cms.futurecdn.net/vdJEbco2ETrfLhMYWcXPAF-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>For the unfamiliar, the iOS Camera app is already pretty good for shooting videos with simple controls, HDR and SDR recording, slow motion and even a Cinematic mode. However, if you want more control with settings and option adjustments, it can be a bit of a pain.</p><p>Final Cut Camera puts those controls front and center with an interface that lets you swap between exposure modes, change frame rate, color modes and encoding formats. It also includes multicam recording to sync multiple iPhones. </p><h2 id="what-39-s-new">What's new</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9NnJ8eMP36sKQ9iKKbe7i7" name="Final Cut Camera edit" alt="Final Cut Camera on iPhone 18 Pro" src="https://cdn.mos.cms.futurecdn.net/9NnJ8eMP36sKQ9iKKbe7i7-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>Version 2.4 brings a new interface meant to give you easier access to settings like shutter angle, ISO, and white balance using customizable overlays. The updated controls include a new tally light to indicate when recording is underway, and a two-finger tap control to clear the viewfinder so you can see your shot.</p><p>The update also supports the new Variable Aperture lens in the iPhone 18 Pro models. This will let you dial in your aperture settings or choose your shutter priority and aperture priority modes.</p><p>For editing, version 2.4 gets Cinematic mode effects for your videos including those captured in ProRes and Apple Log. This will let you adjust focus points and depth of field while editing in Final Cut Pro.</p><p>Finally, in iOS 27  the app now has support for professional video scopes, clean SDI out and genlock offset.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-report-just-revealed-how-many-apple-is-producing-theres-good-and-bad-news"><strong>iPhone Duo report just revealed how many Apple is producing — there's good and bad news</strong></a></li><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/i-walked-5-000-steps-with-the-apple-watch-series-12-and-the-garmin-forerunner-570-heres-which-watch-came-out-on-top"><strong>I walked 5,000 steps with the Apple Watch Series 12 and the Garmin Forerunner 570 — here’s which watch came out on top</strong></a></li><li><a href="https://www.tomsguide.com/vehicle-tech/i-tested-google-maps-immersive-navigation-for-2-weeks-and-it-makes-seeing-tricky-exits-a-breeze-on-apple-carplay-and-android-auto"><strong>I tested Google Maps Immersive Navigation for 2 weeks — and it makes seeing tricky exits a breeze on Apple CarPlay and Android Auto</strong></a></li></ul><h2 id=""></h2> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/iphone-18-pro-variable-aperture-lens-just-added-to-apples-final-cut-camera-heres-how-it-works</link>
                                                                            <description>
                            <![CDATA[ Apple just released updates for Final Cut Camera that make editing and shooting much better. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">THANny6j6ikMyLrA8NrtHU</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/25cQefcDjAhiob5rfz67BV-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 29 Sep 2026 20:57:02 +0000</pubDate>                                                                                                                                <updated>Tue, 29 Sep 2026 23:25:25 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ scott.younker@futurenet.com (Scott Younker) ]]></author>                    <dc:creator><![CDATA[ Scott Younker ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/RZsUpqcJ6Uj2q83oCUwNhQ-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Scott Younker is the West Coast Reporter at Tom’s Guide. He covers all the latest tech news, including phones, computing and more. He’s been involved in tech since 2011 covering everything from cameras and swimming pool equipment to the latest gaming consoles and smart TVs. He is on a seemingly never ending hunt to build the easiest to use home media system. &lt;/p&gt;&lt;p&gt;Before Tom’s Guide, Scott worked for publications like &lt;em&gt;Digital Trends, Outdoor Photographer, Dead Beats Panel&lt;/em&gt;, and in a brief detour, &lt;em&gt;America’s Funniest Home Videos&lt;/em&gt;. Yes, he has seen more pratfalls, silly pets and ridiculous home movie fails than is reasonably healthy. &lt;/p&gt;&lt;p&gt;When not writing about the latest devices or advances in chipsets, be sure to ask about Scott about disc golf and sustainability, or just if you’re being cheeky, ask about his noodle arm. If you truly want to get nerdy, bring up board games and his ongoing losing streak. &lt;/p&gt;&lt;p&gt;Scott joined Tom&#039;s Guide in 2024 as the West Coast Reporter. He graduated from the School of Journalism at the University of Oregon with a degree in magazine journalism and a minor in communications. While there he blogged or wrote for several magazines including the Fluxx, Ethos and the Oregon Commentator. He briefly wrote and managed a moderately successful blog focused on web comics. &lt;br&gt;Send secure tips on Signal: scyo1.55.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/25cQefcDjAhiob5rfz67BV-1920-80.jpg">
                                                            <media:credit><![CDATA[Apple]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Final Cut Camera version 2.4]]></media:description>                                                            <media:text><![CDATA[Final Cut Camera version 2.4]]></media:text>
                                <media:title type="plain"><![CDATA[Final Cut Camera version 2.4]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/25cQefcDjAhiob5rfz67BV-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>If you want to get professional with your videos, you should check out Final Cut Camera on your iPhone. The Apple-owned app features recording and shooting options that you won't find in the normal Camera app, including exposure control and monitoring tools that pros use.</p><p>For those with or planning to get the<a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review"> iPhone 18 Pro or Pro Max</a>, today <a href="https://www.apple.com/newsroom/2026/09/final-cut-camera-now-supports-variable-aperture-on-iphone-18-pro/" target="_blank">Apple released an update</a> to Final Cut Camera that adds support for the new variable lens, a streamlined UI and more. </p><h2 id="what-is-final-cut-camera">What is Final Cut Camera?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vdJEbco2ETrfLhMYWcXPAF" name="Final Cut Camera 2" alt="Final Cut Camera on iPhone 18 Pro" src="https://cdn.mos.cms.futurecdn.net/vdJEbco2ETrfLhMYWcXPAF-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>For the unfamiliar, the iOS Camera app is already pretty good for shooting videos with simple controls, HDR and SDR recording, slow motion and even a Cinematic mode. However, if you want more control with settings and option adjustments, it can be a bit of a pain.</p><p>Final Cut Camera puts those controls front and center with an interface that lets you swap between exposure modes, change frame rate, color modes and encoding formats. It also includes multicam recording to sync multiple iPhones. </p><h2 id="what-39-s-new">What's new</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9NnJ8eMP36sKQ9iKKbe7i7" name="Final Cut Camera edit" alt="Final Cut Camera on iPhone 18 Pro" src="https://cdn.mos.cms.futurecdn.net/9NnJ8eMP36sKQ9iKKbe7i7-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>Version 2.4 brings a new interface meant to give you easier access to settings like shutter angle, ISO, and white balance using customizable overlays. The updated controls include a new tally light to indicate when recording is underway, and a two-finger tap control to clear the viewfinder so you can see your shot.</p><p>The update also supports the new Variable Aperture lens in the iPhone 18 Pro models. This will let you dial in your aperture settings or choose your shutter priority and aperture priority modes.</p><p>For editing, version 2.4 gets Cinematic mode effects for your videos including those captured in ProRes and Apple Log. This will let you adjust focus points and depth of field while editing in Final Cut Pro.</p><p>Finally, in iOS 27  the app now has support for professional video scopes, clean SDI out and genlock offset.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-report-just-revealed-how-many-apple-is-producing-theres-good-and-bad-news"><strong>iPhone Duo report just revealed how many Apple is producing — there's good and bad news</strong></a></li><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/i-walked-5-000-steps-with-the-apple-watch-series-12-and-the-garmin-forerunner-570-heres-which-watch-came-out-on-top"><strong>I walked 5,000 steps with the Apple Watch Series 12 and the Garmin Forerunner 570 — here’s which watch came out on top</strong></a></li><li><a href="https://www.tomsguide.com/vehicle-tech/i-tested-google-maps-immersive-navigation-for-2-weeks-and-it-makes-seeing-tricky-exits-a-breeze-on-apple-carplay-and-android-auto"><strong>I tested Google Maps Immersive Navigation for 2 weeks — and it makes seeing tricky exits a breeze on Apple CarPlay and Android Auto</strong></a></li></ul><h2 id=""></h2>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ iPhone Duo report just revealed how many Apple is producing — there's good and bad news ]]></title>
                                                                                                <dc:content><![CDATA[ <p>A new report from the Chinese publication <a href="https://www.jiemian.com/article/15109695.html" target="_blank">Jiemian News</a> revealed both bad news and good news about <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> production. </p><p>According to the article, Apple has not completed the expected mass production ramp-up for the company's first foldable phone. Foxconn, Apple's manufacturing partner, has only managed a yield rate of 60%, even with a small production run. </p><p>The yield percentage refers to the number of viable devices created during a manufacturing run. At 60%, that means 40% of the produced devices have some flaw that would prevent Apple from selling them.</p><p>Even before the announcement earlier this month, it was <a href="https://www.tomsguide.com/phones/iphones/iphone-ultra-latest-release-date-rumors-heres-when-we-expect-it-to-launch">rumored that Apple was having production issues</a> and that it would only be available in "extremely limited stock." Largely, this is based on the complicated manufacturing process for the foldable phone.</p><h2 id="exacting-standards">Exacting standards</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/2qNfOa5AuVU" allowfullscreen></iframe></div></div><p>Here's the caveated good news: per Jiemian, the low yield is thanks to Apple's quality standards, which the company refuses to relax.</p><p>"The supply chain is now waiting for Apple to make a decision on whether to relax the quality requirements," an unnamed source who is allegedly close to the Foxconn supply chain told the outlet (machine translated). "If the quality requirements are relaxed, it will be possible to move towards mass production more quickly."</p><p>The source reported that the production line is still debugging the process and repeatedly adjusting things during actual production to optimize equipment and processes.</p><p>Reportedly, delays in receiving Samsung Display's OLED panels and some hinge-components have also contributed to delays and lower yields.</p><p>Manufacturing isn't expecting to reach maturity for at least another six months.</p><p>Apple is only expected to produce around 6 to 8 million iPhone Duo units for its global inventory, a third of what the company will make for the more mature iPhone 18 Pro and Pro Max, which should get between 20 and 30 million.</p><h2 id="expectations-and-price">Expectations and price</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="uXT4kgo4D8JQqjmnEb4VfM" name="iPhone Duo standby" alt="The iPhone Duo standing on a surface showing StandBy mode" src="https://cdn.mos.cms.futurecdn.net/uXT4kgo4D8JQqjmnEb4VfM-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>If Apple is able to sell out an initial inventory of 8 million Duos, that would be a major win for the company. </p><p>We're still two weeks out from the launch date of October 16, and <a href="https://www.tomsguide.com/phones/iphones/how-to-save-up-to-usd885-on-the-new-iphone-duo">you can preorder now</a> if you're interested.</p><p>With a starting price of $1,999, Apple's take on the foldable is more expensive than the <a href="https://www.tomsguide.com/phones/samsung-phones/ive-been-living-with-the-galaxy-z-fold-8-for-3-weeks-and-i-was-wrong">Samsung Galaxy Z Fold 8</a>, but it's nice to know that Apple's high standards means you should get a quality, working device if you buy one.</p><p>Apple is causing quite the stir with the Duo but, it'll be interesting to see if customers respond. As we found in a <a href="https://www.tomsguide.com/phones/iphones/the-iphone-duo-has-a-lot-of-hype-but-this-poll-has-a-surprising-reveal-for-samsungs-foldable">recent reader poll</a>, most of you are more interested in the Z Fold 8 which has seen a <a href="https://www.androidcentral.com/phones/samsung-galaxy/after-the-iphone-duo-the-galaxy-z-fold-8-just-got-even-more-popular" target="_blank">surge in popularity </a>since Apple's announcement.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/computing/online-security/apple-issues-emergency-update-for-millions-of-iphones-ipads-and-macs-update-your-devices-now"><strong>Apple issues emergency update for millions of iPhones, iPads, and Macs — update your devices now</strong></a></li><li><a href="https://www.tomsguide.com/vehicle-tech/i-tested-google-maps-immersive-navigation-for-2-weeks-and-it-makes-seeing-tricky-exits-a-breeze-on-apple-carplay-and-android-auto"><strong>I tested Google Maps Immersive Navigation for 2 weeks — and it makes seeing tricky exits a breeze on Apple CarPlay and Android Auto</strong></a></li><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/i-walked-5-000-steps-with-the-apple-watch-series-12-and-the-garmin-forerunner-570-heres-which-watch-came-out-on-top"><strong>I walked 5,000 steps with the Apple Watch Series 12 and the Garmin Forerunner 570 — here’s which watch came out on top</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/iphone-duo-report-just-revealed-how-many-apple-is-producing-theres-good-and-bad-news</link>
                                                                            <description>
                            <![CDATA[ A new report reveals good news and bad news about iPhone Duo production. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">QfrYhwNMQtKiS5M7goXsxQ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/DrnkS3FeWHhXivG9osdVqd-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 29 Sep 2026 19:20:06 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ scott.younker@futurenet.com (Scott Younker) ]]></author>                    <dc:creator><![CDATA[ Scott Younker ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/RZsUpqcJ6Uj2q83oCUwNhQ-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Scott Younker is the West Coast Reporter at Tom’s Guide. He covers all the latest tech news, including phones, computing and more. He’s been involved in tech since 2011 covering everything from cameras and swimming pool equipment to the latest gaming consoles and smart TVs. He is on a seemingly never ending hunt to build the easiest to use home media system. &lt;/p&gt;&lt;p&gt;Before Tom’s Guide, Scott worked for publications like &lt;em&gt;Digital Trends, Outdoor Photographer, Dead Beats Panel&lt;/em&gt;, and in a brief detour, &lt;em&gt;America’s Funniest Home Videos&lt;/em&gt;. Yes, he has seen more pratfalls, silly pets and ridiculous home movie fails than is reasonably healthy. &lt;/p&gt;&lt;p&gt;When not writing about the latest devices or advances in chipsets, be sure to ask about Scott about disc golf and sustainability, or just if you’re being cheeky, ask about his noodle arm. If you truly want to get nerdy, bring up board games and his ongoing losing streak. &lt;/p&gt;&lt;p&gt;Scott joined Tom&#039;s Guide in 2024 as the West Coast Reporter. He graduated from the School of Journalism at the University of Oregon with a degree in magazine journalism and a minor in communications. While there he blogged or wrote for several magazines including the Fluxx, Ethos and the Oregon Commentator. He briefly wrote and managed a moderately successful blog focused on web comics. &lt;br&gt;Send secure tips on Signal: scyo1.55.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/DrnkS3FeWHhXivG9osdVqd-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone Duo hands on]]></media:description>                                                            <media:text><![CDATA[iPhone Duo hands on]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone Duo hands on]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/DrnkS3FeWHhXivG9osdVqd-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>A new report from the Chinese publication <a href="https://www.jiemian.com/article/15109695.html" target="_blank">Jiemian News</a> revealed both bad news and good news about <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> production. </p><p>According to the article, Apple has not completed the expected mass production ramp-up for the company's first foldable phone. Foxconn, Apple's manufacturing partner, has only managed a yield rate of 60%, even with a small production run. </p><p>The yield percentage refers to the number of viable devices created during a manufacturing run. At 60%, that means 40% of the produced devices have some flaw that would prevent Apple from selling them.</p><p>Even before the announcement earlier this month, it was <a href="https://www.tomsguide.com/phones/iphones/iphone-ultra-latest-release-date-rumors-heres-when-we-expect-it-to-launch">rumored that Apple was having production issues</a> and that it would only be available in "extremely limited stock." Largely, this is based on the complicated manufacturing process for the foldable phone.</p><h2 id="exacting-standards">Exacting standards</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/2qNfOa5AuVU" allowfullscreen></iframe></div></div><p>Here's the caveated good news: per Jiemian, the low yield is thanks to Apple's quality standards, which the company refuses to relax.</p><p>"The supply chain is now waiting for Apple to make a decision on whether to relax the quality requirements," an unnamed source who is allegedly close to the Foxconn supply chain told the outlet (machine translated). "If the quality requirements are relaxed, it will be possible to move towards mass production more quickly."</p><p>The source reported that the production line is still debugging the process and repeatedly adjusting things during actual production to optimize equipment and processes.</p><p>Reportedly, delays in receiving Samsung Display's OLED panels and some hinge-components have also contributed to delays and lower yields.</p><p>Manufacturing isn't expecting to reach maturity for at least another six months.</p><p>Apple is only expected to produce around 6 to 8 million iPhone Duo units for its global inventory, a third of what the company will make for the more mature iPhone 18 Pro and Pro Max, which should get between 20 and 30 million.</p><h2 id="expectations-and-price">Expectations and price</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="uXT4kgo4D8JQqjmnEb4VfM" name="iPhone Duo standby" alt="The iPhone Duo standing on a surface showing StandBy mode" src="https://cdn.mos.cms.futurecdn.net/uXT4kgo4D8JQqjmnEb4VfM-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>If Apple is able to sell out an initial inventory of 8 million Duos, that would be a major win for the company. </p><p>We're still two weeks out from the launch date of October 16, and <a href="https://www.tomsguide.com/phones/iphones/how-to-save-up-to-usd885-on-the-new-iphone-duo">you can preorder now</a> if you're interested.</p><p>With a starting price of $1,999, Apple's take on the foldable is more expensive than the <a href="https://www.tomsguide.com/phones/samsung-phones/ive-been-living-with-the-galaxy-z-fold-8-for-3-weeks-and-i-was-wrong">Samsung Galaxy Z Fold 8</a>, but it's nice to know that Apple's high standards means you should get a quality, working device if you buy one.</p><p>Apple is causing quite the stir with the Duo but, it'll be interesting to see if customers respond. As we found in a <a href="https://www.tomsguide.com/phones/iphones/the-iphone-duo-has-a-lot-of-hype-but-this-poll-has-a-surprising-reveal-for-samsungs-foldable">recent reader poll</a>, most of you are more interested in the Z Fold 8 which has seen a <a href="https://www.androidcentral.com/phones/samsung-galaxy/after-the-iphone-duo-the-galaxy-z-fold-8-just-got-even-more-popular" target="_blank">surge in popularity </a>since Apple's announcement.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/computing/online-security/apple-issues-emergency-update-for-millions-of-iphones-ipads-and-macs-update-your-devices-now"><strong>Apple issues emergency update for millions of iPhones, iPads, and Macs — update your devices now</strong></a></li><li><a href="https://www.tomsguide.com/vehicle-tech/i-tested-google-maps-immersive-navigation-for-2-weeks-and-it-makes-seeing-tricky-exits-a-breeze-on-apple-carplay-and-android-auto"><strong>I tested Google Maps Immersive Navigation for 2 weeks — and it makes seeing tricky exits a breeze on Apple CarPlay and Android Auto</strong></a></li><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/i-walked-5-000-steps-with-the-apple-watch-series-12-and-the-garmin-forerunner-570-heres-which-watch-came-out-on-top"><strong>I walked 5,000 steps with the Apple Watch Series 12 and the Garmin Forerunner 570 — here’s which watch came out on top</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ iPhone Duo leak reveals a bunch of StandBy details Apple didn't tell us about — including what sounds like a smart home display ]]></title>
                                                                                                <dc:content><![CDATA[ <p>After Apple revealed the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> at its<a href="https://www.tomsguide.com/phones/iphones/apple-september-event-preview-all-the-new-products-to-expect-at-iphone-18-pro-launch-and-beyond"> September launch event</a>, you may have assumed we'd found out everything there is to know about the phone. That's apparently not the case. A new leak has revealed specific details about the foldable's StandBy Mode that Apple hasn't officially shared yet.</p><p>Apple already confirmed that StandBy would be coming to iPhone Duo, and that the feature would work regardless of the physical configuration of the phone. It's also available to use without having to plug the Duo  in to charge, which is a privilege the company doesn't offer to other iPhones. But <a href="https://x.com/itspdfu/status/2104567049963921785" target="_blank">leaker pdfu</a> just discovered a bunch more uses, thanks to a code deep-dive.</p><div class="see-more see-more--clipped"><figure><blockquote class="twitter-tweet hawk-ignore" data-lang="en" cite="https://twitter.com/cantworkitout/status/2104567049963921785"><p lang="en" dir="ltr">Here’s a deep dive into StandBy mode on iPhone Duo.Rushmore, the app meant to host the redesigned faces, is missing from the iOS 27.1 simulator.But its localization strings reveal unreported faces, and I got some new faces running in the current renderer. 🧵 pic.twitter.com/lDQHOy5R0e<a href="https://twitter.com/cantworkitout/status/2104567049963921785">September 28, 2026</a></p></blockquote></figure><div class="see-more__filter"></div></div><p>Specifically pdfu uncovered several new <a href="https://x.com/itspdfu/status/2104567050463014985" target="_blank">StandBy faces</a> for the iPhone Duo, including:</p><ul><li>Home Camera, which features between one and nine live camera feeds</li><li>Home Modular, which pdfu speculates is a screen focused on home accessories</li><li>Flow, which is assumed to be an abstract animated design</li><li>Face, which is a total unknown</li><li>Snoopy, which is almost certainly another Apple tie-in with Peanuts</li></ul><p>To me, that suggests Apple is prepping StandBy Mode to be more of a smart home hub than a glorified clock and weather device. Considering the long-standing rumors that<a href="https://www.tomsguide.com/home/smart-home/apple-homepad-rumored-release-date-price-and-all-the-latest-leaks"> Apple has a dedicated Smart Display in the works</a> (tentatively called the HomePad), it makes sense that it would try and expand those features to tablet-like devices like iPhone Duo.</p><p>The question is whether <a href="https://www.tomsguide.com/computing/ipads/ipados-27-how-to-download-it-right-now">iPadOS</a> may finally get its own StandBy mode as well. If the Duo is getting its own version, and without needing to charge, then there's little reason why iPads can't follow suit. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xj2RQX"></div>                            </div>                            <script src="https://kwizly.com/embed/Xj2RQX.js" async></script><div class="see-more see-more--clipped"><figure><blockquote class="twitter-tweet hawk-ignore" data-lang="en" cite="https://twitter.com/cantworkitout/status/2104567050924368286"><p lang="en" dir="ltr">Here’s the new face editor.Its design closely matches the Apple Watch face editor. You can swipe between settings, then scroll through available options.Next, a closer look at three faces I managed to get running: pic.twitter.com/Hlv7xBmulG<a href="https://twitter.com/cantworkitout/status/2104567050924368286">September 28, 2026</a></p></blockquote></figure><div class="see-more__filter"></div></div><p>Pdfu also discovered a new <a href="https://x.com/itspdfu/status/2104567050924368286" target="_blank">face editor</a>, which they liken to the Apple Watch face editor. This mode lets you swipe between settings and different options. Those options include a calendar, plus analog and digital clock faces, with different looks, fonts and color options to choose from.</p><p>The code also mentions five separate layouts for the Duo's StandBy mode, including StandBy, Stacked, Top, Middle and Bottom. Pdfu speculates that the last four are intended for the foldable screen, while StandBy sounds just like the normal StandBy mode iPhones have had for a few years.</p><p>You can see all the leaked designs in greater detail by checking out <a href="https://x.com/itspdfu/status/2104567049963921785" target="_blank">pdfu's thread</a> on X. Meanwhile, let me know what your early impressions are of the iPhone Duo in the comments below.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><a href="https://www.tomsguide.com/phones/samsung-phones/5-ways-galaxy-s27-ultra-can-beat-the-iphone-18-pro-and-2-ways-apple-will-still-win">5 ways Galaxy S27 Ultra can beat the iPhone 18 Pro — and 2 ways Apple will still win</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-7-features-youre-giving-up-by-not-buying-the-iphone-18-pro-max">iPhone Duo: 7 features you’re giving up by not buying the iPhone 18 Pro Max</a></li><li><a href="https://www.tomsguide.com/phones/iphones/the-real-reason-why-iphone-duo-will-beat-all-android-foldable-phones">The real reason why iPhone Duo will beat all Android foldable phones</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/iphone-duo-leak-reveals-a-bunch-of-standby-details-apple-didnt-tell-us-about-including-what-sounds-like-a-smart-home-display</link>
                                                                            <description>
                            <![CDATA[ A code dive may have just revealed the iPhone Duo StandBy features Apple hasn't told us about yet. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">WdDYHyjJCJuigef26rtEwP</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/uXT4kgo4D8JQqjmnEb4VfM-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 29 Sep 2026 11:19:10 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ tom.pritchard@futurenet.com (Tom Pritchard) ]]></author>                    <dc:creator><![CDATA[ Tom Pritchard ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/biCewUkKfSA6QnT2HxVc3f-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/uXT4kgo4D8JQqjmnEb4VfM-1920-80.jpg">
                                                            <media:credit><![CDATA[Apple]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[The iPhone Duo standing on a surface showing StandBy mode]]></media:description>                                                            <media:text><![CDATA[The iPhone Duo standing on a surface showing StandBy mode]]></media:text>
                                <media:title type="plain"><![CDATA[The iPhone Duo standing on a surface showing StandBy mode]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/uXT4kgo4D8JQqjmnEb4VfM-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>After Apple revealed the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> at its<a href="https://www.tomsguide.com/phones/iphones/apple-september-event-preview-all-the-new-products-to-expect-at-iphone-18-pro-launch-and-beyond"> September launch event</a>, you may have assumed we'd found out everything there is to know about the phone. That's apparently not the case. A new leak has revealed specific details about the foldable's StandBy Mode that Apple hasn't officially shared yet.</p><p>Apple already confirmed that StandBy would be coming to iPhone Duo, and that the feature would work regardless of the physical configuration of the phone. It's also available to use without having to plug the Duo  in to charge, which is a privilege the company doesn't offer to other iPhones. But <a href="https://x.com/itspdfu/status/2104567049963921785" target="_blank">leaker pdfu</a> just discovered a bunch more uses, thanks to a code deep-dive.</p><div class="see-more see-more--clipped"><figure><blockquote class="twitter-tweet hawk-ignore" data-lang="en" cite="https://twitter.com/cantworkitout/status/2104567049963921785"><p lang="en" dir="ltr">Here’s a deep dive into StandBy mode on iPhone Duo.Rushmore, the app meant to host the redesigned faces, is missing from the iOS 27.1 simulator.But its localization strings reveal unreported faces, and I got some new faces running in the current renderer. 🧵 pic.twitter.com/lDQHOy5R0e<a href="https://twitter.com/cantworkitout/status/2104567049963921785">September 28, 2026</a></p></blockquote></figure><div class="see-more__filter"></div></div><p>Specifically pdfu uncovered several new <a href="https://x.com/itspdfu/status/2104567050463014985" target="_blank">StandBy faces</a> for the iPhone Duo, including:</p><ul><li>Home Camera, which features between one and nine live camera feeds</li><li>Home Modular, which pdfu speculates is a screen focused on home accessories</li><li>Flow, which is assumed to be an abstract animated design</li><li>Face, which is a total unknown</li><li>Snoopy, which is almost certainly another Apple tie-in with Peanuts</li></ul><p>To me, that suggests Apple is prepping StandBy Mode to be more of a smart home hub than a glorified clock and weather device. Considering the long-standing rumors that<a href="https://www.tomsguide.com/home/smart-home/apple-homepad-rumored-release-date-price-and-all-the-latest-leaks"> Apple has a dedicated Smart Display in the works</a> (tentatively called the HomePad), it makes sense that it would try and expand those features to tablet-like devices like iPhone Duo.</p><p>The question is whether <a href="https://www.tomsguide.com/computing/ipads/ipados-27-how-to-download-it-right-now">iPadOS</a> may finally get its own StandBy mode as well. If the Duo is getting its own version, and without needing to charge, then there's little reason why iPads can't follow suit. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xj2RQX"></div>                            </div>                            <script src="https://kwizly.com/embed/Xj2RQX.js" async></script><div class="see-more see-more--clipped"><figure><blockquote class="twitter-tweet hawk-ignore" data-lang="en" cite="https://twitter.com/cantworkitout/status/2104567050924368286"><p lang="en" dir="ltr">Here’s the new face editor.Its design closely matches the Apple Watch face editor. You can swipe between settings, then scroll through available options.Next, a closer look at three faces I managed to get running: pic.twitter.com/Hlv7xBmulG<a href="https://twitter.com/cantworkitout/status/2104567050924368286">September 28, 2026</a></p></blockquote></figure><div class="see-more__filter"></div></div><p>Pdfu also discovered a new <a href="https://x.com/itspdfu/status/2104567050924368286" target="_blank">face editor</a>, which they liken to the Apple Watch face editor. This mode lets you swipe between settings and different options. Those options include a calendar, plus analog and digital clock faces, with different looks, fonts and color options to choose from.</p><p>The code also mentions five separate layouts for the Duo's StandBy mode, including StandBy, Stacked, Top, Middle and Bottom. Pdfu speculates that the last four are intended for the foldable screen, while StandBy sounds just like the normal StandBy mode iPhones have had for a few years.</p><p>You can see all the leaked designs in greater detail by checking out <a href="https://x.com/itspdfu/status/2104567049963921785" target="_blank">pdfu's thread</a> on X. Meanwhile, let me know what your early impressions are of the iPhone Duo in the comments below.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><a href="https://www.tomsguide.com/phones/samsung-phones/5-ways-galaxy-s27-ultra-can-beat-the-iphone-18-pro-and-2-ways-apple-will-still-win">5 ways Galaxy S27 Ultra can beat the iPhone 18 Pro — and 2 ways Apple will still win</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-7-features-youre-giving-up-by-not-buying-the-iphone-18-pro-max">iPhone Duo: 7 features you’re giving up by not buying the iPhone 18 Pro Max</a></li><li><a href="https://www.tomsguide.com/phones/iphones/the-real-reason-why-iphone-duo-will-beat-all-android-foldable-phones">The real reason why iPhone Duo will beat all Android foldable phones</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 5 ways Galaxy S27 Ultra can beat the iPhone 18 Pro — and 2 ways Apple will still win ]]></title>
                                                                                                <dc:content><![CDATA[ <p>There are a lot of things to love about the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro and iPhone 18 Pro Max,</a> but they definitely are not perfect. There are things that Apple's latest flagships are missing, and that could give Samsung an advantage with the release of the <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s27-ultra-design-leaked-and-it-could-cause-the-most-intense-wave-of-criticism-in-galaxy-history">Galaxy S27 Ultra</a> next year. </p><p>Success over Apple isn't guaranteed, but with Galaxy S27 Ultra rumors arriving pretty regularly, we're getting a good idea of what the next Samsung flagship could offer. There could be some pretty big changes, including a brand new design that ditches the vertical camera array of the last several generations of Galaxy phones. </p><p>That's only scratching the surface. These 5 things in particular could help the Samsung Galaxy S27 Ultra beat the iPhone 18 Pro — but there are two ways Apple could stay on top.</p><h3 class="article-body__section" id="section-a-bigger-battery"><span>A bigger battery</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:3755px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="iGGyvv7a4hQPrn26YbFnid" name="Galaxy S26 Ultra 24 hours-11" alt="Samsung Galaxy S26 Ultra" src="https://cdn.mos.cms.futurecdn.net/iGGyvv7a4hQPrn26YbFnid-1920-80.jpg" mos="" align="middle" fullscreen="" width="3755" height="2112" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Samsung already proved that it has what it takes to boost battery capacity without affecting the design of the device — as we saw with the <a href="https://www.tomsguide.com/phones/samsung-phones/galaxy-z-fold-8-vs-fold-8-ultra-vs-flip-8-battery-tests-silicon-carbon-pays-off">Galaxy Z Fold 8 Ultra's 5,000 mAh silicon carbon battery</a>. Rumor has it that Samsung could utilize the same tech in the S27 Ultra, which makes total sense considering how long the Ultra models have been stuck with 5,000 mAh batteries</p><p>Regulator documents have already revealed that <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s27-ultra-leak-reveals-silicon-carbon-battery-leap-but-also-a-camera-downgrade">Samsung could add a 5,700 mAh battery to the phone</a>. That's a 14% increase over the<a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s26-ultra-review"> Galaxy S26 Ultra</a>, and while it's nowhere near as large as the 7,300 mAh <a href="https://www.tomsguide.com/phones/oneplus-phones/oneplus-15-review">OnePlus 15</a>, it's still a noticeable jump in available power. That should hopefully increase the overall battery life. That said, we won't know whether it will exceed the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-18-pro-battery-life-tested-the-results-are-surprising">iPhone 18 Pro Max's 18 hours and 27 minutes</a>. </p><p>That would require an extra two hours of battery life on Samsung's part, so it better get to work on the efficiency side of things.</p><h3 class="article-body__section" id="section-an-improved-privacy-display"><span>An improved privacy display</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="f7xgeogiw6KvPnUbLtRM34" name="Galaxy S26 Ultra privacy screen LIST (1)" alt="Samsung Galaxy S26 Ultra front view and profile" src="https://cdn.mos.cms.futurecdn.net/f7xgeogiw6KvPnUbLtRM34-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s26-ultra-has-the-worlds-first-privacy-display-heres-how-it-works">Privacy Display</a> is the S26 Ultra's stand-out feature, but it wasn't perfect, and what we really want to see are some improvements to the technology. We'd hope that means brighter overall displays, even when Privacy Display is turned off, and more versatile use of the dimmed sections of the screen.</p><p>The latter may be coming true, with leaker <a href="https://x.com/UniverseIce/status/2103074330351751491?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E2103074330351751491%7Ctwgr%5E25a2a2ada5c14def33c245f770f969839de48b85%7Ctwcon%5Es1_&ref_url=https%3A%2F%2Fwww.androidauthority.com%2Fsamsung-galaxy-s27-ultra-split-screen-privacy-display-3715094%2F">Ice Universe</a> claiming that Samsung will adopt a feature that Xiaomi included on the newly-released 18 Pro — a split-screen privacy display. This feature would work in tandem with the S27 Ultra's multitasking, and would expand or contract according to how big the different windows are. The other window is fully lit and visible.</p><h3 class="article-body__section" id="section-s-pen"><span>S Pen</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="UfraPifaz2CpXLbJKJYqDY" name="S Pen S26 Ultra" alt="Samsung Galaxy S26 Ultra S Pen" src="https://cdn.mos.cms.futurecdn.net/UfraPifaz2CpXLbJKJYqDY-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>While the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo </a>is set to <a href="https://www.tomsguide.com/phones/iphones/steve-jobs-said-there-would-never-be-an-iphone-stylus-but-iphone-duo-just-proved-him-wrong-and-itll-be-a-better-device-for-it">get Apple Pencil support,</a> the iPhone 18 Pro does not. The Samsung Galaxy S27 Ultra is <a href="https://www.etnews.com/20260320000126" target="_blank">likely to stick</a> with the same level of S Pen support Samsung has offered for the past several years.</p><p>We're not expecting any major changes with the S27 Ultra's S Pen. This means you shouldn't expect to see the <a href="https://www.tomsguide.com/phones/samsung-phones/galaxy-s25-ultra-confusion-samsung-now-says-you-can-buy-bluetooth-s-pen-separately">return of Bluetooth or other more advanced functionality</a> we have seen in previous years. But even the simplest S Pen around is something that Apple doesn't offer on its flagship. So if you like to use a stylus to draw, take notes or make fine photo edits, the S27 Ultra is a more appealing device.</p><h3 class="article-body__section" id="section-better-camera-hardware"><span>Better camera hardware</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:2715px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="vbGrCLaZGfUvCojyg8YYUd" name="Galaxy S26 Ultra 24 hours-12" alt="Samsung Galaxy S26 Ultra" src="https://cdn.mos.cms.futurecdn.net/vbGrCLaZGfUvCojyg8YYUd-1920-80.jpg" mos="" align="middle" fullscreen="" width="2715" height="1527" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Ultra-tier Galaxy phones already have superior camera hardware, thanks to the 200MP main sensor, but things could be getting even better with the S27 Ultra — in the front and back of the phone. </p><p>The first upgrade rumor is the addition of<a href="https://www.galaxyclub.nl/samsung/galaxy-s27/"> a 16MP selfie camera</a>, which would be a notable upgrade from the 12MP shooter on the S26 Ultra. While that's still a little bit less than the 18MP Center Stage camera on iPhone 18 Pro, it's still a welcome upgrade. However, Samsung could jump ahead with rumors of a large sensor on the telephoto lens.</p><p>Some rumors suggest that Samsung <a href="https://go.skimresources.com/?id=803X112721&xs=1&url=https://x.com/phonefuturist/status/2094046496362483863&xcust=4-0-3238643-1-0-0-0-0&sref=https://www.techadvisor.com/article/3238643/galaxy-s27-ultra-the-camera-upgrade-debate-rolls-on.html" target="_blank">could offer a larger</a> 1/1.9-inch telephoto sensor, but as a result reduce the amount of optical zoom from 5x magnification to 4x. However, this has been disputed by <a href="https://go.skimresources.com/?id=803X112721&xs=1&url=https://x.com/UniverseIce/status/2099327785814945972&xcust=4-0-3238643-1-0-0-0-0&sref=https://www.techadvisor.com/article/3238643/galaxy-s27-ultra-the-camera-upgrade-debate-rolls-on.html" target="_blank">some leakers,</a> who claim Samsung is sticking with the same 5x 1/2.52-inch sensor as the S26 Ultra. But either way, it's a telephoto lens offering higher resolution and sensor size than the 48MP 1/2.55-inch sensor on iPhone 18 Pro Max.</p><h3 class="article-body__section" id="section-a-16gb-ram-option"><span>A 16GB RAM option</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:1704px;"><p class="vanilla-image-block" style="padding-top:54.17%;"><img id="U2CzUvPvEThFgKxQen6pD7" name="HHEajh5bAAAyh0z" alt="Samsung Galaxy S27 Ultra concept" src="https://cdn.mos.cms.futurecdn.net/U2CzUvPvEThFgKxQen6pD7-1920-80.jpg" mos="" align="middle" fullscreen="" width="1704" height="923" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Ice Universe)</span></figcaption></figure><p>While it's unlikely that we'll see the S27 Ultra get a full 16GB of RAM in its cheapest form, there's still a good chance the pricier 1TB models will get that memory boost. This should in turn give those models a slight advantage when it comes to processing, specifically where on-device AI is concerned.</p><p>Considering on-device AI is a big focus for Apple, the 12GB of RAM in the iPhone 18 Pro doesn't seem quite so impressive. The S27 Ultra, with more advanced Galaxy AI and computing hardware, could end up leaving the iPhone 18 Pro in the dust here.</p><h2 id="2-ways-apple-can-still-win">2 ways Apple can still win</h2><h3 class="article-body__section" id="section-performance-power"><span>Performance power</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="473VNvCMPfhDkYKpe3aJjK" name="iPhone 18 Pro and Pro Max-12" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/473VNvCMPfhDkYKpe3aJjK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>We can't say for certain how powerful the Galaxy S27 Ultra will be, but we have tested the chip that should power the phone when it arrives next year — the Snapdragon 8 Elite Extreme Gen 6. <a href="https://www.tomsguide.com/phones/android-phones/snapdragon-8-elite-gen-6-benchmark-test-results-hands-on-vs-a20-pro-iphone-18-pro">We have done some benchmarking tests with a Qualcomm Reference Device</a>, which gives us an idea of how the chip should perform. As powerful as it is, it doesn't really compare to Apple's A20 Pro in a lot of areas.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>Geekbench 7 (single core)</strong></p></td><td  ><p><strong>Geekbench 7 (multi-core)</strong></p></td><td  ><p><strong>3DMark Solar Bay Extreme</strong></p></td><td  ><p><strong>3DMark Wildlife Extreme</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Snapdragon 8 Elite Extreme Gen 6 (QRD)</strong></p></td><td  ><p>4161</p></td><td  ><p>12464</p></td><td  ><p>2262</p></td><td  ><p>9941</p></td></tr><tr><td class="firstcol " ><p><strong>Snapdragon 8 Elite Gen 5 (Samsung Galaxy Z Fold 8 Ultra)</strong></p></td><td  ><p>3110</p></td><td  ><p>10578</p></td><td  ><p>1372</p></td><td  ><p>6632</p></td></tr><tr><td class="firstcol " ><p><strong>A20 Pro (iPhone 18 Pro Max)</strong></p></td><td  ><p>4741</p></td><td  ><p>12789</p></td><td  ><p>2904</p></td><td  ><p>8344</p></td></tr></tbody></table></div><p>As you can see, the A20 Pro pulls ahead in most areas, including single- and multi-core benchmarking tests, and 3DMark's Solar Bay Extreme graphics test. The figures are close in a lot of places, but the only time the Gen 6 chip outpaces Apple is with the 3DMark Wildlife Extreme graphics test.</p><p>We don't know how Qualcomm's chip will perform on the S27 Ultra, especially if Samsung gets another custom "for Galaxy" chipset, but for now it seems like Apple certainly has the upper hand.</p><h3 class="article-body__section" id="section-more-storage"><span>More storage</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="5kKUCv7Eef6yGkMMGEgbvJ" name="iPhone 18 Pro and Pro Max-9" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/5kKUCv7Eef6yGkMMGEgbvJ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>As small a difference as it may be, we know that Apple currently offers more storage space than Samsung — offering a maximum storage space of 2TB to Samsung's 1TB. There's always the possibility that this could change, but the rumors suggest otherwise. In fact, the S27 series will apparently have the exact same storage options as the S26 series. This means the Ultra will max out at 1TB.</p><p>Those larger storage variants might get<a href="https://blog.naver.com/yeux1122/224419648243"> LPDDR6 RAM and UFS 5.1 storage</a>, which would be a benefit for performance and loading speed. Sadly, your maximum limit will be the same 1TB as always, if these rumors are to be believed.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><a href="https://www.tomsguide.com/phones/the-new-iphone-feature-in-ios-27-im-using-every-single-day-and-where-to-find-it">There's a new shortcut in iOS 27 I’m using every single day — here's where to find it</a></li><li><a href="https://www.tomsguide.com/phones/iphones/apple-confirms-iphone-18-pro-face-id-freezing-bug-what-you-need-to-know">Apple confirms iPhone 18 Pro Face ID freezing bug — what you need to know</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-7-features-youre-giving-up-by-not-buying-the-iphone-18-pro-max">iPhone Duo: 7 features you’re giving up by not buying the iPhone 18 Pro Max</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/samsung-phones/5-ways-galaxy-s27-ultra-can-beat-the-iphone-18-pro-and-2-ways-apple-will-still-win</link>
                                                                            <description>
                            <![CDATA[ iPhone 18 Pro is good, but the Galaxy S27 Ultra could beat it in these key ways. Luckily Samsung can't do everything. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">aurwygfVY2c7C4dFHdAFGf</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/LacgYzjqWKVkFAs6DKZ3ak-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 29 Sep 2026 07:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Samsung Phones]]></category>
                                                    <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                    <category><![CDATA[Android Phones]]></category>
                                                                                                <author><![CDATA[ tom.pritchard@futurenet.com (Tom Pritchard) ]]></author>                    <dc:creator><![CDATA[ Tom Pritchard ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/biCewUkKfSA6QnT2HxVc3f-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/LacgYzjqWKVkFAs6DKZ3ak-1920-80.jpg">
                                                            <media:credit><![CDATA[@TechHome100]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Samsung Galaxy S27 Ultra render]]></media:description>                                                            <media:text><![CDATA[Samsung Galaxy S27 Ultra render]]></media:text>
                                <media:title type="plain"><![CDATA[Samsung Galaxy S27 Ultra render]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/LacgYzjqWKVkFAs6DKZ3ak-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>There are a lot of things to love about the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro and iPhone 18 Pro Max,</a> but they definitely are not perfect. There are things that Apple's latest flagships are missing, and that could give Samsung an advantage with the release of the <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s27-ultra-design-leaked-and-it-could-cause-the-most-intense-wave-of-criticism-in-galaxy-history">Galaxy S27 Ultra</a> next year. </p><p>Success over Apple isn't guaranteed, but with Galaxy S27 Ultra rumors arriving pretty regularly, we're getting a good idea of what the next Samsung flagship could offer. There could be some pretty big changes, including a brand new design that ditches the vertical camera array of the last several generations of Galaxy phones. </p><p>That's only scratching the surface. These 5 things in particular could help the Samsung Galaxy S27 Ultra beat the iPhone 18 Pro — but there are two ways Apple could stay on top.</p><h3 class="article-body__section" id="section-a-bigger-battery"><span>A bigger battery</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:3755px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="iGGyvv7a4hQPrn26YbFnid" name="Galaxy S26 Ultra 24 hours-11" alt="Samsung Galaxy S26 Ultra" src="https://cdn.mos.cms.futurecdn.net/iGGyvv7a4hQPrn26YbFnid-1920-80.jpg" mos="" align="middle" fullscreen="" width="3755" height="2112" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Samsung already proved that it has what it takes to boost battery capacity without affecting the design of the device — as we saw with the <a href="https://www.tomsguide.com/phones/samsung-phones/galaxy-z-fold-8-vs-fold-8-ultra-vs-flip-8-battery-tests-silicon-carbon-pays-off">Galaxy Z Fold 8 Ultra's 5,000 mAh silicon carbon battery</a>. Rumor has it that Samsung could utilize the same tech in the S27 Ultra, which makes total sense considering how long the Ultra models have been stuck with 5,000 mAh batteries</p><p>Regulator documents have already revealed that <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s27-ultra-leak-reveals-silicon-carbon-battery-leap-but-also-a-camera-downgrade">Samsung could add a 5,700 mAh battery to the phone</a>. That's a 14% increase over the<a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s26-ultra-review"> Galaxy S26 Ultra</a>, and while it's nowhere near as large as the 7,300 mAh <a href="https://www.tomsguide.com/phones/oneplus-phones/oneplus-15-review">OnePlus 15</a>, it's still a noticeable jump in available power. That should hopefully increase the overall battery life. That said, we won't know whether it will exceed the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-18-pro-battery-life-tested-the-results-are-surprising">iPhone 18 Pro Max's 18 hours and 27 minutes</a>. </p><p>That would require an extra two hours of battery life on Samsung's part, so it better get to work on the efficiency side of things.</p><h3 class="article-body__section" id="section-an-improved-privacy-display"><span>An improved privacy display</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="f7xgeogiw6KvPnUbLtRM34" name="Galaxy S26 Ultra privacy screen LIST (1)" alt="Samsung Galaxy S26 Ultra front view and profile" src="https://cdn.mos.cms.futurecdn.net/f7xgeogiw6KvPnUbLtRM34-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s26-ultra-has-the-worlds-first-privacy-display-heres-how-it-works">Privacy Display</a> is the S26 Ultra's stand-out feature, but it wasn't perfect, and what we really want to see are some improvements to the technology. We'd hope that means brighter overall displays, even when Privacy Display is turned off, and more versatile use of the dimmed sections of the screen.</p><p>The latter may be coming true, with leaker <a href="https://x.com/UniverseIce/status/2103074330351751491?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E2103074330351751491%7Ctwgr%5E25a2a2ada5c14def33c245f770f969839de48b85%7Ctwcon%5Es1_&ref_url=https%3A%2F%2Fwww.androidauthority.com%2Fsamsung-galaxy-s27-ultra-split-screen-privacy-display-3715094%2F">Ice Universe</a> claiming that Samsung will adopt a feature that Xiaomi included on the newly-released 18 Pro — a split-screen privacy display. This feature would work in tandem with the S27 Ultra's multitasking, and would expand or contract according to how big the different windows are. The other window is fully lit and visible.</p><h3 class="article-body__section" id="section-s-pen"><span>S Pen</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="UfraPifaz2CpXLbJKJYqDY" name="S Pen S26 Ultra" alt="Samsung Galaxy S26 Ultra S Pen" src="https://cdn.mos.cms.futurecdn.net/UfraPifaz2CpXLbJKJYqDY-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>While the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo </a>is set to <a href="https://www.tomsguide.com/phones/iphones/steve-jobs-said-there-would-never-be-an-iphone-stylus-but-iphone-duo-just-proved-him-wrong-and-itll-be-a-better-device-for-it">get Apple Pencil support,</a> the iPhone 18 Pro does not. The Samsung Galaxy S27 Ultra is <a href="https://www.etnews.com/20260320000126" target="_blank">likely to stick</a> with the same level of S Pen support Samsung has offered for the past several years.</p><p>We're not expecting any major changes with the S27 Ultra's S Pen. This means you shouldn't expect to see the <a href="https://www.tomsguide.com/phones/samsung-phones/galaxy-s25-ultra-confusion-samsung-now-says-you-can-buy-bluetooth-s-pen-separately">return of Bluetooth or other more advanced functionality</a> we have seen in previous years. But even the simplest S Pen around is something that Apple doesn't offer on its flagship. So if you like to use a stylus to draw, take notes or make fine photo edits, the S27 Ultra is a more appealing device.</p><h3 class="article-body__section" id="section-better-camera-hardware"><span>Better camera hardware</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:2715px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="vbGrCLaZGfUvCojyg8YYUd" name="Galaxy S26 Ultra 24 hours-12" alt="Samsung Galaxy S26 Ultra" src="https://cdn.mos.cms.futurecdn.net/vbGrCLaZGfUvCojyg8YYUd-1920-80.jpg" mos="" align="middle" fullscreen="" width="2715" height="1527" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Ultra-tier Galaxy phones already have superior camera hardware, thanks to the 200MP main sensor, but things could be getting even better with the S27 Ultra — in the front and back of the phone. </p><p>The first upgrade rumor is the addition of<a href="https://www.galaxyclub.nl/samsung/galaxy-s27/"> a 16MP selfie camera</a>, which would be a notable upgrade from the 12MP shooter on the S26 Ultra. While that's still a little bit less than the 18MP Center Stage camera on iPhone 18 Pro, it's still a welcome upgrade. However, Samsung could jump ahead with rumors of a large sensor on the telephoto lens.</p><p>Some rumors suggest that Samsung <a href="https://go.skimresources.com/?id=803X112721&xs=1&url=https://x.com/phonefuturist/status/2094046496362483863&xcust=4-0-3238643-1-0-0-0-0&sref=https://www.techadvisor.com/article/3238643/galaxy-s27-ultra-the-camera-upgrade-debate-rolls-on.html" target="_blank">could offer a larger</a> 1/1.9-inch telephoto sensor, but as a result reduce the amount of optical zoom from 5x magnification to 4x. However, this has been disputed by <a href="https://go.skimresources.com/?id=803X112721&xs=1&url=https://x.com/UniverseIce/status/2099327785814945972&xcust=4-0-3238643-1-0-0-0-0&sref=https://www.techadvisor.com/article/3238643/galaxy-s27-ultra-the-camera-upgrade-debate-rolls-on.html" target="_blank">some leakers,</a> who claim Samsung is sticking with the same 5x 1/2.52-inch sensor as the S26 Ultra. But either way, it's a telephoto lens offering higher resolution and sensor size than the 48MP 1/2.55-inch sensor on iPhone 18 Pro Max.</p><h3 class="article-body__section" id="section-a-16gb-ram-option"><span>A 16GB RAM option</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:1704px;"><p class="vanilla-image-block" style="padding-top:54.17%;"><img id="U2CzUvPvEThFgKxQen6pD7" name="HHEajh5bAAAyh0z" alt="Samsung Galaxy S27 Ultra concept" src="https://cdn.mos.cms.futurecdn.net/U2CzUvPvEThFgKxQen6pD7-1920-80.jpg" mos="" align="middle" fullscreen="" width="1704" height="923" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Ice Universe)</span></figcaption></figure><p>While it's unlikely that we'll see the S27 Ultra get a full 16GB of RAM in its cheapest form, there's still a good chance the pricier 1TB models will get that memory boost. This should in turn give those models a slight advantage when it comes to processing, specifically where on-device AI is concerned.</p><p>Considering on-device AI is a big focus for Apple, the 12GB of RAM in the iPhone 18 Pro doesn't seem quite so impressive. The S27 Ultra, with more advanced Galaxy AI and computing hardware, could end up leaving the iPhone 18 Pro in the dust here.</p><h2 id="2-ways-apple-can-still-win">2 ways Apple can still win</h2><h3 class="article-body__section" id="section-performance-power"><span>Performance power</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="473VNvCMPfhDkYKpe3aJjK" name="iPhone 18 Pro and Pro Max-12" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/473VNvCMPfhDkYKpe3aJjK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>We can't say for certain how powerful the Galaxy S27 Ultra will be, but we have tested the chip that should power the phone when it arrives next year — the Snapdragon 8 Elite Extreme Gen 6. <a href="https://www.tomsguide.com/phones/android-phones/snapdragon-8-elite-gen-6-benchmark-test-results-hands-on-vs-a20-pro-iphone-18-pro">We have done some benchmarking tests with a Qualcomm Reference Device</a>, which gives us an idea of how the chip should perform. As powerful as it is, it doesn't really compare to Apple's A20 Pro in a lot of areas.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>Geekbench 7 (single core)</strong></p></td><td  ><p><strong>Geekbench 7 (multi-core)</strong></p></td><td  ><p><strong>3DMark Solar Bay Extreme</strong></p></td><td  ><p><strong>3DMark Wildlife Extreme</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Snapdragon 8 Elite Extreme Gen 6 (QRD)</strong></p></td><td  ><p>4161</p></td><td  ><p>12464</p></td><td  ><p>2262</p></td><td  ><p>9941</p></td></tr><tr><td class="firstcol " ><p><strong>Snapdragon 8 Elite Gen 5 (Samsung Galaxy Z Fold 8 Ultra)</strong></p></td><td  ><p>3110</p></td><td  ><p>10578</p></td><td  ><p>1372</p></td><td  ><p>6632</p></td></tr><tr><td class="firstcol " ><p><strong>A20 Pro (iPhone 18 Pro Max)</strong></p></td><td  ><p>4741</p></td><td  ><p>12789</p></td><td  ><p>2904</p></td><td  ><p>8344</p></td></tr></tbody></table></div><p>As you can see, the A20 Pro pulls ahead in most areas, including single- and multi-core benchmarking tests, and 3DMark's Solar Bay Extreme graphics test. The figures are close in a lot of places, but the only time the Gen 6 chip outpaces Apple is with the 3DMark Wildlife Extreme graphics test.</p><p>We don't know how Qualcomm's chip will perform on the S27 Ultra, especially if Samsung gets another custom "for Galaxy" chipset, but for now it seems like Apple certainly has the upper hand.</p><h3 class="article-body__section" id="section-more-storage"><span>More storage</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="5kKUCv7Eef6yGkMMGEgbvJ" name="iPhone 18 Pro and Pro Max-9" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/5kKUCv7Eef6yGkMMGEgbvJ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>As small a difference as it may be, we know that Apple currently offers more storage space than Samsung — offering a maximum storage space of 2TB to Samsung's 1TB. There's always the possibility that this could change, but the rumors suggest otherwise. In fact, the S27 series will apparently have the exact same storage options as the S26 series. This means the Ultra will max out at 1TB.</p><p>Those larger storage variants might get<a href="https://blog.naver.com/yeux1122/224419648243"> LPDDR6 RAM and UFS 5.1 storage</a>, which would be a benefit for performance and loading speed. Sadly, your maximum limit will be the same 1TB as always, if these rumors are to be believed.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><a href="https://www.tomsguide.com/phones/the-new-iphone-feature-in-ios-27-im-using-every-single-day-and-where-to-find-it">There's a new shortcut in iOS 27 I’m using every single day — here's where to find it</a></li><li><a href="https://www.tomsguide.com/phones/iphones/apple-confirms-iphone-18-pro-face-id-freezing-bug-what-you-need-to-know">Apple confirms iPhone 18 Pro Face ID freezing bug — what you need to know</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-7-features-youre-giving-up-by-not-buying-the-iphone-18-pro-max">iPhone Duo: 7 features you’re giving up by not buying the iPhone 18 Pro Max</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ iPhone Duo — the real reason why Apple will beat all Android foldables ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Did you hear about the new <a href="https://www.mi.com/global/discover/article?id=6357"><u>Xiaomi 18 Fold</u></a>? Maybe not, but this foldable phone is getting a lot of attention on YouTube for “beating” the upcoming <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice"><u>iPhone Duo</u></a> at its own game. Here’s just some of the ways it wins.</p><ul><li>It’s lighter</li><li>It’s thinner</li><li>It has a telephoto camera</li><li>It has a bigger battery</li><li>It charges faster</li><li>It’s better at multitasking</li><li>It has a brighter screen</li><li>It’s hundreds cheaper</li></ul><p>As you’ll see in the very slick video by<a href="https://www.youtube.com/@Mrwhosetheboss"> <u>Mrwhosetheboss</u></a>, which at last count has over 16 million views, Xiaomi has superior hardware. On paper. But when he digs deeper a bunch of flaws emerge in this would be iPhone Duo killer.</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/eYBEJBfq_Zs" allowfullscreen></iframe></div></div><p>For starters, the phone is made of less durable aluminum, versus the stronger titanium frame on the iPhone Duo. And that durability advantage extends to the Duo’s IP68 rating for water and dust protection, which the Xiaomi lacks.</p><p>In addition, the crease is more noticeable on the Xiaomi 18 Fold because it lacks the Duo’s nano-texture display. Even worse, Mrwhosetheboss found that just opening and closing the Xiaomi foldable resulted in unsettling clicking sounds.</p><p>But the real reason the iPhone Duo is superior is the software experience, specifically how Apple optimized its OS and apps for the foldable form factor. It looks like Xiaomi just threw its regular OS at a foldable, with sometimes awkward and ugly results.</p><p>This is the same reason why the iPhone Duo will likely beat all other Android foldables once it’s released: no other company focuses as obsessively on how the hardware and software work together.</p><h2 id="hardware-software-innovation">Hardware + Software innovation</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:4656px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Q9CmG4bSftigAEdPtH3Qqd" name="iPhone Duo-LIST1" alt="iPhone Duo hands on" src="https://cdn.mos.cms.futurecdn.net/Q9CmG4bSftigAEdPtH3Qqd-1920-80.jpg" mos="" align="middle" fullscreen="" width="4656" height="2619" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>For example, Apple redesigned the dock on the iPhone so it sits on the right side, making it easier to reach both when the display is closed and open. The same thing goes with the controls for apps.</p><p>This is admittedly a bummer for left-handed people, but it is a good use of the available space and wider aspect ratio, so you can see more of your content.</p><div class="looped-video"><video class="lazyload-in-view lazyloading" data-src="https://cdn.mos.cms.futurecdn.net/53Tjqd2ZGw3r4mghxSwHMC/Apple-iPhone-Duo-StandBy-260909.mp4" autoplay loop muted playsinline src="https://cdn.mos.cms.futurecdn.net/53Tjqd2ZGw3r4mghxSwHMC/Apple-iPhone-Duo-StandBy-260909.mp4"></video></div><p>In addition, Apple has optimized the software so that apps can adapt based on the “pose” the device is in. For example, when you turn the iPhone Duo upside down in tent mode, it can automatically morph into an alarm clock. And it emits a soft glow when your alarm goes off.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2820px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="aCP29PwqKVRBqd3bbipckc" name="Apple iPhone Duo" alt="iPhone Duo shown half open" src="https://cdn.mos.cms.futurecdn.net/aCP29PwqKVRBqd3bbipckc-1920-80.jpg" mos="" align="middle" fullscreen="" width="2820" height="1586" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>Apple has also redesigned <a href="https://www.tomsguide.com/phones/iphones/ios-27-7-features-you-need-to-try-first-after-updating"><u>iOS 27</u></a> so that the iPhone Duo reacts as you fold the device. If you fold the phone half way while in Safari, for example, a keyboard will automatically appear at the bottom of the display. And when it’s stood up vertically, you can display your calendar on the left and favorite photos on the right, just like one of the best digital photo frames.</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/y227RF0smAg" allowfullscreen></iframe></div></div><p>Apple is making an API available for developers as well to enable them to make apps that can “read” the angle of the hinge, and in an interview with <a href="https://www.youtube.com/watch?v=y227RF0smAg"><u>Donald Decodes on YouTube</u></a> Apple’s Craig Federighi confirmed it’s accurate to within 5 degrees. But he said that most developers will simply be focusing on various pose states for the device, like the book pose, table pose or tent pose. </p><p>“We make those things so that as a developer you’re not having to operate on how many degrees [it’s] open,” said Federighi. “We can deliver a really standard and consistent experience across apps.”</p><p>Meanwhile, Samsung abandoned its similar Flex mode for the <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-review-wide-for-the-win"><u>Galaxy Z Fold 8</u></a>, reserving this feature only for the <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-ultra-review"><u>Fold 8 Ultra</u></a>.</p><p>“There are choices that Samsung previously tried that Apple is revisiting, including hinges that open at different angles and under-display selfie cameras,” said Avi Greengart, founder and lead analyst at Techsponential. “The different hinge postures are well-supported in iOS27 with interface elements and are a clear win for Apple.”</p><h2 id="a-seamless-transition-but-what-about-multitasking">A seamless transition, but what about multitasking?</h2><div class="looped-video"><video class="lazyload-in-view lazyloading" data-src="https://cdn.mos.cms.futurecdn.net/aqxFE2U2HAYdiGKe3CtHtP/Apple-iPhone-Duo-multitasking-260909.mp4" autoplay loop muted playsinline src="https://cdn.mos.cms.futurecdn.net/aqxFE2U2HAYdiGKe3CtHtP/Apple-iPhone-Duo-multitasking-260909.mp4"></video></div><p>Apple has taken a lot of heat for how much buzz the transition animation has gotten that takes you from the inner to the outer display. But it does make the device feel magical.</p><p>And if this effect was just eye candy, then you wouldn’t have developers racing to copy the effect within the first day. </p><p>To be fair, the iPhone Duo is limited when it comes to multitasking. You can only run two apps side by side, whereas the Galaxy Z Fold 8 lets you run three apps at once, plus put floating windows on top. The Xiaomi 18 Fold lets you run up to eight apps.</p><p>So it remains to be seen if the Duo is versatile enough in this category.</p><p>However, I do give Apple credit for how it enabled Split View. The two sides feel like independent desktops or workspaces. It feels natural when you’re using it.</p><h2 id="the-iphone-duo-app-difference">The iPhone Duo app difference</h2><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="vHxTDrc3YV6DT2rVpf9Sp8" name="Apple-iPhone-Duo-Slack" alt="iPhone Duo apps" src="https://cdn.mos.cms.futurecdn.net/vHxTDrc3YV6DT2rVpf9Sp8-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">Slack on the iPhone Duo </span><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>Apple hasn’t shared much in the way of third-party applications yet, but what I’ve seen so far looks promising.</p><p>On Slack, for example, you’ll see your rooms and contacts on the left and messages on the right. The last time I checked, Slack was just a stretched out phone app on Android foldables with a ton of wasted space. And Zoom lets you easily see the content being shared and other call participants down below.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="KRgUvBrWECLXj3TF4YNro8" name="Apple-iPhone-Duo-Zoom" alt="iPhone Duo apps" src="https://cdn.mos.cms.futurecdn.net/KRgUvBrWECLXj3TF4YNro8-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">Zoom on the iPhone Duo </span><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>Apple's software experience is extremely polished on the Duo, but Android works fine on foldables,” Greengart said. “The real test will be whether Apple can get developers to update their apps so that the entire experience is fluid and optimized; that's the area where Android falls short.”</p><div class="see-more see-more--clipped"><figure><blockquote class="twitter-tweet hawk-ignore" data-lang="en" cite="https://twitter.com/cantworkitout/status/2104103592726765722"><p lang="en" dir="ltr">Duo-Man offers the complete walkman experience on the iPhone Duo. Open the Duo to pick and 'insert' the cassette, Close the Duo to start listening.Yes, I actually recorded the button clicks and static noise from a real Walkman!It was fun making this at @bitrig hacks today. pic.twitter.com/juSrLhofrH<a href="https://twitter.com/cantworkitout/status/2104103592726765722">September 27, 2026</a></p></blockquote></figure><div class="see-more__filter"></div></div><p>There's already one independent developer showing off an app for the iPhone Duo that's creating some buzz. Vidit Bhargava has revealed the very retro Duo Man app, which mimics the Sony Walkman experience on the foldable. You open the Duo to pick your music and "insert" the cassette, then close the Duo to start listening.</p><p>I also think it’s telling that Netflix has an iPhone Duo-optimized app on day one for this device, while it refused to make one for the Vision Pro at first. Yes, $2,000 is expensive for a phone, but I don’t think Netflix would have bothered with a Duo app unless it believed this device was going to take off.</p><h2 id="where-android-foldables-still-win">Where Android foldables still win</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="F6qr2SDN3gLqxsmgpqVYsY" name="Fold 8 back 2" alt="Samsung Galaxy Z Fold 8" src="https://cdn.mos.cms.futurecdn.net/F6qr2SDN3gLqxsmgpqVYsY-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>As someone who reviewed the Galaxy Z Fold 8, I really like how thin and light the design is. It's nearly a 2-ounce difference, with the Fold 8 weighing 7.09 ounces, compared to 8.96 ounces for the Duo.</p><p>It makes the iPhone Duo seem bulky by comparison when you hold them both as I did. But there's a benefit to this additional heft.</p><p>"The iPhone Duo is thicker and noticeably heavier than Samsung's Galaxy Z Fold8," Greengart said. That's both a disadvantage and a specific choice: the iPhone Duo is more water and dust resistant compared to most Android foldables.</p><p>It's true that the Fold 8 and Fold 8 Ultra both lack an IP68 rating for water and dust resistance, but the <a href="https://www.tomsguide.com/phones/motorola-phones/motorola-razr-fold-review">Motorola Razr Fold</a> and <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-fold-review">Google Pixel 11 Pro Fold</a> both offer it. </p><p>In addition, the Fold 8 has some really cool software tricks I don't think the iPhone Duo will offer, such as suggesting apps that can open in mult-window mode on the fly. </p><h2 id="bottom-line-2">Bottom line</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:5439px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="DrnkS3FeWHhXivG9osdVqd" name="iPhone Duo-4" alt="iPhone Duo hands on" src="https://cdn.mos.cms.futurecdn.net/DrnkS3FeWHhXivG9osdVqd-1920-80.jpg" mos="" align="middle" fullscreen="" width="5439" height="3059" attribution="" endorsement="" class="inline"></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 clear that the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-trade-offs"><u>iPhone Duo has some drawbacks</u></a>, especially for its $2,000 price. It’s heavier and thicker than other foldable phones, and you don’t get iPhone 18 Pro features like a telephoto zoom. </p><p>But the real reason that this device will put other foldable phones on notice is how the hardware and software work together. And I think that will spur more innovation on the Android side, which is good for everyone.</p> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/the-real-reason-why-iphone-duo-will-beat-all-android-foldable-phones</link>
                                                                            <description>
                            <![CDATA[ The iPhone Duo may lose on certain specs versus Android foldables, but it will likely win on software and apps. And that’s what really counts. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">oKJdDQ8avfFYaZyphpB2bH</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/6RbxqgBQeRcLXmzyc9Sx6d-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 29 Sep 2026 04:30:00 +0000</pubDate>                                                                                                                                <updated>Tue, 29 Sep 2026 19:41:28 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                                    <dc:creator><![CDATA[ Mark Spoonauer ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/wtAspSzVfcKLB4JEd39AMo-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Mark Spoonauer is the global editor in chief of Tom&#039;s Guide and has covered technology for over 20 years. He oversees the direction of Tom&#039;s Guide and leads a team of over 25 journalists to bring you our expert buying guides, reviews, news, how-to articles, deals and other coverage.&lt;/p&gt;&lt;p&gt;Mark has a passion for covering all things mobile, having reviewed dozens of smartphones and other gadgets. He enjoys testing the top mobile devices and putting them up against each other in our in-depth face-offs. He also works hand in hand with our editors and testing team to continually improve how we evaluate products. &lt;/p&gt;&lt;p&gt;Having led Tom&#039;s Guide since 2013, Mark has focused on growing the core tech coverage of the site while also expanding into new areas, such as entertainment, fitness and home, recruiting talented writers and editors to help our readers figure out what to buy and how to get the most out of the products and services they use every day. &lt;/p&gt;&lt;p&gt;Mark has spoken at key industry events and appears regularly on TV to discuss the latest trends, including &lt;a href=&quot;https://cheddar.com/media/pixel-watch-gets-a-release-date-at-google-i-o-2022&quot;&gt;Cheddar&lt;/a&gt;, Fox 5, &lt;a href=&quot;https://www.foxbusiness.com/technology/apple-march-event-5g-iphone&quot;&gt;Fox Business&lt;/a&gt; and other outlets. Mark was previously editor in chief of Laptop Mag, and his work has appeared in Wired, Popular Science and Inc. Follow him on Twitter at @mspoonauer.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/6RbxqgBQeRcLXmzyc9Sx6d-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone Duo hands on]]></media:description>                                                            <media:text><![CDATA[iPhone Duo hands on]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone Duo hands on]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/6RbxqgBQeRcLXmzyc9Sx6d-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Did you hear about the new <a href="https://www.mi.com/global/discover/article?id=6357"><u>Xiaomi 18 Fold</u></a>? Maybe not, but this foldable phone is getting a lot of attention on YouTube for “beating” the upcoming <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice"><u>iPhone Duo</u></a> at its own game. Here’s just some of the ways it wins.</p><ul><li>It’s lighter</li><li>It’s thinner</li><li>It has a telephoto camera</li><li>It has a bigger battery</li><li>It charges faster</li><li>It’s better at multitasking</li><li>It has a brighter screen</li><li>It’s hundreds cheaper</li></ul><p>As you’ll see in the very slick video by<a href="https://www.youtube.com/@Mrwhosetheboss"> <u>Mrwhosetheboss</u></a>, which at last count has over 16 million views, Xiaomi has superior hardware. On paper. But when he digs deeper a bunch of flaws emerge in this would be iPhone Duo killer.</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/eYBEJBfq_Zs" allowfullscreen></iframe></div></div><p>For starters, the phone is made of less durable aluminum, versus the stronger titanium frame on the iPhone Duo. And that durability advantage extends to the Duo’s IP68 rating for water and dust protection, which the Xiaomi lacks.</p><p>In addition, the crease is more noticeable on the Xiaomi 18 Fold because it lacks the Duo’s nano-texture display. Even worse, Mrwhosetheboss found that just opening and closing the Xiaomi foldable resulted in unsettling clicking sounds.</p><p>But the real reason the iPhone Duo is superior is the software experience, specifically how Apple optimized its OS and apps for the foldable form factor. It looks like Xiaomi just threw its regular OS at a foldable, with sometimes awkward and ugly results.</p><p>This is the same reason why the iPhone Duo will likely beat all other Android foldables once it’s released: no other company focuses as obsessively on how the hardware and software work together.</p><h2 id="hardware-software-innovation">Hardware + Software innovation</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:4656px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Q9CmG4bSftigAEdPtH3Qqd" name="iPhone Duo-LIST1" alt="iPhone Duo hands on" src="https://cdn.mos.cms.futurecdn.net/Q9CmG4bSftigAEdPtH3Qqd-1920-80.jpg" mos="" align="middle" fullscreen="" width="4656" height="2619" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>For example, Apple redesigned the dock on the iPhone so it sits on the right side, making it easier to reach both when the display is closed and open. The same thing goes with the controls for apps.</p><p>This is admittedly a bummer for left-handed people, but it is a good use of the available space and wider aspect ratio, so you can see more of your content.</p><div class="looped-video"><video class="lazyload-in-view lazyloading" data-src="https://cdn.mos.cms.futurecdn.net/53Tjqd2ZGw3r4mghxSwHMC/Apple-iPhone-Duo-StandBy-260909.mp4" autoplay loop muted playsinline src="https://cdn.mos.cms.futurecdn.net/53Tjqd2ZGw3r4mghxSwHMC/Apple-iPhone-Duo-StandBy-260909.mp4"></video></div><p>In addition, Apple has optimized the software so that apps can adapt based on the “pose” the device is in. For example, when you turn the iPhone Duo upside down in tent mode, it can automatically morph into an alarm clock. And it emits a soft glow when your alarm goes off.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2820px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="aCP29PwqKVRBqd3bbipckc" name="Apple iPhone Duo" alt="iPhone Duo shown half open" src="https://cdn.mos.cms.futurecdn.net/aCP29PwqKVRBqd3bbipckc-1920-80.jpg" mos="" align="middle" fullscreen="" width="2820" height="1586" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>Apple has also redesigned <a href="https://www.tomsguide.com/phones/iphones/ios-27-7-features-you-need-to-try-first-after-updating"><u>iOS 27</u></a> so that the iPhone Duo reacts as you fold the device. If you fold the phone half way while in Safari, for example, a keyboard will automatically appear at the bottom of the display. And when it’s stood up vertically, you can display your calendar on the left and favorite photos on the right, just like one of the best digital photo frames.</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/y227RF0smAg" allowfullscreen></iframe></div></div><p>Apple is making an API available for developers as well to enable them to make apps that can “read” the angle of the hinge, and in an interview with <a href="https://www.youtube.com/watch?v=y227RF0smAg"><u>Donald Decodes on YouTube</u></a> Apple’s Craig Federighi confirmed it’s accurate to within 5 degrees. But he said that most developers will simply be focusing on various pose states for the device, like the book pose, table pose or tent pose. </p><p>“We make those things so that as a developer you’re not having to operate on how many degrees [it’s] open,” said Federighi. “We can deliver a really standard and consistent experience across apps.”</p><p>Meanwhile, Samsung abandoned its similar Flex mode for the <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-review-wide-for-the-win"><u>Galaxy Z Fold 8</u></a>, reserving this feature only for the <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-ultra-review"><u>Fold 8 Ultra</u></a>.</p><p>“There are choices that Samsung previously tried that Apple is revisiting, including hinges that open at different angles and under-display selfie cameras,” said Avi Greengart, founder and lead analyst at Techsponential. “The different hinge postures are well-supported in iOS27 with interface elements and are a clear win for Apple.”</p><h2 id="a-seamless-transition-but-what-about-multitasking">A seamless transition, but what about multitasking?</h2><div class="looped-video"><video class="lazyload-in-view lazyloading" data-src="https://cdn.mos.cms.futurecdn.net/aqxFE2U2HAYdiGKe3CtHtP/Apple-iPhone-Duo-multitasking-260909.mp4" autoplay loop muted playsinline src="https://cdn.mos.cms.futurecdn.net/aqxFE2U2HAYdiGKe3CtHtP/Apple-iPhone-Duo-multitasking-260909.mp4"></video></div><p>Apple has taken a lot of heat for how much buzz the transition animation has gotten that takes you from the inner to the outer display. But it does make the device feel magical.</p><p>And if this effect was just eye candy, then you wouldn’t have developers racing to copy the effect within the first day. </p><p>To be fair, the iPhone Duo is limited when it comes to multitasking. You can only run two apps side by side, whereas the Galaxy Z Fold 8 lets you run three apps at once, plus put floating windows on top. The Xiaomi 18 Fold lets you run up to eight apps.</p><p>So it remains to be seen if the Duo is versatile enough in this category.</p><p>However, I do give Apple credit for how it enabled Split View. The two sides feel like independent desktops or workspaces. It feels natural when you’re using it.</p><h2 id="the-iphone-duo-app-difference">The iPhone Duo app difference</h2><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="vHxTDrc3YV6DT2rVpf9Sp8" name="Apple-iPhone-Duo-Slack" alt="iPhone Duo apps" src="https://cdn.mos.cms.futurecdn.net/vHxTDrc3YV6DT2rVpf9Sp8-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">Slack on the iPhone Duo </span><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>Apple hasn’t shared much in the way of third-party applications yet, but what I’ve seen so far looks promising.</p><p>On Slack, for example, you’ll see your rooms and contacts on the left and messages on the right. The last time I checked, Slack was just a stretched out phone app on Android foldables with a ton of wasted space. And Zoom lets you easily see the content being shared and other call participants down below.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="KRgUvBrWECLXj3TF4YNro8" name="Apple-iPhone-Duo-Zoom" alt="iPhone Duo apps" src="https://cdn.mos.cms.futurecdn.net/KRgUvBrWECLXj3TF4YNro8-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">Zoom on the iPhone Duo </span><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>Apple's software experience is extremely polished on the Duo, but Android works fine on foldables,” Greengart said. “The real test will be whether Apple can get developers to update their apps so that the entire experience is fluid and optimized; that's the area where Android falls short.”</p><div class="see-more see-more--clipped"><figure><blockquote class="twitter-tweet hawk-ignore" data-lang="en" cite="https://twitter.com/cantworkitout/status/2104103592726765722"><p lang="en" dir="ltr">Duo-Man offers the complete walkman experience on the iPhone Duo. Open the Duo to pick and 'insert' the cassette, Close the Duo to start listening.Yes, I actually recorded the button clicks and static noise from a real Walkman!It was fun making this at @bitrig hacks today. pic.twitter.com/juSrLhofrH<a href="https://twitter.com/cantworkitout/status/2104103592726765722">September 27, 2026</a></p></blockquote></figure><div class="see-more__filter"></div></div><p>There's already one independent developer showing off an app for the iPhone Duo that's creating some buzz. Vidit Bhargava has revealed the very retro Duo Man app, which mimics the Sony Walkman experience on the foldable. You open the Duo to pick your music and "insert" the cassette, then close the Duo to start listening.</p><p>I also think it’s telling that Netflix has an iPhone Duo-optimized app on day one for this device, while it refused to make one for the Vision Pro at first. Yes, $2,000 is expensive for a phone, but I don’t think Netflix would have bothered with a Duo app unless it believed this device was going to take off.</p><h2 id="where-android-foldables-still-win">Where Android foldables still win</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="F6qr2SDN3gLqxsmgpqVYsY" name="Fold 8 back 2" alt="Samsung Galaxy Z Fold 8" src="https://cdn.mos.cms.futurecdn.net/F6qr2SDN3gLqxsmgpqVYsY-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>As someone who reviewed the Galaxy Z Fold 8, I really like how thin and light the design is. It's nearly a 2-ounce difference, with the Fold 8 weighing 7.09 ounces, compared to 8.96 ounces for the Duo.</p><p>It makes the iPhone Duo seem bulky by comparison when you hold them both as I did. But there's a benefit to this additional heft.</p><p>"The iPhone Duo is thicker and noticeably heavier than Samsung's Galaxy Z Fold8," Greengart said. That's both a disadvantage and a specific choice: the iPhone Duo is more water and dust resistant compared to most Android foldables.</p><p>It's true that the Fold 8 and Fold 8 Ultra both lack an IP68 rating for water and dust resistance, but the <a href="https://www.tomsguide.com/phones/motorola-phones/motorola-razr-fold-review">Motorola Razr Fold</a> and <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-fold-review">Google Pixel 11 Pro Fold</a> both offer it. </p><p>In addition, the Fold 8 has some really cool software tricks I don't think the iPhone Duo will offer, such as suggesting apps that can open in mult-window mode on the fly. </p><h2 id="bottom-line-2">Bottom line</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:5439px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="DrnkS3FeWHhXivG9osdVqd" name="iPhone Duo-4" alt="iPhone Duo hands on" src="https://cdn.mos.cms.futurecdn.net/DrnkS3FeWHhXivG9osdVqd-1920-80.jpg" mos="" align="middle" fullscreen="" width="5439" height="3059" attribution="" endorsement="" class="inline"></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 clear that the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-trade-offs"><u>iPhone Duo has some drawbacks</u></a>, especially for its $2,000 price. It’s heavier and thicker than other foldable phones, and you don’t get iPhone 18 Pro features like a telephoto zoom. </p><p>But the real reason that this device will put other foldable phones on notice is how the hardware and software work together. And I think that will spur more innovation on the Android side, which is good for everyone.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Apple confirms iPhone 18 Pro Face ID freezing bug — what you need to know. UPDATE: A fix is available ]]></title>
                                                                                                <dc:content><![CDATA[ <p><em><strong>Update: A fix is now available, keep reading to find out how to get it.</strong></em></p><p>The <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro and iPhone 18 Pro Max</a> are out in the wild now. The launch has been fairly smooth so far, with most people who really wanted the phone able to order one and receive it, though <a href="https://www.tomsguide.com/phones/iphones/warning-here-are-all-the-iphone-18-pro-shipping-delays-at-t-mobile-verizon-at-and-t-and-more">some models and colors were pushed back from the launch date due</a> to popularity. </p><p>But a new issue is emerging that is making iPhone 18 Pro owners upset. Apparently, when Face ID fails to detect a user's face, the phone can sometimes crash, which is obviously frustrating for anyone trying to get into their phone.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-W5Em0W"></div>                            </div>                            <script src="https://kwizly.com/embed/W5Em0W.js" async></script><h2 id="iphone-18-face-id-bug">iPhone 18 Face ID bug</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="XEnBSEb3MMRqFRw7NPesBo" name="iPhone 18 Pro Max front" alt="iPhone 18 Pro Max" src="https://cdn.mos.cms.futurecdn.net/XEnBSEb3MMRqFRw7NPesBo-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p><a href="https://www.tomsguide.com/phones/iphones/how-to-protect-your-apps-with-face-id-in-ios-18">Face ID</a> is a huge convenience for iPhone owners (though some would prefer <a href="https://www.tomsguide.com/phones/iphones/apple-could-bring-touch-id-back-to-iphone-but-not-in-the-way-youd-expect">Touch ID back</a>). But when a failed Face ID attempt causes the iPhone to restart, it becomes much less convenient and more of a problem.</p><p>If Face ID reads the user's face and unlocks the phone, there's no issue. But when the angle is off, or Face ID fails for one reason or another, then the problem pops up, and the phone sometimes restarts itself. Though it doesn't seem to affect all iPhone 18 Pro and Pro Max users, even an intermittent bug like this on a brand new phone isn't a good look.</p><p>Thankfully, Apple is aware of the issue and told <a href="https://9to5mac.com/2026/09/23/apple-iphone-18-pro-rebooting-bug-software-update-fix/" target="_blank">9To5Mac</a> that a fix should be launching in the next few days. That fix is already here, thanks to an iOS 27 update.</p><p>The fact that the problem is a software bug, not a hardware issue, is a huge relief. If the company had to recall iPhone 18 Pro devices due to a defect, it could have been a much bigger headache for both Apple and customers with affected devices.</p><p>Of course, we'll have to wait for an update to see whether it completely rectifies the situation. </p><p>In the meantime, there isn't a lot you can do to fix the issue. Instead, just make sure Face ID gets a clear, straight-on view of your face when you unlock your phone to reduce failures. In theory, if Face ID recognizes you, your phone shouldn't restart itself. It's annoying to deal with, but at least you know the end is in sight.</p><h2 id="ios-27-update-fixes-the-bug">iOS 27 update fixes the bug</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="qCqRx69EK98Yt86UK3KgVA" name="iOS 27" alt="iOS 27 logo on iPhone" src="https://cdn.mos.cms.futurecdn.net/qCqRx69EK98Yt86UK3KgVA-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Today, Apple released an update that appears to fix the FaceID bug. iOS version 27.0.1 is the first update for Apple's newest version of iOS. </p><p>You can download iOS 27.0.1 by going to Settings > General > Software Update. Apple also released iPadOS 27.0.1 and visionOS 27.0.1 updates, as well as iOS 26.7.1 and iPadOS 26.7.1 for devices that don't support iOS 27.</p><p>Here's what the release notes say about the bug fixes, per <a href="https://www.macrumors.com/2026/09/28/apple-releases-ios-27-0-1/" target="_blank">MacRumors</a>: </p><p><em>This update provides bug fixes for your iPhone, including fixes for the following issues:</em></p><ul><li><em>iPhone 18 Pro and iPhone 18 Pro Max may unexpectedly restart when Face ID fails to authenticate</em></li><li><em>A color artifact may appear on photos captured at 2x under certain lighting conditions at f/1.48 on a small number of iPhone 18 Pro and iPhone 18 Pro Max devices</em></li><li><em>Opening Notification Center and Control Center simultaneously may cause the touchscreen to become unresponsive</em></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/phones/android-phones/googles-android-president-on-apple-iphone-duo-android-is-usually-where-you-see-the-future-first"><strong>Android president on Apple's iPhone Duo: 'I'm glad to see more people joining what is now the obvious party'</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20"><strong>Forget iPhone 18 Pro — 9 reasons to wait for the iPhone 20</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/i-finally-unlinked-my-iphone-alarm-from-my-ringer-volume-here-is-where-apple-hid-it-in-ios-27"><strong>I finally unlinked my iPhone alarm from my ringer volume — here is where Apple hid it in iOS 27</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/apple-confirms-iphone-18-pro-face-id-freezing-bug-what-you-need-to-know</link>
                                                                            <description>
                            <![CDATA[ Apple is having an issue with the iPhone 18 Pro and Face ID that's annoying new device owners, but a fix is on the way. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">vk5gE9tK9DLZgoFQF3BnWB</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/SX4gbVkjCpbhun7sFGaQEN-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 28 Sep 2026 13:15:21 +0000</pubDate>                                                                                                                                <updated>Mon, 28 Sep 2026 20:12:40 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ dave.leclair@futurenet.com (Dave LeClair) ]]></author>                    <dc:creator><![CDATA[ Dave LeClair ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/fyx7qYdxPMTNBhdnMfNmaB-320-70.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Dave LeClair is the Managing News Editor for Tom&#039;s Guide, keeping his finger on the pulse of all things technology. He loves taking the complicated happenings in the tech world and explaining why they matter. Whether Apple is announcing the next big thing in the mobile space or a small startup advancing generative AI, Dave will apply his experience to help you figure out what&#039;s happening and why it&#039;s relevant to your life.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;Before Tom&#039;s Guide, Dave worked for publications like PCMag, Pocket-lint, MUO, How-To Geek, Digital Trends, and others. He started writing about technology professionally for MUO in 2011 and hasn&#039;t looked back since. In addition to news, you can find reviews, how-to pieces, shopping guides, and many other types of content with Dave&#039;s name attached.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/SX4gbVkjCpbhun7sFGaQEN-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 18 Pro Max and iPhone 18 Pro held side by side]]></media:description>                                                            <media:text><![CDATA[iPhone 18 Pro Max and iPhone 18 Pro held side by side]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 18 Pro Max and iPhone 18 Pro held side by side]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/SX4gbVkjCpbhun7sFGaQEN-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p><em><strong>Update: A fix is now available, keep reading to find out how to get it.</strong></em></p><p>The <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro and iPhone 18 Pro Max</a> are out in the wild now. The launch has been fairly smooth so far, with most people who really wanted the phone able to order one and receive it, though <a href="https://www.tomsguide.com/phones/iphones/warning-here-are-all-the-iphone-18-pro-shipping-delays-at-t-mobile-verizon-at-and-t-and-more">some models and colors were pushed back from the launch date due</a> to popularity. </p><p>But a new issue is emerging that is making iPhone 18 Pro owners upset. Apparently, when Face ID fails to detect a user's face, the phone can sometimes crash, which is obviously frustrating for anyone trying to get into their phone.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-W5Em0W"></div>                            </div>                            <script src="https://kwizly.com/embed/W5Em0W.js" async></script><h2 id="iphone-18-face-id-bug">iPhone 18 Face ID bug</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="XEnBSEb3MMRqFRw7NPesBo" name="iPhone 18 Pro Max front" alt="iPhone 18 Pro Max" src="https://cdn.mos.cms.futurecdn.net/XEnBSEb3MMRqFRw7NPesBo-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p><a href="https://www.tomsguide.com/phones/iphones/how-to-protect-your-apps-with-face-id-in-ios-18">Face ID</a> is a huge convenience for iPhone owners (though some would prefer <a href="https://www.tomsguide.com/phones/iphones/apple-could-bring-touch-id-back-to-iphone-but-not-in-the-way-youd-expect">Touch ID back</a>). But when a failed Face ID attempt causes the iPhone to restart, it becomes much less convenient and more of a problem.</p><p>If Face ID reads the user's face and unlocks the phone, there's no issue. But when the angle is off, or Face ID fails for one reason or another, then the problem pops up, and the phone sometimes restarts itself. Though it doesn't seem to affect all iPhone 18 Pro and Pro Max users, even an intermittent bug like this on a brand new phone isn't a good look.</p><p>Thankfully, Apple is aware of the issue and told <a href="https://9to5mac.com/2026/09/23/apple-iphone-18-pro-rebooting-bug-software-update-fix/" target="_blank">9To5Mac</a> that a fix should be launching in the next few days. That fix is already here, thanks to an iOS 27 update.</p><p>The fact that the problem is a software bug, not a hardware issue, is a huge relief. If the company had to recall iPhone 18 Pro devices due to a defect, it could have been a much bigger headache for both Apple and customers with affected devices.</p><p>Of course, we'll have to wait for an update to see whether it completely rectifies the situation. </p><p>In the meantime, there isn't a lot you can do to fix the issue. Instead, just make sure Face ID gets a clear, straight-on view of your face when you unlock your phone to reduce failures. In theory, if Face ID recognizes you, your phone shouldn't restart itself. It's annoying to deal with, but at least you know the end is in sight.</p><h2 id="ios-27-update-fixes-the-bug">iOS 27 update fixes the bug</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="qCqRx69EK98Yt86UK3KgVA" name="iOS 27" alt="iOS 27 logo on iPhone" src="https://cdn.mos.cms.futurecdn.net/qCqRx69EK98Yt86UK3KgVA-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Today, Apple released an update that appears to fix the FaceID bug. iOS version 27.0.1 is the first update for Apple's newest version of iOS. </p><p>You can download iOS 27.0.1 by going to Settings > General > Software Update. Apple also released iPadOS 27.0.1 and visionOS 27.0.1 updates, as well as iOS 26.7.1 and iPadOS 26.7.1 for devices that don't support iOS 27.</p><p>Here's what the release notes say about the bug fixes, per <a href="https://www.macrumors.com/2026/09/28/apple-releases-ios-27-0-1/" target="_blank">MacRumors</a>: </p><p><em>This update provides bug fixes for your iPhone, including fixes for the following issues:</em></p><ul><li><em>iPhone 18 Pro and iPhone 18 Pro Max may unexpectedly restart when Face ID fails to authenticate</em></li><li><em>A color artifact may appear on photos captured at 2x under certain lighting conditions at f/1.48 on a small number of iPhone 18 Pro and iPhone 18 Pro Max devices</em></li><li><em>Opening Notification Center and Control Center simultaneously may cause the touchscreen to become unresponsive</em></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/phones/android-phones/googles-android-president-on-apple-iphone-duo-android-is-usually-where-you-see-the-future-first"><strong>Android president on Apple's iPhone Duo: 'I'm glad to see more people joining what is now the obvious party'</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20"><strong>Forget iPhone 18 Pro — 9 reasons to wait for the iPhone 20</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/i-finally-unlinked-my-iphone-alarm-from-my-ringer-volume-here-is-where-apple-hid-it-in-ios-27"><strong>I finally unlinked my iPhone alarm from my ringer volume — here is where Apple hid it in iOS 27</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ iPhone Duo: 6 features you’re giving up by not buying the iPhone 18 Pro Max ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I’ve spent the last couple of weeks testing both the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro and iPhone 18 Pro Max</a>, which revealed some of their biggest upgrades — like the class-leading performance of the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen">A20 Pro chip</a> and <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-18-pro-battery-life-tested-the-results-are-surprising">improved battery life</a>. But with the launch of the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> right around the corner, plenty of people are likely still undecided about which one they should buy.</p><p>The fact that the Duo is Apple’s first-ever foldable device is appealing all on its own. Who wouldn’t want the novelty of having an expansive 7.6-inch canvas to multitask and watch videos on the go? However, the price gap certainly gives reason to pause. With a starting price of $1,999, the iPhone Duo commands a massive premium over the $1,299 iPhone 18 Pro Max.</p><p>Paying significantly more for the Duo doesn't just mean a lighter wallet — it comes with the reality of accepting some real compromises. And I'm not just talking about potential <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-trade-offs">iPhone Duo dealbreakers</a> we've already covered, like the lack of telephoto zoom and Face ID. After testing the 18 Pro lineup, these are the 7 features you’re giving up if you choose the iPhone Duo over the iPhone 18 Pro Max.</p><h2 id="proper-magsafe-compatibility">Proper MagSafe compatibility</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:4327px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="hh33LkoPUzesXQf2A99DT9" name="Nomad Leather Mag Wallet" alt="Nomad Leather Mag Wallet on iPhone 17 Pro case." src="https://cdn.mos.cms.futurecdn.net/hh33LkoPUzesXQf2A99DT9-1920-80.jpg" mos="" align="middle" fullscreen="" width="4327" height="2434" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>MagSafe is no longer just an option for me — it’s a necessity given the utility it offers. While the iPhone Duo does include a magnetic ring, I won’t be able to use my favorite MagSafe accessories nearly as smoothly as I do on the iPhone 18 Pro Max.</p><p>That's because the Duo's folding design shifts internal components and cuts into rear real estate. Meaning, standard-sized MagSafe accessories don't sit flush against the back. A perfect example is the <a href="https://www.tomsguide.com/phones/iphones/ive-tried-dozens-of-wallet-cases-but-this-magsafe-wallet-does-one-thing-i-havent-seen-before">MagSafe wallets</a> I've tested, which would overhang past the bottom edge of the frame. Sure, they might still technically stick — but you lose the seamless feel that makes the ecosystem so good in the first place.</p><h2 id="variable-aperture">Variable aperture</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Ps5cuSJ8Gtww8vSAKrrAFU" name="iphone 18 pro varirable aperture" alt="iPhone 18 Pro variable aperture camera" src="https://cdn.mos.cms.futurecdn.net/Ps5cuSJ8Gtww8vSAKrrAFU-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Even now, I’m constantly impressed watching the <a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">mechanical aperture blades</a> over the main camera open and close on the iPhone 18 Pro series. This new system finally brings true optical versatility, letting me stop down to keep expansive landscapes in razor-sharp focus or open wide to produce authentic background blur in portraits.</p><p>I won’t have that mechanical control on the iPhone Duo, leaving me entirely at the mercy of digital post-processing and simulated depth maps. Missing out on the iPhone 18 Pro Max's physical aperture also means losing creative flexibility in other shooting scenarios — like intentionally adding motion blur with moving subjects.</p><h2 id="action-button">Action Button</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2838px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="dSrGEwdMeghVYzcf3N2zYC" name="ios184-visual-intelligence-2" alt="The Action button settings in iOS 18.4 with a Visual Intelligence shortcut for the iPhone 15 Pro" src="https://cdn.mos.cms.futurecdn.net/dSrGEwdMeghVYzcf3N2zYC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2838" height="1596" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Whether you stick with its default setting or customize it, the <a href="https://www.tomsguide.com/how-to/use-iphone-16-action-button-to-do-more-than-one-thing">Action button</a> on the iPhone 18 Pro Max offers genuine utility and granular control over how the phone behaves.</p><p>I rely on it daily for tactile access to my flashlight, camera presets, and favorite <a href="https://www.tomsguide.com/computing/software/apples-shortcuts-app-is-getting-a-huge-upgrade-in-ios-26-and-macos-26-heres-how-it-will-help-you">Shortcuts</a> — a luxury the iPhone Duo simply won't have. That absence stings even more on a foldable, where a programmable physical key could have effortlessly launched two apps side by side with a single click.</p><h2 id="proraw-prores">ProRAW/ProRES</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9vTc72TMzDRoRoybUB5YTd" name="iPhone 15 Pro with Samsung T9 SSD-4.jpg" alt="Apple iPhone 15 Pro Video Recording USB-C." src="https://cdn.mos.cms.futurecdn.net/9vTc72TMzDRoRoybUB5YTd-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>For serious shooters like myself, Apple <a href="https://www.tomsguide.com/news/apple-proraw-iphone-12-pros-killer-photography-feature-explained">ProRAW</a> and <a href="https://www.tomsguide.com/how-to/how-to-record-prores-video-on-iphone-13-pro">ProRes </a>on the iPhone 18 Pro Max provide an essential layer of control in the editing room. ProRAW captures uncompressed files with full sensor readout, giving me the ability to recover highlights, lift shadows, and fine-tune white balance. Pair that with ProRes video — which preserves 10-bit color depth and low compression for smooth scrubbing — and the 18 Pro Max can easily double as an A-cam when I can't use my professional setup.</p><p>With the iPhone Duo, though, you’re limited to standard HEIF and JPEG photos alongside heavily compressed video. While those are perfectly fine for quick social shares, they strip away the post-production editing workflow that lets me get the most out of the cameras.</p><h2 id="log-recording">Log recording</h2><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="2qecuCgsKYTMxtFE3bk7tB" name="iPhone 18 Pro Max camera" alt="iPhone 18 Pro Max camera." src="https://cdn.mos.cms.futurecdn.net/2qecuCgsKYTMxtFE3bk7tB-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>Another video-centric feature that delivers noticeable quality gains is <a href="https://www.tomsguide.com/how-to/how-to-shoot-video-in-a-log-profile-iphone">Apple Log</a> on the iPhone 18 Pro Max. While the unedited footage looks flat and desaturated straight out of camera, the Log profile preserves maximum dynamic range in the highlights and shadows — giving me far more control when color grading. That becomes especially crucial whenever I need to match mobile clips to footage shot on dedicated mirrorless cameras.</p><p>Because Log recording isn’t available on the iPhone Duo, I’d be stuck with Apple’s baked-in color science and contrast. That’s more than fine for casual social clips, but if you rely on your phone as a reliable B-cam, losing Log support makes the Duo a tough sell for serious video workflows.</p><h2 id="spatial-photos-and-videos">Spatial photos and videos</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1485px;"><p class="vanilla-image-block" style="padding-top:56.16%;"><img id="YTmUUxY6xLfaoPB8r6Esf5" name="Capture.PNG" alt="Apple Vision Pro spatial video" src="https://cdn.mos.cms.futurecdn.net/YTmUUxY6xLfaoPB8r6Esf5-1920-80.png" mos="" align="middle" fullscreen="" width="1485" height="834" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>Even if it isn't an everyday shooting mode for most people, the ability to capture <a href="https://www.tomsguide.com/how-to/record-spatial-video-on-iphone">spatial photos and videos</a> has real perks. The iPhone 18 Pro Max has the calibrated sensor array required to record lifelike stereoscopic media ready for playback on <a href="https://www.tomsguide.com/computing/smart-glasses/apple-vision-pro-review">Apple Vision Pro</a> — while letting you preview that parallax effect right inside the Photos app.</p><p>Because the iPhone Duo lacks a LiDAR scanner and the necessary lens alignment, spatial capture isn't an option. That's a miss in my book, especially given how much more pronounced and lifelike the 3D depth feels with static shots. It's way more genuine than the AI-assisted generation of <a href="https://www.tomsguide.com/phones/iphones/i-just-installed-the-ios-27-beta-and-reframe-is-unlike-any-other-ai-feature-ive-come-across">Reframe</a>.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XpBVGW"></div>                            </div>                            <script src="https://kwizly.com/embed/XpBVGW.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/android-phones/googles-android-president-on-apple-iphone-duo-android-is-usually-where-you-see-the-future-first"><strong>Android president on Apple's iPhone Duo: 'I'm glad to see more people joining what is now the obvious party'</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20"><strong>Forget iPhone 18 Pro — 9 reasons to wait for the iPhone 20</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/i-finally-unlinked-my-iphone-alarm-from-my-ringer-volume-here-is-where-apple-hid-it-in-ios-27"><strong>I finally unlinked my iPhone alarm from my ringer volume — here is where Apple hid it in iOS 27</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/iphone-duo-7-features-youre-giving-up-by-not-buying-the-iphone-18-pro-max</link>
                                                                            <description>
                            <![CDATA[ While the upcoming iPhone Duo brings new utility, the iPhone 18 Pro Max has features I've genuinely come to enjoy and use. Here's what you don't get with the Duo. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">b7TnSUBC5oCxZSnKqCquPc</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/GBMD7e8uuJ6iTS9UUzZHzf-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 28 Sep 2026 04:30:00 +0000</pubDate>                                                                                                                                <updated>Wed, 30 Sep 2026 14:13:32 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ john.velasco@futurenet.com (John Velasco) ]]></author>                    <dc:creator><![CDATA[ John Velasco ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/TSj224oX8d5ERXaDs8pDGd-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/GBMD7e8uuJ6iTS9UUzZHzf-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone Duo vs iPhone 18 Pro.]]></media:description>                                                            <media:text><![CDATA[iPhone Duo vs iPhone 18 Pro.]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone Duo vs iPhone 18 Pro.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/GBMD7e8uuJ6iTS9UUzZHzf-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I’ve spent the last couple of weeks testing both the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro and iPhone 18 Pro Max</a>, which revealed some of their biggest upgrades — like the class-leading performance of the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen">A20 Pro chip</a> and <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-18-pro-battery-life-tested-the-results-are-surprising">improved battery life</a>. But with the launch of the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> right around the corner, plenty of people are likely still undecided about which one they should buy.</p><p>The fact that the Duo is Apple’s first-ever foldable device is appealing all on its own. Who wouldn’t want the novelty of having an expansive 7.6-inch canvas to multitask and watch videos on the go? However, the price gap certainly gives reason to pause. With a starting price of $1,999, the iPhone Duo commands a massive premium over the $1,299 iPhone 18 Pro Max.</p><p>Paying significantly more for the Duo doesn't just mean a lighter wallet — it comes with the reality of accepting some real compromises. And I'm not just talking about potential <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-trade-offs">iPhone Duo dealbreakers</a> we've already covered, like the lack of telephoto zoom and Face ID. After testing the 18 Pro lineup, these are the 7 features you’re giving up if you choose the iPhone Duo over the iPhone 18 Pro Max.</p><h2 id="proper-magsafe-compatibility">Proper MagSafe compatibility</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:4327px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="hh33LkoPUzesXQf2A99DT9" name="Nomad Leather Mag Wallet" alt="Nomad Leather Mag Wallet on iPhone 17 Pro case." src="https://cdn.mos.cms.futurecdn.net/hh33LkoPUzesXQf2A99DT9-1920-80.jpg" mos="" align="middle" fullscreen="" width="4327" height="2434" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>MagSafe is no longer just an option for me — it’s a necessity given the utility it offers. While the iPhone Duo does include a magnetic ring, I won’t be able to use my favorite MagSafe accessories nearly as smoothly as I do on the iPhone 18 Pro Max.</p><p>That's because the Duo's folding design shifts internal components and cuts into rear real estate. Meaning, standard-sized MagSafe accessories don't sit flush against the back. A perfect example is the <a href="https://www.tomsguide.com/phones/iphones/ive-tried-dozens-of-wallet-cases-but-this-magsafe-wallet-does-one-thing-i-havent-seen-before">MagSafe wallets</a> I've tested, which would overhang past the bottom edge of the frame. Sure, they might still technically stick — but you lose the seamless feel that makes the ecosystem so good in the first place.</p><h2 id="variable-aperture">Variable aperture</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Ps5cuSJ8Gtww8vSAKrrAFU" name="iphone 18 pro varirable aperture" alt="iPhone 18 Pro variable aperture camera" src="https://cdn.mos.cms.futurecdn.net/Ps5cuSJ8Gtww8vSAKrrAFU-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Even now, I’m constantly impressed watching the <a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">mechanical aperture blades</a> over the main camera open and close on the iPhone 18 Pro series. This new system finally brings true optical versatility, letting me stop down to keep expansive landscapes in razor-sharp focus or open wide to produce authentic background blur in portraits.</p><p>I won’t have that mechanical control on the iPhone Duo, leaving me entirely at the mercy of digital post-processing and simulated depth maps. Missing out on the iPhone 18 Pro Max's physical aperture also means losing creative flexibility in other shooting scenarios — like intentionally adding motion blur with moving subjects.</p><h2 id="action-button">Action Button</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2838px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="dSrGEwdMeghVYzcf3N2zYC" name="ios184-visual-intelligence-2" alt="The Action button settings in iOS 18.4 with a Visual Intelligence shortcut for the iPhone 15 Pro" src="https://cdn.mos.cms.futurecdn.net/dSrGEwdMeghVYzcf3N2zYC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2838" height="1596" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Whether you stick with its default setting or customize it, the <a href="https://www.tomsguide.com/how-to/use-iphone-16-action-button-to-do-more-than-one-thing">Action button</a> on the iPhone 18 Pro Max offers genuine utility and granular control over how the phone behaves.</p><p>I rely on it daily for tactile access to my flashlight, camera presets, and favorite <a href="https://www.tomsguide.com/computing/software/apples-shortcuts-app-is-getting-a-huge-upgrade-in-ios-26-and-macos-26-heres-how-it-will-help-you">Shortcuts</a> — a luxury the iPhone Duo simply won't have. That absence stings even more on a foldable, where a programmable physical key could have effortlessly launched two apps side by side with a single click.</p><h2 id="proraw-prores">ProRAW/ProRES</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9vTc72TMzDRoRoybUB5YTd" name="iPhone 15 Pro with Samsung T9 SSD-4.jpg" alt="Apple iPhone 15 Pro Video Recording USB-C." src="https://cdn.mos.cms.futurecdn.net/9vTc72TMzDRoRoybUB5YTd-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>For serious shooters like myself, Apple <a href="https://www.tomsguide.com/news/apple-proraw-iphone-12-pros-killer-photography-feature-explained">ProRAW</a> and <a href="https://www.tomsguide.com/how-to/how-to-record-prores-video-on-iphone-13-pro">ProRes </a>on the iPhone 18 Pro Max provide an essential layer of control in the editing room. ProRAW captures uncompressed files with full sensor readout, giving me the ability to recover highlights, lift shadows, and fine-tune white balance. Pair that with ProRes video — which preserves 10-bit color depth and low compression for smooth scrubbing — and the 18 Pro Max can easily double as an A-cam when I can't use my professional setup.</p><p>With the iPhone Duo, though, you’re limited to standard HEIF and JPEG photos alongside heavily compressed video. While those are perfectly fine for quick social shares, they strip away the post-production editing workflow that lets me get the most out of the cameras.</p><h2 id="log-recording">Log recording</h2><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="2qecuCgsKYTMxtFE3bk7tB" name="iPhone 18 Pro Max camera" alt="iPhone 18 Pro Max camera." src="https://cdn.mos.cms.futurecdn.net/2qecuCgsKYTMxtFE3bk7tB-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>Another video-centric feature that delivers noticeable quality gains is <a href="https://www.tomsguide.com/how-to/how-to-shoot-video-in-a-log-profile-iphone">Apple Log</a> on the iPhone 18 Pro Max. While the unedited footage looks flat and desaturated straight out of camera, the Log profile preserves maximum dynamic range in the highlights and shadows — giving me far more control when color grading. That becomes especially crucial whenever I need to match mobile clips to footage shot on dedicated mirrorless cameras.</p><p>Because Log recording isn’t available on the iPhone Duo, I’d be stuck with Apple’s baked-in color science and contrast. That’s more than fine for casual social clips, but if you rely on your phone as a reliable B-cam, losing Log support makes the Duo a tough sell for serious video workflows.</p><h2 id="spatial-photos-and-videos">Spatial photos and videos</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1485px;"><p class="vanilla-image-block" style="padding-top:56.16%;"><img id="YTmUUxY6xLfaoPB8r6Esf5" name="Capture.PNG" alt="Apple Vision Pro spatial video" src="https://cdn.mos.cms.futurecdn.net/YTmUUxY6xLfaoPB8r6Esf5-1920-80.png" mos="" align="middle" fullscreen="" width="1485" height="834" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>Even if it isn't an everyday shooting mode for most people, the ability to capture <a href="https://www.tomsguide.com/how-to/record-spatial-video-on-iphone">spatial photos and videos</a> has real perks. The iPhone 18 Pro Max has the calibrated sensor array required to record lifelike stereoscopic media ready for playback on <a href="https://www.tomsguide.com/computing/smart-glasses/apple-vision-pro-review">Apple Vision Pro</a> — while letting you preview that parallax effect right inside the Photos app.</p><p>Because the iPhone Duo lacks a LiDAR scanner and the necessary lens alignment, spatial capture isn't an option. That's a miss in my book, especially given how much more pronounced and lifelike the 3D depth feels with static shots. It's way more genuine than the AI-assisted generation of <a href="https://www.tomsguide.com/phones/iphones/i-just-installed-the-ios-27-beta-and-reframe-is-unlike-any-other-ai-feature-ive-come-across">Reframe</a>.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XpBVGW"></div>                            </div>                            <script src="https://kwizly.com/embed/XpBVGW.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/android-phones/googles-android-president-on-apple-iphone-duo-android-is-usually-where-you-see-the-future-first"><strong>Android president on Apple's iPhone Duo: 'I'm glad to see more people joining what is now the obvious party'</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20"><strong>Forget iPhone 18 Pro — 9 reasons to wait for the iPhone 20</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/i-finally-unlinked-my-iphone-alarm-from-my-ringer-volume-here-is-where-apple-hid-it-in-ios-27"><strong>I finally unlinked my iPhone alarm from my ringer volume — here is where Apple hid it in iOS 27</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tested iPhone 18 Pro vs Pixel 11 Pro and found out which extracts better photos from video clips ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Being able to carry a powerful camera in my pocket is fantastic, and I can't tell you the number of times I've been able to pull out my phone to snap something that would have otherwise vanished in a second. The problem is that smartphones are not so great and shooting a lot of photos in a short space of time.</p><p>The lack of a burst mode has always irked me, especially since I'm often trying to take photos of things that are moving around — mainly my dogs or my son.  My workaround has been to shoot video and then try and screenshot the appropriate frame, but those results are often lacking. You lose resolution and the whole process is rather fiddly, as you try and find the perfect frame.</p><p>Thankfully Google and Apple have each developed systems to do this exact thing, without all the same pitfalls. The execution is very different, though, and I set out to see whether <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-pro-xl-review">Google Pixel 11 Pro's</a> <a href="https://www.tomsguide.com/phones/google-pixel-phones/the-pixel-11-is-a-swing-and-a-miss-of-a-phone-but-this-one-ai-camera-feature-is-genuinely-useful">Magic Capture</a> or the Save Video Frame as Photo option from<a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review"> iPhone 18 Pro</a> and <a href="https://www.tomsguide.com/phones/iphones/ios-27-7-features-you-need-to-try-first-after-updating">iOS 27</a> offered a better experience.</p><h2 id="what-are-magic-capture-and-save-video-frame-as-photo">What are Magic Capture and Save Video Frame as Photo?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:5590px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="nTDHtTHnfed5HyDkXhb5iV" name="Google Pixel 11 Pro XL-5" alt="pixel 11 pro and 11 pro xl review images" src="https://cdn.mos.cms.futurecdn.net/nTDHtTHnfed5HyDkXhb5iV-1920-80.jpg" mos="" align="middle" fullscreen="" width="5590" height="3144" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Magic Capture is a new AI-powered feature exclusive to <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-review">Google's Pixel 11</a> series, and it functions as a separate mode within the Pixel camera app. Magic Capture records videos up to two minutes in length, and once finished, uses AI to analyze the footage and export a handful of frames as standalone photos.</p><p>The crucial thing there is that the whole process is automatic. You don't get to choose what Magic Capture picks out, and the number of photos you get is actually pretty limited. You get one photo at first, but that number increases to five once the cloud-based processing is complete. </p><p>In contrast to this, Apple's Save Video Frame as Photo feature is all on you. Rather than having a specialist camera mode, or complicated AI integration, it all functions as a feature in the Apple Photos app. Simply find a video you want to pull photos from, tap the three-dot menu in the top-right corner, and tap the <strong>Save Video Frame as Photo</strong> option.</p><p>Tapping that option then isolates the frame that's on screen and exports it to Apple Photos as a photo. It doesn't matter whether the video is playing, or if you've paused it, the feature will work as advertised, dropping the newly-created photo at the end of your timeline. Naturally, the manual process means you're not guaranteed to get a good photo, since it only copies what's seen on screen.</p><p><strong>How do they actually differ in practice?</strong></p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dwHR9JPRYGZjEvwow5JR3X" name="pixel" alt="magic capture screenshots" src="https://cdn.mos.cms.futurecdn.net/dwHR9JPRYGZjEvwow5JR3X-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Magic Capture is certainly the more convenient method of extracting photos from video, though it definitely comes with some downsides. The fact that you can record a video clip, and have Google's AI do all the hard work for you to get things done quickly and stress-free. That said, the limitations do get in the way.</p><p>One issue is that Magic Capture is limited to two minutes of actual use. That's not an issue for short bursts of video, but if you want continuous, uninterrupted recording, you're out of luck. Similarly the feature sticks you with five photos no matter how long the clip is — no more, no less. It doesn't matter whether you record 30 seconds or the full two minutes, you get five photos. </p><p>If you want anything more, or you don't like what Magic Capture selected, you're going to have to do things the old fashioned way. That is less than ideal, especially since Magic Capture was supposed to solve this problem. The reliance on cloud processing may also be a little much for some people, depending on how much you trust Google's servers to keep your video clips secure.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="PdghV85CwZQ63wqS85MJDF" name="TG Deals Template 2023 copy" alt="ios 27 save video frame as photo feature" src="https://cdn.mos.cms.futurecdn.net/PdghV85CwZQ63wqS85MJDF-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Apple's system has no such limitations, because it doesn't rely on AI processing or a specialist camera. You simply record a video as normal, with no extra caveats or conditions you need to meet. The obvious downside is that you need to pull each individual frame out manually, which is not that easy — especially on an iPhone touchscreen.</p><p>There's a difference between photographs and video frames, since one is designed to be standalone and the other is one part of something much larger. Without the surrounding frames, that single snapshot could look like absolute garbage. And that happens quite a lot with the Save Video Frame as Photo feature. Not always, and rapid movement definitely makes it a lot harder, but it is something to be aware of.</p><p>The process is fairly simple, though. You load up the video you recorded in Apple Photos, and slide the progress bar along until you get to the frame you want to see as a photo. The main issue is that doing it in Portrait mode is not easy, especially if it's a particularly long video. This isn't like VLC, where you can advance frame by frame until you get to the spot you want. </p><p>There isn't enough finesse in my fingers to be super accurate with everything, but I found that flipping the phone into landscape mode made the process slightly easier. Similarly, loading up the video on my iPad and cycling through the video using the Apple Pencil made it feel as though I had more control over the entire process. Yes, <a href="https://www.tomsguide.com/computing/ipads/ipados-27-review">iPadOS 27</a> has this feature too, and it works in the exact same way.</p><p>Clipping videos down into shorter clips can also be a big help, since the playback bar is the same size no matter the length of the video in question.</p><h2 id="verdict-which-is-the-better-option">Verdict: Which is the better option?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="5kKUCv7Eef6yGkMMGEgbvJ" name="iPhone 18 Pro and Pro Max-9" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/5kKUCv7Eef6yGkMMGEgbvJ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The most important thing to remember about Magic Capture and Apple's Save Video Frame as Photo is that they are both rather different methods of reaching the same goal. The way they work is going to impact which of these is actually right for you, and the truth is that neither of them is a bad option.</p><p>Magic Capture has its limits, but it's the easiest way to get a handful of photos from short video clips. Personally I think Google's option is better suited to those times when you know getting a good photo is going to be difficult, but you don't want the moment to pass. So you use Magic Capture to record the video, and have Google AI select five photos of the event in question.</p><p>Meanwhile Apple's Save Video Frame to Photo feature is arguably better for those times you know you're going to be recording anyway, but want to be able to export different frames as their own photos. Or, alternatively, for those of you that prefer to put the effort into generating those photos yourself, rather than having a faceless collection of cloud-based AI algorithms do it for you. It's certainly the more labor-intensive option, but it's also the one that ensures better data security. Provided you have the will and means to go through your video frame-by-frame — or close enough to it.</p><p>A blend of the two wouldn't be a bad option, especially if Apple can adapt its own version of Magic Capture through Private Cloud Compute. However, we can all agree that it certainly beats the alternative of screenshotting videos and losing all resolution in the process.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/google-pixel-phones/pixel-11-phones-will-soon-have-a-new-gemini-intelligence-feature-that-will-actually-make-phone-calls-on-your-behalf-and-its-exactly-what-the-introvert-in-me-wants"><strong>Pixel 11 phones will soon have a new Gemini Intelligence feature that will actually make phone calls on your behalf</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20"><strong>Forget iPhone 18 Pro — 9 reasons to wait for the iPhone 20</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/ios-27-didnt-add-this-anti-snatching-feature-to-iphone-but-that-doesnt-mean-its-been-cancelled-heres-why-its-important"><strong>iOS 27 didn't add this anti-snatching feature to iPhone, but that doesn't mean it's been cancelled — here's why it's important</strong></a><strong></strong></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-vs-pixel-11-pro-and-found-out-which-extracts-better-photos-from-video-clips</link>
                                                                            <description>
                            <![CDATA[ Which is better, Google's AI-powered Magic Capture or Apple's manual Save Video Frame as Photo? ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">ZLbefGbcQt6chhZWameDwE</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/HYuuDMJ2Ch2YMUKD2MbYWc-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 27 Sep 2026 07:30:00 +0000</pubDate>                                                                                                                                <updated>Sun, 27 Sep 2026 12:45:05 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Google Phones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                    <category><![CDATA[Android Phones]]></category>
                                                                                                <author><![CDATA[ tom.pritchard@futurenet.com (Tom Pritchard) ]]></author>                    <dc:creator><![CDATA[ Tom Pritchard ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/biCewUkKfSA6QnT2HxVc3f-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/HYuuDMJ2Ch2YMUKD2MbYWc-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 18 Pro cameras]]></media:description>                                                            <media:text><![CDATA[iPhone 18 Pro cameras]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 18 Pro cameras]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/HYuuDMJ2Ch2YMUKD2MbYWc-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Being able to carry a powerful camera in my pocket is fantastic, and I can't tell you the number of times I've been able to pull out my phone to snap something that would have otherwise vanished in a second. The problem is that smartphones are not so great and shooting a lot of photos in a short space of time.</p><p>The lack of a burst mode has always irked me, especially since I'm often trying to take photos of things that are moving around — mainly my dogs or my son.  My workaround has been to shoot video and then try and screenshot the appropriate frame, but those results are often lacking. You lose resolution and the whole process is rather fiddly, as you try and find the perfect frame.</p><p>Thankfully Google and Apple have each developed systems to do this exact thing, without all the same pitfalls. The execution is very different, though, and I set out to see whether <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-pro-xl-review">Google Pixel 11 Pro's</a> <a href="https://www.tomsguide.com/phones/google-pixel-phones/the-pixel-11-is-a-swing-and-a-miss-of-a-phone-but-this-one-ai-camera-feature-is-genuinely-useful">Magic Capture</a> or the Save Video Frame as Photo option from<a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review"> iPhone 18 Pro</a> and <a href="https://www.tomsguide.com/phones/iphones/ios-27-7-features-you-need-to-try-first-after-updating">iOS 27</a> offered a better experience.</p><h2 id="what-are-magic-capture-and-save-video-frame-as-photo">What are Magic Capture and Save Video Frame as Photo?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:5590px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="nTDHtTHnfed5HyDkXhb5iV" name="Google Pixel 11 Pro XL-5" alt="pixel 11 pro and 11 pro xl review images" src="https://cdn.mos.cms.futurecdn.net/nTDHtTHnfed5HyDkXhb5iV-1920-80.jpg" mos="" align="middle" fullscreen="" width="5590" height="3144" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Magic Capture is a new AI-powered feature exclusive to <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-review">Google's Pixel 11</a> series, and it functions as a separate mode within the Pixel camera app. Magic Capture records videos up to two minutes in length, and once finished, uses AI to analyze the footage and export a handful of frames as standalone photos.</p><p>The crucial thing there is that the whole process is automatic. You don't get to choose what Magic Capture picks out, and the number of photos you get is actually pretty limited. You get one photo at first, but that number increases to five once the cloud-based processing is complete. </p><p>In contrast to this, Apple's Save Video Frame as Photo feature is all on you. Rather than having a specialist camera mode, or complicated AI integration, it all functions as a feature in the Apple Photos app. Simply find a video you want to pull photos from, tap the three-dot menu in the top-right corner, and tap the <strong>Save Video Frame as Photo</strong> option.</p><p>Tapping that option then isolates the frame that's on screen and exports it to Apple Photos as a photo. It doesn't matter whether the video is playing, or if you've paused it, the feature will work as advertised, dropping the newly-created photo at the end of your timeline. Naturally, the manual process means you're not guaranteed to get a good photo, since it only copies what's seen on screen.</p><p><strong>How do they actually differ in practice?</strong></p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dwHR9JPRYGZjEvwow5JR3X" name="pixel" alt="magic capture screenshots" src="https://cdn.mos.cms.futurecdn.net/dwHR9JPRYGZjEvwow5JR3X-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Magic Capture is certainly the more convenient method of extracting photos from video, though it definitely comes with some downsides. The fact that you can record a video clip, and have Google's AI do all the hard work for you to get things done quickly and stress-free. That said, the limitations do get in the way.</p><p>One issue is that Magic Capture is limited to two minutes of actual use. That's not an issue for short bursts of video, but if you want continuous, uninterrupted recording, you're out of luck. Similarly the feature sticks you with five photos no matter how long the clip is — no more, no less. It doesn't matter whether you record 30 seconds or the full two minutes, you get five photos. </p><p>If you want anything more, or you don't like what Magic Capture selected, you're going to have to do things the old fashioned way. That is less than ideal, especially since Magic Capture was supposed to solve this problem. The reliance on cloud processing may also be a little much for some people, depending on how much you trust Google's servers to keep your video clips secure.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="PdghV85CwZQ63wqS85MJDF" name="TG Deals Template 2023 copy" alt="ios 27 save video frame as photo feature" src="https://cdn.mos.cms.futurecdn.net/PdghV85CwZQ63wqS85MJDF-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Apple's system has no such limitations, because it doesn't rely on AI processing or a specialist camera. You simply record a video as normal, with no extra caveats or conditions you need to meet. The obvious downside is that you need to pull each individual frame out manually, which is not that easy — especially on an iPhone touchscreen.</p><p>There's a difference between photographs and video frames, since one is designed to be standalone and the other is one part of something much larger. Without the surrounding frames, that single snapshot could look like absolute garbage. And that happens quite a lot with the Save Video Frame as Photo feature. Not always, and rapid movement definitely makes it a lot harder, but it is something to be aware of.</p><p>The process is fairly simple, though. You load up the video you recorded in Apple Photos, and slide the progress bar along until you get to the frame you want to see as a photo. The main issue is that doing it in Portrait mode is not easy, especially if it's a particularly long video. This isn't like VLC, where you can advance frame by frame until you get to the spot you want. </p><p>There isn't enough finesse in my fingers to be super accurate with everything, but I found that flipping the phone into landscape mode made the process slightly easier. Similarly, loading up the video on my iPad and cycling through the video using the Apple Pencil made it feel as though I had more control over the entire process. Yes, <a href="https://www.tomsguide.com/computing/ipads/ipados-27-review">iPadOS 27</a> has this feature too, and it works in the exact same way.</p><p>Clipping videos down into shorter clips can also be a big help, since the playback bar is the same size no matter the length of the video in question.</p><h2 id="verdict-which-is-the-better-option">Verdict: Which is the better option?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="5kKUCv7Eef6yGkMMGEgbvJ" name="iPhone 18 Pro and Pro Max-9" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/5kKUCv7Eef6yGkMMGEgbvJ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The most important thing to remember about Magic Capture and Apple's Save Video Frame as Photo is that they are both rather different methods of reaching the same goal. The way they work is going to impact which of these is actually right for you, and the truth is that neither of them is a bad option.</p><p>Magic Capture has its limits, but it's the easiest way to get a handful of photos from short video clips. Personally I think Google's option is better suited to those times when you know getting a good photo is going to be difficult, but you don't want the moment to pass. So you use Magic Capture to record the video, and have Google AI select five photos of the event in question.</p><p>Meanwhile Apple's Save Video Frame to Photo feature is arguably better for those times you know you're going to be recording anyway, but want to be able to export different frames as their own photos. Or, alternatively, for those of you that prefer to put the effort into generating those photos yourself, rather than having a faceless collection of cloud-based AI algorithms do it for you. It's certainly the more labor-intensive option, but it's also the one that ensures better data security. Provided you have the will and means to go through your video frame-by-frame — or close enough to it.</p><p>A blend of the two wouldn't be a bad option, especially if Apple can adapt its own version of Magic Capture through Private Cloud Compute. However, we can all agree that it certainly beats the alternative of screenshotting videos and losing all resolution in the process.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/google-pixel-phones/pixel-11-phones-will-soon-have-a-new-gemini-intelligence-feature-that-will-actually-make-phone-calls-on-your-behalf-and-its-exactly-what-the-introvert-in-me-wants"><strong>Pixel 11 phones will soon have a new Gemini Intelligence feature that will actually make phone calls on your behalf</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20"><strong>Forget iPhone 18 Pro — 9 reasons to wait for the iPhone 20</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/ios-27-didnt-add-this-anti-snatching-feature-to-iphone-but-that-doesnt-mean-its-been-cancelled-heres-why-its-important"><strong>iOS 27 didn't add this anti-snatching feature to iPhone, but that doesn't mean it's been cancelled — here's why it's important</strong></a><strong></strong></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tested Belkin's 'semi-solid-state' battery — and it's the best iPhone portable charger I've ever used ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I'm a big fan of <a href="https://www.tomsguide.com/phones/google-pixel-phones/i-added-magsafe-support-to-my-pixel-9-pro-because-google-refused-to-heres-how">magnetic phone accessories</a>, especially when it involves MagSafe-compatible wireless charging. Portable battery packs are great, but the reliance on cables is not something I will ever be happy about. Switching to wireless charging, and using magnets to keep everything in place, means that problem is eliminated — though it's not ideal that those batteries add a bunch of bulk and weight to your phone.</p><p>Belkin's newest magnetic battery pack, <a href="https://www.belkin.com/pr-belkin-ultra-charge-pro-semi-solid-state-power-banks.html" target="_blank">UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell,</a> helps to eliminate that problem. The "Semi Solid State" battery design is significantly thinner and lighter than you might expect, which makes a surprising amount of difference for comfort. However, that also comes at the cost of overall capacity, which may or not be a dealbreaker.</p><div class="product"><a data-dimension112="df0c4ffc-b8ee-11f1-9c35-690e422548c3" data-action="Deal Block" data-label="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension48="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension25="$69" href="https://www.amazon.com/Belkin-5000mAh-Magnetic-Wireless-Charger/dp/B0HHBHL8W2" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:976px;"><p class="vanilla-image-block" style="padding-top:153.69%;"><img id="xf8bgkRQfXnV33JCG9h7jb" name="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/xf8bgkRQfXnV33JCG9h7jb-1920-80.png" mos="" align="middle" fullscreen="" width="976" height="1500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.amazon.com/Belkin-5000mAh-Magnetic-Wireless-Charger/dp/B0HHBHL8W2" target="_blank" rel="nofollow" data-dimension112="df0c4ffc-b8ee-11f1-9c35-690e422548c3" data-action="Deal Block" data-label="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension48="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension25="$69">UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell: $69</a></strong><br>Belkin's new Semi-Solid-State battery pack is thinner and lighter than any magnetic battery pack I've ever used. While the relatively low capacity might be a problem for some, it is an absolute joy to use for those reasons. It offers 15W Qi2 wireless charging on the go and built-in temperature management technology.<a class="view-deal button" href="https://www.amazon.com/Belkin-5000mAh-Magnetic-Wireless-Charger/dp/B0HHBHL8W2" target="_blank" rel="nofollow" data-dimension112="df0c4ffc-b8ee-11f1-9c35-690e422548c3" data-action="Deal Block" data-label="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension48="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension25="$69">View Deal</a></p></div><div class="product"><a data-dimension112="75474514-bc08-11f1-96dd-0d6b6fccd597" data-action="Deal Block" data-label="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension48="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension25="£60" href="https://www.amazon.co.uk/Belkin-UltraCharge-5000mAh-Semi-Solid-State-Wireless/dp/B0HFJS1LVW" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:700px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="YbjrGZMrc73eSYJGJiYC4A" name="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/YbjrGZMrc73eSYJGJiYC4A-1920-80.png" mos="" align="middle" fullscreen="" width="700" height="700" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.amazon.co.uk/Belkin-UltraCharge-5000mAh-Semi-Solid-State-Wireless/dp/B0HFJS1LVW" target="_blank" rel="nofollow" data-dimension112="75474514-bc08-11f1-96dd-0d6b6fccd597" data-action="Deal Block" data-label="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension48="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension25="£60">UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell: £60</a></strong><br>Those of you living in the U.K. can also pick up the UltraCharge Pro for £60. You can the exact same battery and specs, but with a price tag in British pounds instead of dollars.<a class="view-deal button" href="https://www.amazon.co.uk/Belkin-UltraCharge-5000mAh-Semi-Solid-State-Wireless/dp/B0HFJS1LVW" target="_blank" rel="nofollow" data-dimension112="75474514-bc08-11f1-96dd-0d6b6fccd597" data-action="Deal Block" data-label="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension48="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension25="£60">View Deal</a></p></div><h2 id="what-the-heck-is-a-39-semi-solid-state-39-battery">What the heck is a 'semi-solid-state' battery?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ZJCG4aTG8pWTGfDBEAEcTD" name="PXL_20260925_140126366" alt="Belkin UltraCharge Pro Magnetic Power Bank" src="https://cdn.mos.cms.futurecdn.net/ZJCG4aTG8pWTGfDBEAEcTD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>You may be wondering what Semi-Solid-State actually means. The idea of solid-state batteries is nothing new, since those offer power without any of the chemical movements and reactions. </p><p>According to Belkin, this "semi-solid" design utilizes a gel-like layer alongside a liquid electrolyte. The company hasn't gone into the specifics of how everything works, but the design enables a slimmer and more compact design, greater longevity and a much lower risk of overheating. That should help improve the overall safety of using these batteries, and considering the clampdown by airlines in recent months, that's definitely a good thing.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Wiq6MgcSzojNoLcpuLDeSD" name="PXL_20260925_140121879" alt="Belkin UltraCharge Pro Magnetic Power Bank" src="https://cdn.mos.cms.futurecdn.net/Wiq6MgcSzojNoLcpuLDeSD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Speaking of airlines, Belkin says that the <a href="https://www.belkin.com/p/slim-magnetic-power-bank-5k-with-boostsolid-cell/BPD024fqBK.html" target="_blank" rel="nofollow">$70 UltraCharge Pro Magnetic Power Bank</a> has been built to comply with standard safety requirements, and the TSA's carry-on guidance. Though this doesn't necessarily mean that you are cleared to use this one in the air. Each airline has their own policies, and you need to be aware of them before you travel.</p><p>The battery itself is Qi2 certified, offering up to 15W charging speeds on compatible phones. Wired USB-C charging is also available if you have a cable, with speeds up to 7.5W. The battery itself recharges at up to 22.5W. Naturally, being magnetic, it snaps onto the back of your phone — whether it has built-in magnets or you're using a special case.</p><p>Materials-wise, you've got a battery that is a mix of metal and rubber, which is not exactly uncommon in magnetic batteries, though the actual size of the thing is arguably where its biggest strength lies.</p><h2 id="how-does-it-compare-to-my-existing-magnetic-power-bank">How does it compare to my existing magnetic power bank?</h2><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="WUA5JUqSBq8jfWLwYcnjTD" name="PXL_20260925_140207588" alt="Belkin UltraCharge Pro Magnetic Power Bank" src="https://cdn.mos.cms.futurecdn.net/WUA5JUqSBq8jfWLwYcnjTD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The magnetic battery pack I use most of the time is <a href="https://www.amazon.com/UGREEN-10000mAh-Magnetic-Power-Black/dp/B0CH33F5P2/" target="_blank" rel="nofollow">UGreen's 10,000 mAh magnetic power pack</a>. It's a fairly cheap option, which means it isn't officially certified as MagSafe or Qi2 — it's just a regular wireless charger with a MagSafe-compatible connection. That means it's slow, and it has a habit of getting pretty hot.</p><p>UGreen's model is 0.79-inches thick, which is more than double Belkin's 0.35-inches. It's also heavier, weighing 7.9 ounces compared to 4.4 ounces for the Belkin. The UGreen battery is actually heavier and thicker than an iPhone 17 Pro (0.35-inches and 7.27 ounces), and only slightly lighter than the iPhone 17 Pro Max (8.33 ounces).</p><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="kDmKnRfMNrAVgVtrErPuED" name="PXL_20260925_140228651" alt="Belkin UltraCharge Pro Magnetic Power Bank" src="https://cdn.mos.cms.futurecdn.net/kDmKnRfMNrAVgVtrErPuED-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The UltraCharge Pro Magnetic Power Bank is still going to add thickness and weight to your phone. However, it is a lot more comfortable and convenient to use compared to the bulky UGreen option I've been using.</p><p>The downside is that it the Belkin has half the capacity of the UGreen. 10,000 mAh is enough to charge just about every phone at least once — and often more. 5,000 mAh doesn't go quite as far, but it's no small amount of power. It's enough to recharge a lot of phones in full, and enough to add a significant amount of power to others. </p><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="XFcqQapJ3csAzN7kapb6qC" name="PXL_20260925_140214437" alt="Belkin UltraCharge Pro Magnetic Power Bank" src="https://cdn.mos.cms.futurecdn.net/XFcqQapJ3csAzN7kapb6qC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Personally, while I like to overprepare and make sure I have more than enough energy to keep me going, I'll admit that 10,000 mAh is a bit overkill for most situations. So long as you have enough power to make it through the day, and get back to a home charger, then what does it matter how much of a reserve you have?</p><p>In terms of charging and heat, I decided to test the two batteries on my iPhone 17 Pro Max starting at 47% charge. The Belkin battery restored 10%, bringing the total to 57% in that time, while the UGreen battery brought the charge to 54% — a 7% increase. It's not a huge amount of difference, but over the course of many hours that will add up. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1900px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="cYhGhQSnQJDo6xAqrUGN5X" name="FLIR_20260925_095419_443" alt="belkin vs ugreen thermal imagery" src="https://cdn.mos.cms.futurecdn.net/cYhGhQSnQJDo6xAqrUGN5X-1920-80.jpg" mos="" align="middle" fullscreen="" width="1900" height="1069" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">Left: Belkin, Right: Ugreen </span><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>As for heat, the Belkin battery definitely felt warmer, but a quick check with a thermal camera saw the temperature peak at just under 95 degrees Fahrenheit. The UGreen battery didn't feel nearly as warm, but the thermal imaging revealed that a small part of the battery had risen to just shy of 97 degrees. That's not a huge difference, but you do have to remember that the UGreen charger is going much more slowly — and I did feel that heat start to add up over extended charging sessions.</p><p>Wireless charging is always going to produce some heat if you don't have some sort of active cooling system. The Belkin UltraCharge does get warm, but it doesn't get too hot, which is quite nice.</p><h2 id="bottom-line-3">Bottom line</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="BFGpKU627gDADg4NcbgMTD" name="PXL_20260925_140123935" alt="Belkin UltraCharge Pro Magnetic Power Bank" src="https://cdn.mos.cms.futurecdn.net/BFGpKU627gDADg4NcbgMTD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>I really like the Belkin UltraCharge Pro Magnetic Power Bank. Not specifically because it's a semi-solid-state battery, but because it manages to do all the things you need from a portable battery pack. It's slim and lightweight, with the magnetic connection making it incredibly easy to recharge your phone. Plus, the 15W Qi2 speeds mean it's fairly speedy as far as wireless charging goes.</p><p>Admittedly, the 5,000 mAh capacity would be enough to make me hesitate on buying one for myself — especially with a $70 price tag. You can buy wired battery packs that offer four times the capacity for similar prices, if not less. Still, you can't fault the Belkin for convenience or comfort, and that premium might be worth it if you regularly find that you need to top off your phone on the move.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/ios-27-didnt-add-this-anti-snatching-feature-to-iphone-but-that-doesnt-mean-its-been-cancelled-heres-why-its-important"><strong>iOS 27 didn't add this anti-snatching feature to iPhone, but that doesn't mean it's been cancelled — here's why it's important</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20"><strong>Forget iPhone 18 Pro — 9 reasons to wait for the iPhone 20</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/google-pixel-phones/pixel-11-phones-will-soon-have-a-new-gemini-intelligence-feature-that-will-actually-make-phone-calls-on-your-behalf-and-its-exactly-what-the-introvert-in-me-wants"><strong>Pixel 11 phones will soon have a new Gemini Intelligence feature that will actually make phone calls on your behalf — and it’s exactly what the introvert in me wants</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/belkins-semi-solid-state-battery-is-the-best-portable-charger-ive-ever-used-with-my-iphone</link>
                                                                            <description>
                            <![CDATA[ Belkin's new semi-solid-state battery makes all sorts of claims about performance, but I think the lightweight design is the best thing it has to offer. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">hcY4f39LBZNwbFMHjeG9hh</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/NxK74opLZzwek9snpxooSD-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 26 Sep 2026 09:00:00 +0000</pubDate>                                                                                                                                <updated>Tue, 29 Sep 2026 13:19:53 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Google Phones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                    <category><![CDATA[Android Phones]]></category>
                                                                                                <author><![CDATA[ tom.pritchard@futurenet.com (Tom Pritchard) ]]></author>                    <dc:creator><![CDATA[ Tom Pritchard ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/biCewUkKfSA6QnT2HxVc3f-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/NxK74opLZzwek9snpxooSD-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Belkin UltraCharge Pro Magnetic Power Bank ]]></media:description>                                                            <media:text><![CDATA[Belkin UltraCharge Pro Magnetic Power Bank ]]></media:text>
                                <media:title type="plain"><![CDATA[Belkin UltraCharge Pro Magnetic Power Bank ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/NxK74opLZzwek9snpxooSD-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I'm a big fan of <a href="https://www.tomsguide.com/phones/google-pixel-phones/i-added-magsafe-support-to-my-pixel-9-pro-because-google-refused-to-heres-how">magnetic phone accessories</a>, especially when it involves MagSafe-compatible wireless charging. Portable battery packs are great, but the reliance on cables is not something I will ever be happy about. Switching to wireless charging, and using magnets to keep everything in place, means that problem is eliminated — though it's not ideal that those batteries add a bunch of bulk and weight to your phone.</p><p>Belkin's newest magnetic battery pack, <a href="https://www.belkin.com/pr-belkin-ultra-charge-pro-semi-solid-state-power-banks.html" target="_blank">UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell,</a> helps to eliminate that problem. The "Semi Solid State" battery design is significantly thinner and lighter than you might expect, which makes a surprising amount of difference for comfort. However, that also comes at the cost of overall capacity, which may or not be a dealbreaker.</p><div class="product"><a data-dimension112="df0c4ffc-b8ee-11f1-9c35-690e422548c3" data-action="Deal Block" data-label="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension48="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension25="$69" href="https://www.amazon.com/Belkin-5000mAh-Magnetic-Wireless-Charger/dp/B0HHBHL8W2" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:976px;"><p class="vanilla-image-block" style="padding-top:153.69%;"><img id="xf8bgkRQfXnV33JCG9h7jb" name="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/xf8bgkRQfXnV33JCG9h7jb-1920-80.png" mos="" align="middle" fullscreen="" width="976" height="1500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.amazon.com/Belkin-5000mAh-Magnetic-Wireless-Charger/dp/B0HHBHL8W2" target="_blank" rel="nofollow" data-dimension112="df0c4ffc-b8ee-11f1-9c35-690e422548c3" data-action="Deal Block" data-label="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension48="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension25="$69">UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell: $69</a></strong><br>Belkin's new Semi-Solid-State battery pack is thinner and lighter than any magnetic battery pack I've ever used. While the relatively low capacity might be a problem for some, it is an absolute joy to use for those reasons. It offers 15W Qi2 wireless charging on the go and built-in temperature management technology.<a class="view-deal button" href="https://www.amazon.com/Belkin-5000mAh-Magnetic-Wireless-Charger/dp/B0HHBHL8W2" target="_blank" rel="nofollow" data-dimension112="df0c4ffc-b8ee-11f1-9c35-690e422548c3" data-action="Deal Block" data-label="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension48="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension25="$69">View Deal</a></p></div><div class="product"><a data-dimension112="75474514-bc08-11f1-96dd-0d6b6fccd597" data-action="Deal Block" data-label="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension48="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension25="£60" href="https://www.amazon.co.uk/Belkin-UltraCharge-5000mAh-Semi-Solid-State-Wireless/dp/B0HFJS1LVW" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:700px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="YbjrGZMrc73eSYJGJiYC4A" name="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/YbjrGZMrc73eSYJGJiYC4A-1920-80.png" mos="" align="middle" fullscreen="" width="700" height="700" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.amazon.co.uk/Belkin-UltraCharge-5000mAh-Semi-Solid-State-Wireless/dp/B0HFJS1LVW" target="_blank" rel="nofollow" data-dimension112="75474514-bc08-11f1-96dd-0d6b6fccd597" data-action="Deal Block" data-label="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension48="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension25="£60">UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell: £60</a></strong><br>Those of you living in the U.K. can also pick up the UltraCharge Pro for £60. You can the exact same battery and specs, but with a price tag in British pounds instead of dollars.<a class="view-deal button" href="https://www.amazon.co.uk/Belkin-UltraCharge-5000mAh-Semi-Solid-State-Wireless/dp/B0HFJS1LVW" target="_blank" rel="nofollow" data-dimension112="75474514-bc08-11f1-96dd-0d6b6fccd597" data-action="Deal Block" data-label="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension48="UltraCharge Pro Slim Magnetic Power Bank with BoostSolid Cell" data-dimension25="£60">View Deal</a></p></div><h2 id="what-the-heck-is-a-39-semi-solid-state-39-battery">What the heck is a 'semi-solid-state' battery?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ZJCG4aTG8pWTGfDBEAEcTD" name="PXL_20260925_140126366" alt="Belkin UltraCharge Pro Magnetic Power Bank" src="https://cdn.mos.cms.futurecdn.net/ZJCG4aTG8pWTGfDBEAEcTD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>You may be wondering what Semi-Solid-State actually means. The idea of solid-state batteries is nothing new, since those offer power without any of the chemical movements and reactions. </p><p>According to Belkin, this "semi-solid" design utilizes a gel-like layer alongside a liquid electrolyte. The company hasn't gone into the specifics of how everything works, but the design enables a slimmer and more compact design, greater longevity and a much lower risk of overheating. That should help improve the overall safety of using these batteries, and considering the clampdown by airlines in recent months, that's definitely a good thing.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Wiq6MgcSzojNoLcpuLDeSD" name="PXL_20260925_140121879" alt="Belkin UltraCharge Pro Magnetic Power Bank" src="https://cdn.mos.cms.futurecdn.net/Wiq6MgcSzojNoLcpuLDeSD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Speaking of airlines, Belkin says that the <a href="https://www.belkin.com/p/slim-magnetic-power-bank-5k-with-boostsolid-cell/BPD024fqBK.html" target="_blank" rel="nofollow">$70 UltraCharge Pro Magnetic Power Bank</a> has been built to comply with standard safety requirements, and the TSA's carry-on guidance. Though this doesn't necessarily mean that you are cleared to use this one in the air. Each airline has their own policies, and you need to be aware of them before you travel.</p><p>The battery itself is Qi2 certified, offering up to 15W charging speeds on compatible phones. Wired USB-C charging is also available if you have a cable, with speeds up to 7.5W. The battery itself recharges at up to 22.5W. Naturally, being magnetic, it snaps onto the back of your phone — whether it has built-in magnets or you're using a special case.</p><p>Materials-wise, you've got a battery that is a mix of metal and rubber, which is not exactly uncommon in magnetic batteries, though the actual size of the thing is arguably where its biggest strength lies.</p><h2 id="how-does-it-compare-to-my-existing-magnetic-power-bank">How does it compare to my existing magnetic power bank?</h2><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="WUA5JUqSBq8jfWLwYcnjTD" name="PXL_20260925_140207588" alt="Belkin UltraCharge Pro Magnetic Power Bank" src="https://cdn.mos.cms.futurecdn.net/WUA5JUqSBq8jfWLwYcnjTD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The magnetic battery pack I use most of the time is <a href="https://www.amazon.com/UGREEN-10000mAh-Magnetic-Power-Black/dp/B0CH33F5P2/" target="_blank" rel="nofollow">UGreen's 10,000 mAh magnetic power pack</a>. It's a fairly cheap option, which means it isn't officially certified as MagSafe or Qi2 — it's just a regular wireless charger with a MagSafe-compatible connection. That means it's slow, and it has a habit of getting pretty hot.</p><p>UGreen's model is 0.79-inches thick, which is more than double Belkin's 0.35-inches. It's also heavier, weighing 7.9 ounces compared to 4.4 ounces for the Belkin. The UGreen battery is actually heavier and thicker than an iPhone 17 Pro (0.35-inches and 7.27 ounces), and only slightly lighter than the iPhone 17 Pro Max (8.33 ounces).</p><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="kDmKnRfMNrAVgVtrErPuED" name="PXL_20260925_140228651" alt="Belkin UltraCharge Pro Magnetic Power Bank" src="https://cdn.mos.cms.futurecdn.net/kDmKnRfMNrAVgVtrErPuED-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The UltraCharge Pro Magnetic Power Bank is still going to add thickness and weight to your phone. However, it is a lot more comfortable and convenient to use compared to the bulky UGreen option I've been using.</p><p>The downside is that it the Belkin has half the capacity of the UGreen. 10,000 mAh is enough to charge just about every phone at least once — and often more. 5,000 mAh doesn't go quite as far, but it's no small amount of power. It's enough to recharge a lot of phones in full, and enough to add a significant amount of power to others. </p><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="XFcqQapJ3csAzN7kapb6qC" name="PXL_20260925_140214437" alt="Belkin UltraCharge Pro Magnetic Power Bank" src="https://cdn.mos.cms.futurecdn.net/XFcqQapJ3csAzN7kapb6qC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Personally, while I like to overprepare and make sure I have more than enough energy to keep me going, I'll admit that 10,000 mAh is a bit overkill for most situations. So long as you have enough power to make it through the day, and get back to a home charger, then what does it matter how much of a reserve you have?</p><p>In terms of charging and heat, I decided to test the two batteries on my iPhone 17 Pro Max starting at 47% charge. The Belkin battery restored 10%, bringing the total to 57% in that time, while the UGreen battery brought the charge to 54% — a 7% increase. It's not a huge amount of difference, but over the course of many hours that will add up. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1900px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="cYhGhQSnQJDo6xAqrUGN5X" name="FLIR_20260925_095419_443" alt="belkin vs ugreen thermal imagery" src="https://cdn.mos.cms.futurecdn.net/cYhGhQSnQJDo6xAqrUGN5X-1920-80.jpg" mos="" align="middle" fullscreen="" width="1900" height="1069" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">Left: Belkin, Right: Ugreen </span><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>As for heat, the Belkin battery definitely felt warmer, but a quick check with a thermal camera saw the temperature peak at just under 95 degrees Fahrenheit. The UGreen battery didn't feel nearly as warm, but the thermal imaging revealed that a small part of the battery had risen to just shy of 97 degrees. That's not a huge difference, but you do have to remember that the UGreen charger is going much more slowly — and I did feel that heat start to add up over extended charging sessions.</p><p>Wireless charging is always going to produce some heat if you don't have some sort of active cooling system. The Belkin UltraCharge does get warm, but it doesn't get too hot, which is quite nice.</p><h2 id="bottom-line-3">Bottom line</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="BFGpKU627gDADg4NcbgMTD" name="PXL_20260925_140123935" alt="Belkin UltraCharge Pro Magnetic Power Bank" src="https://cdn.mos.cms.futurecdn.net/BFGpKU627gDADg4NcbgMTD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>I really like the Belkin UltraCharge Pro Magnetic Power Bank. Not specifically because it's a semi-solid-state battery, but because it manages to do all the things you need from a portable battery pack. It's slim and lightweight, with the magnetic connection making it incredibly easy to recharge your phone. Plus, the 15W Qi2 speeds mean it's fairly speedy as far as wireless charging goes.</p><p>Admittedly, the 5,000 mAh capacity would be enough to make me hesitate on buying one for myself — especially with a $70 price tag. You can buy wired battery packs that offer four times the capacity for similar prices, if not less. Still, you can't fault the Belkin for convenience or comfort, and that premium might be worth it if you regularly find that you need to top off your phone on the move.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/ios-27-didnt-add-this-anti-snatching-feature-to-iphone-but-that-doesnt-mean-its-been-cancelled-heres-why-its-important"><strong>iOS 27 didn't add this anti-snatching feature to iPhone, but that doesn't mean it's been cancelled — here's why it's important</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20"><strong>Forget iPhone 18 Pro — 9 reasons to wait for the iPhone 20</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/google-pixel-phones/pixel-11-phones-will-soon-have-a-new-gemini-intelligence-feature-that-will-actually-make-phone-calls-on-your-behalf-and-its-exactly-what-the-introvert-in-me-wants"><strong>Pixel 11 phones will soon have a new Gemini Intelligence feature that will actually make phone calls on your behalf — and it’s exactly what the introvert in me wants</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I found this hidden trick that makes Pro Controls on my iPhone 18 Pro even better — here's what it is ]]></title>
                                                                                                <dc:content><![CDATA[ <p>For the past couple of weeks, I’ve been putting all the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro</a> (and 18 Pro Max) camera upgrades to work. While the <a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">variable aperture system</a> has drawn plenty of attention — and rightfully so, given the natural depth of field it delivers — the bigger upgrade for me has been the introduction of new <a href="https://www.tomsguide.com/phones/iphones/forget-variable-aperture-the-real-upgrade-with-the-iphone-18-pro-max-is-pro-controls">Pro Controls</a>.</p><p>I can’t tell you how long I’ve been asking for this. Apple has historically been reluctant to give users full manual control, but over the last few generations, it’s slowly been rolling out incremental features that prove it's actually listening. Even so, it wasn't until recently that I stumbled onto something that takes the feature to another level: the ability to fully customize the Pro Controls layout to match your exact shooting style.</p><p>Whether you want shutter speed pinned front and center, or the focus slider positioned for precise fine-tuning, customizing this interface completely transforms the experience. Here’s how to do it.</p><h3 class="article-body__section" id="section-how-to-customize-pro-controls-layout-using-the-iphone-18-pro-pro-max"><span>How to customize Pro Controls layout using the iPhone 18 Pro/Pro Max</span></h3><section class="howto-block">                    <h3>1. Open the camera app, access Pro Controls</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/HtfQ8dZWp33brerH9GPYjD.jpg"                                        alt="iPhone 18 Pro - Pro Controls screenshots."                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/HtfQ8dZWp33brerH9GPYjD.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Future)</div></figure>                    <p><p>Customizing the Pro Controls layout to keep your favorite tools within reach is surprisingly simple. Start by <strong>opening the Camera app</strong>, then <strong>press and hold</strong> any of the control icons located on the side opposite the shutter button.</p><p>On a brand-new iPhone 18 Pro or 18 Pro Max, you’ll typically see the default icons for Live Photos and the LED flash — just long-press either one.</p></p>                </section><section class="howto-block">                    <h3>2. Make your selections</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/kbMLvfEAMvVZTikvjch5kD.jpg"                                        alt="iPhone 18 Pro - Pro Controls screenshots."                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/kbMLvfEAMvVZTikvjch5kD.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Future)</div></figure>                    <p><p>You’ll now see an <strong>Add Photo Controls</strong> overlay displaying icons for every available manual setting. You can configure anywhere from two to eight controls at a time. Once you’ve picked what you need, simply drag and drop the icons into whatever order or layout works best for your shooting. Click <strong>Done </strong>when you're finished to save the layout.</p></p>                </section><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="CnomJi87LGPQMYz3JC6Qx7" name="iPhone 18 Pro - Pro Controls" alt="iPhone 18 Pro showing Pro Controls." src="https://cdn.mos.cms.futurecdn.net/CnomJi87LGPQMYz3JC6Qx7-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>All of your selections will stay locked in the exact order you arranged them, making Pro Controls vastly more practical since you're no longer forced to constantly tap the six-dot icon to dig into settings. I love this level of customization because it gives me the flexibility to tweak key parameters on the fly, letting me refocus on framing and shooting instead of fumbling through menus.</p><p>Best of all, this layout customization carries over seamlessly to video recording. While you’ll find familiar core adjustments like aperture, shutter speed, manual focus, and white balance, Apple also adds video-specific tools like Dual Capture, Action mode, and Adaptive — the latter designed for time-lapse recording to dynamically slow the frame rate when motion is detected.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-eygyBO"></div>                            </div>                            <script src="https://kwizly.com/embed/eygyBO.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/android-phones/googles-android-president-on-apple-iphone-duo-android-is-usually-where-you-see-the-future-first"><strong>Android president on Apple's iPhone Duo: 'I'm glad to see more people joining what is now the obvious party'</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20"><strong>Forget iPhone 18 Pro — 9 reasons to wait for the iPhone 20</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/i-finally-unlinked-my-iphone-alarm-from-my-ringer-volume-here-is-where-apple-hid-it-in-ios-27"><strong>I finally unlinked my iPhone alarm from my ringer volume — here is where Apple hid it in iOS 27</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/i-found-this-hidden-trick-that-makes-pro-controls-on-my-iphone-18-pro-even-better-heres-what-it-is</link>
                                                                            <description>
                            <![CDATA[ Pro Controls are one of the exclusive features with the iPhone 18 Pro and iPhone 18 Pro Max, but this trick lets you easily customize the layout. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">QTZKJmgFnbeVMbfgSKEKXT</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/btgyTZCtsi3E7LBjv7EVcn-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 26 Sep 2026 04:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ john.velasco@futurenet.com (John Velasco) ]]></author>                    <dc:creator><![CDATA[ John Velasco ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/TSj224oX8d5ERXaDs8pDGd-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/btgyTZCtsi3E7LBjv7EVcn-1920-80.jpg">
                                                            <media:credit><![CDATA[John Velasco / Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 18 Pro showing Pro Controls.]]></media:description>                                                            <media:text><![CDATA[iPhone 18 Pro showing Pro Controls.]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 18 Pro showing Pro Controls.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/btgyTZCtsi3E7LBjv7EVcn-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>For the past couple of weeks, I’ve been putting all the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro</a> (and 18 Pro Max) camera upgrades to work. While the <a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">variable aperture system</a> has drawn plenty of attention — and rightfully so, given the natural depth of field it delivers — the bigger upgrade for me has been the introduction of new <a href="https://www.tomsguide.com/phones/iphones/forget-variable-aperture-the-real-upgrade-with-the-iphone-18-pro-max-is-pro-controls">Pro Controls</a>.</p><p>I can’t tell you how long I’ve been asking for this. Apple has historically been reluctant to give users full manual control, but over the last few generations, it’s slowly been rolling out incremental features that prove it's actually listening. Even so, it wasn't until recently that I stumbled onto something that takes the feature to another level: the ability to fully customize the Pro Controls layout to match your exact shooting style.</p><p>Whether you want shutter speed pinned front and center, or the focus slider positioned for precise fine-tuning, customizing this interface completely transforms the experience. Here’s how to do it.</p><h3 class="article-body__section" id="section-how-to-customize-pro-controls-layout-using-the-iphone-18-pro-pro-max"><span>How to customize Pro Controls layout using the iPhone 18 Pro/Pro Max</span></h3><section class="howto-block">                    <h3>1. Open the camera app, access Pro Controls</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/HtfQ8dZWp33brerH9GPYjD.jpg"                                        alt="iPhone 18 Pro - Pro Controls screenshots."                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/HtfQ8dZWp33brerH9GPYjD.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Future)</div></figure>                    <p><p>Customizing the Pro Controls layout to keep your favorite tools within reach is surprisingly simple. Start by <strong>opening the Camera app</strong>, then <strong>press and hold</strong> any of the control icons located on the side opposite the shutter button.</p><p>On a brand-new iPhone 18 Pro or 18 Pro Max, you’ll typically see the default icons for Live Photos and the LED flash — just long-press either one.</p></p>                </section><section class="howto-block">                    <h3>2. Make your selections</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/kbMLvfEAMvVZTikvjch5kD.jpg"                                        alt="iPhone 18 Pro - Pro Controls screenshots."                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/kbMLvfEAMvVZTikvjch5kD.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Future)</div></figure>                    <p><p>You’ll now see an <strong>Add Photo Controls</strong> overlay displaying icons for every available manual setting. You can configure anywhere from two to eight controls at a time. Once you’ve picked what you need, simply drag and drop the icons into whatever order or layout works best for your shooting. Click <strong>Done </strong>when you're finished to save the layout.</p></p>                </section><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="CnomJi87LGPQMYz3JC6Qx7" name="iPhone 18 Pro - Pro Controls" alt="iPhone 18 Pro showing Pro Controls." src="https://cdn.mos.cms.futurecdn.net/CnomJi87LGPQMYz3JC6Qx7-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>All of your selections will stay locked in the exact order you arranged them, making Pro Controls vastly more practical since you're no longer forced to constantly tap the six-dot icon to dig into settings. I love this level of customization because it gives me the flexibility to tweak key parameters on the fly, letting me refocus on framing and shooting instead of fumbling through menus.</p><p>Best of all, this layout customization carries over seamlessly to video recording. While you’ll find familiar core adjustments like aperture, shutter speed, manual focus, and white balance, Apple also adds video-specific tools like Dual Capture, Action mode, and Adaptive — the latter designed for time-lapse recording to dynamically slow the frame rate when motion is detected.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-eygyBO"></div>                            </div>                            <script src="https://kwizly.com/embed/eygyBO.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/android-phones/googles-android-president-on-apple-iphone-duo-android-is-usually-where-you-see-the-future-first"><strong>Android president on Apple's iPhone Duo: 'I'm glad to see more people joining what is now the obvious party'</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20"><strong>Forget iPhone 18 Pro — 9 reasons to wait for the iPhone 20</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/i-finally-unlinked-my-iphone-alarm-from-my-ringer-volume-here-is-where-apple-hid-it-in-ios-27"><strong>I finally unlinked my iPhone alarm from my ringer volume — here is where Apple hid it in iOS 27</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ iOS 27 didn't add this anti-snatching feature to iPhone, but that doesn't mean it's been cancelled — here's why it's important ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Back in March we heard rumors that <a href="https://www.tomsguide.com/phones/iphones/the-iphone-could-steal-one-of-the-best-android-features-and-im-all-for-it">Apple could add an important anti-theft feature to iPhones</a>: the ability for iOS to lock everything down in the event your phone is snatched out of your hands. While I had hoped that such a feature could launch with iOS 27, that hasn't happened — but it doesn't mean anti-snatch protection is dead in the water.</p><p>Code discovered in the newly released<a href="https://www.tomsguide.com/phones/iphones/ios-27-2-beta-is-here-5-biggest-upgrades-for-your-iphone-including-a-revamped-health-app"> iOS 27.2 beta</a> reveals that Apple<a href="https://9to5mac.com/2026/09/21/ios-27-2-beta-2-reveals-new-details-about-unnanounced-iphone-anti-snatching-feature/" target="_blank"> could still be working</a> on this feature — as well as what signals could end up triggering it in the real world.</p><p>Google launched something similar last year, <a href="https://www.tomsguide.com/phones/android-phones/android-just-got-a-trio-of-powerful-anti-theft-upgrades-heres-how-they-work">known as Theft Detection Lock</a>, and I'm glad to see that Apple is still powering ahead with its own version. Considering how much we have on our phone, and how easy they are to steal, there's no such thing as having too much protection from thieves and other criminals.</p><h2 id="how-apple-39-s-anti-snatching-feature-might-work">How Apple's anti-snatching feature might work</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="MkwV9aEEchURoBBVdNhcse" name="iPhone 18 Pro and Pro Max-5" alt="Apple iPhone 18 Pro Max" src="https://cdn.mos.cms.futurecdn.net/MkwV9aEEchURoBBVdNhcse-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Android's Theft Detection Lock works by detecting sudden changes in your device, using the internal sensors. So if it notices your phone suddenly jerks in one direction and takes off at speed, odds are someone has snatched your phone and started running off with it.</p><p>We assumed that Apple's version would work in a similar manner, but the uncovered code offers a little bit of detail about how iOS will register possible thefts.</p><p>Code snippets seen b<a href="https://9to5mac.com/2026/09/21/ios-27-2-beta-2-reveals-new-details-about-unnanounced-iphone-anti-snatching-feature/" target="_blank">y 9to5Mac</a> shows that the theft detection is internally known as "AutoLock," though there's no guarantee that Apple will actually use that name for the public launch. The code also suggests that AutoLock will rely on five key signals to determine whether a phone has been stolen or not.</p><p>The first trigger is the presence of a "sharp acceleration" that is "consistent with a phone being snatched." Or, in other words, the internal sensors detecting your phone moving in a way that is inconsistent with typical use. Connectivity to the Apple Watch is also considered, including a paired watch not being reachable for an extended period, and general loss of connectivity to that watch. Presumably if that loss of contact is very sudden, then the AutoLock feature will realize something is up. </p><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="ZhVLRJCFGxVjGeDa3TaWmK" name="iPhone 18 Pro and Pro Max-LIST3" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/ZhVLRJCFGxVjGeDa3TaWmK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The code also refers to being disconnected from the network for extended periods. This would be consistent with thieves switching a phone into Airplane mode in an attempt to evade Find My Device — either for tracking or remotely locking down the phone.</p><p>Finally it's said that AutoLock could engage when a device has been unlocked beyond a specific time interval. This suggests that there may be circumstances where AutoLock can engage after being snatched, rather than during the process — the way Android's version of the feature does. </p><p>The code also makes reference to safeguards designed to avoid false positives, including location-based systems that would prevent AutoLock engaging in familiar locations like home ort work — similar to how Apple's Stolen Device Protection works. Other safeguards mention a veto system, in which certain features can override a request to AutoLock, biometric authentication, and a "backoff mechanism" that temporarily prevents automatic locks after repeated AutoLock events.</p><p>Naturally, this feature is still a work in progress, and that means things can (and likely will) change between now and the official release. So don't expect the final feature to arrive in this exact form, whenever that day might actually be.</p><h2 id="why-it-39-s-important-to-have">Why it's important to have</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:800px;"><p class="vanilla-image-block" style="padding-top:56.38%;"><img id="VPuL7vHqvy6jxRAx7DGCa5" name="ezgif-3cd59d6018ef1adf" alt="android theft detection lock in action" src="https://cdn.mos.cms.futurecdn.net/VPuL7vHqvy6jxRAx7DGCa5-1920-80.gif" mos="" align="middle" fullscreen="" width="800" height="451" attribution="" endorsement="" 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 doubt there's anyone reading this that hasn't heard about phone snatching, and many of you may have experienced it first hand. It's become quite a problem, especially in big cities and places with lax enforcement of rules regarding ebikes and mopeds.</p><p>It certainly doesn't help that we use our phones so much, and some people tend to wander around with their phones out, oblivious to the fact that they're putting their device at risk. Last time my wife and I both went to London, I repeatedly had to tell her to put her phone away because she has the awful habit of absentmindedly wandering around with her phone by her side. It's a problem made worse by the fact it's so hard to find women's clothing with phone-friendly pockets. </p><p>Really, we should know to keep our phones more secure. Not only are they expensive devices, the amount of data we keep in them is arguably worth more than the hardware itself. Banking apps, social media, personal photos and videos, the list is endless. The last thing you need is for someone to snatch your phone and gain access to all that data, simply because your phone was unlocked at the wrong moment.</p><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="FEW6JLUCgz8R9HCaQNPqoK" name="iPhone 18 Pro and Pro Max-13" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/FEW6JLUCgz8R9HCaQNPqoK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Obviously staying vigilant, and ensuring your phone is not exposed unnecessarily is always going to be the best way to avoid drive-by phone snatching. But it's foolish to assume that you can stay safe 100% of the time, and there will be points where you need to use your phone and your guard is down just enough for an opportunistic thief to swoop by and grab it from your hands.</p><p>Having a system that locks your phone down means it's that bit harder for a thief to access your data, or attempt to wipe the phone and sell it on for a profit. Crucially it gives you a little more time to find a way to get into Find My Device and lock the device down — significantly reducing its value to the potential thieves.</p><p>AutoLock wouldn't be the only system helping to safeguard your data. Stolen Device Protection has measures to stop potential thieves from accessing key areas of your device — including Find My settings, your Apple account and factory reset. Most importantly, it also works if the thief knows your PIN, since it relies on biometric security. Apple also forces your iPhone to <a href="https://www.tomsguide.com/phones/iphones/ios-18-will-force-your-iphone-to-reboot-after-3-days-heres-why-that-matters"><u>restart after 72 hours of inactivity</u></a>, which encrypts your device and makes it even harder for thieves to try and break in.</p><p>Replacing a phone sucks, especially if it isn't covered by AppleCare+ or some other form of insurance. But the cost of a new phone pales in comparison to the cost of losing control of your accounts and data.</p><h2 id="bottom-line-4">Bottom line</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3858px;"><p class="vanilla-image-block" style="padding-top:52.57%;"><img id="D8JHojF7g6q5yQJozcyjDN" name="shutterstock_2746260993" alt="iOS 27 features" src="https://cdn.mos.cms.futurecdn.net/D8JHojF7g6q5yQJozcyjDN-1920-80.jpg" mos="" align="middle" fullscreen="" width="3858" height="2028" 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>It's important to keep tabs on your phone, no matter where you are or how secure you might feel in the moment. Constant vigilance is a nice idea in theory, but it's not realistically possible. For that reason, it's great that phone companies are continually adding features to keep your devices secure, and lock everything down in the event that your phone is stolen.</p><p>I'm mainly an Android user, and I've lost track of the number of times I've looked at my phone and been met with a notification telling me the screen has auto-locked because it thought someone was stealing it. Some may find that slightly irritating, but not me. Considering how easy it is to unlock a smartphone with biometrics (be it a fingerprint or Face ID), I'd rather the software be a little more cautious and ask me to unlock my phone again than face the alternative. </p><p>And the sooner Apple implements that feature on iPhones, the better.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><a href="https://www.tomsguide.com/phones/android-phones/googles-android-president-on-apple-iphone-duo-android-is-usually-where-you-see-the-future-first">Android president on Apple's iPhone Duo: 'I'm glad to see more people joining what is now the obvious party'</a></li><li><a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20">Forget iPhone 18 Pro — 9 reasons to wait for the iPhone 20</a></li><li><a href="https://www.tomsguide.com/phones/i-finally-unlinked-my-iphone-alarm-from-my-ringer-volume-here-is-where-apple-hid-it-in-ios-27">I finally unlinked my iPhone alarm from my ringer volume — here is where Apple hid it in iOS 27</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/ios-27-didnt-add-this-anti-snatching-feature-to-iphone-but-that-doesnt-mean-its-been-cancelled-heres-why-its-important</link>
                                                                            <description>
                            <![CDATA[ Apple seems to be still working on its own version of Android's anti-snatching feature, and the sooner it launches on iOS, the better. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">CQti3CRxTjVk7rprY2Go64</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/473VNvCMPfhDkYKpe3aJjK-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 24 Sep 2026 05:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ tom.pritchard@futurenet.com (Tom Pritchard) ]]></author>                    <dc:creator><![CDATA[ Tom Pritchard ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/biCewUkKfSA6QnT2HxVc3f-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/473VNvCMPfhDkYKpe3aJjK-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Apple iPhone 18 Pro and Pro Max shown in hand]]></media:description>                                                            <media:text><![CDATA[Apple iPhone 18 Pro and Pro Max shown in hand]]></media:text>
                                <media:title type="plain"><![CDATA[Apple iPhone 18 Pro and Pro Max shown in hand]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/473VNvCMPfhDkYKpe3aJjK-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Back in March we heard rumors that <a href="https://www.tomsguide.com/phones/iphones/the-iphone-could-steal-one-of-the-best-android-features-and-im-all-for-it">Apple could add an important anti-theft feature to iPhones</a>: the ability for iOS to lock everything down in the event your phone is snatched out of your hands. While I had hoped that such a feature could launch with iOS 27, that hasn't happened — but it doesn't mean anti-snatch protection is dead in the water.</p><p>Code discovered in the newly released<a href="https://www.tomsguide.com/phones/iphones/ios-27-2-beta-is-here-5-biggest-upgrades-for-your-iphone-including-a-revamped-health-app"> iOS 27.2 beta</a> reveals that Apple<a href="https://9to5mac.com/2026/09/21/ios-27-2-beta-2-reveals-new-details-about-unnanounced-iphone-anti-snatching-feature/" target="_blank"> could still be working</a> on this feature — as well as what signals could end up triggering it in the real world.</p><p>Google launched something similar last year, <a href="https://www.tomsguide.com/phones/android-phones/android-just-got-a-trio-of-powerful-anti-theft-upgrades-heres-how-they-work">known as Theft Detection Lock</a>, and I'm glad to see that Apple is still powering ahead with its own version. Considering how much we have on our phone, and how easy they are to steal, there's no such thing as having too much protection from thieves and other criminals.</p><h2 id="how-apple-39-s-anti-snatching-feature-might-work">How Apple's anti-snatching feature might work</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="MkwV9aEEchURoBBVdNhcse" name="iPhone 18 Pro and Pro Max-5" alt="Apple iPhone 18 Pro Max" src="https://cdn.mos.cms.futurecdn.net/MkwV9aEEchURoBBVdNhcse-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Android's Theft Detection Lock works by detecting sudden changes in your device, using the internal sensors. So if it notices your phone suddenly jerks in one direction and takes off at speed, odds are someone has snatched your phone and started running off with it.</p><p>We assumed that Apple's version would work in a similar manner, but the uncovered code offers a little bit of detail about how iOS will register possible thefts.</p><p>Code snippets seen b<a href="https://9to5mac.com/2026/09/21/ios-27-2-beta-2-reveals-new-details-about-unnanounced-iphone-anti-snatching-feature/" target="_blank">y 9to5Mac</a> shows that the theft detection is internally known as "AutoLock," though there's no guarantee that Apple will actually use that name for the public launch. The code also suggests that AutoLock will rely on five key signals to determine whether a phone has been stolen or not.</p><p>The first trigger is the presence of a "sharp acceleration" that is "consistent with a phone being snatched." Or, in other words, the internal sensors detecting your phone moving in a way that is inconsistent with typical use. Connectivity to the Apple Watch is also considered, including a paired watch not being reachable for an extended period, and general loss of connectivity to that watch. Presumably if that loss of contact is very sudden, then the AutoLock feature will realize something is up. </p><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="ZhVLRJCFGxVjGeDa3TaWmK" name="iPhone 18 Pro and Pro Max-LIST3" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/ZhVLRJCFGxVjGeDa3TaWmK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The code also refers to being disconnected from the network for extended periods. This would be consistent with thieves switching a phone into Airplane mode in an attempt to evade Find My Device — either for tracking or remotely locking down the phone.</p><p>Finally it's said that AutoLock could engage when a device has been unlocked beyond a specific time interval. This suggests that there may be circumstances where AutoLock can engage after being snatched, rather than during the process — the way Android's version of the feature does. </p><p>The code also makes reference to safeguards designed to avoid false positives, including location-based systems that would prevent AutoLock engaging in familiar locations like home ort work — similar to how Apple's Stolen Device Protection works. Other safeguards mention a veto system, in which certain features can override a request to AutoLock, biometric authentication, and a "backoff mechanism" that temporarily prevents automatic locks after repeated AutoLock events.</p><p>Naturally, this feature is still a work in progress, and that means things can (and likely will) change between now and the official release. So don't expect the final feature to arrive in this exact form, whenever that day might actually be.</p><h2 id="why-it-39-s-important-to-have">Why it's important to have</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:800px;"><p class="vanilla-image-block" style="padding-top:56.38%;"><img id="VPuL7vHqvy6jxRAx7DGCa5" name="ezgif-3cd59d6018ef1adf" alt="android theft detection lock in action" src="https://cdn.mos.cms.futurecdn.net/VPuL7vHqvy6jxRAx7DGCa5-1920-80.gif" mos="" align="middle" fullscreen="" width="800" height="451" attribution="" endorsement="" 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 doubt there's anyone reading this that hasn't heard about phone snatching, and many of you may have experienced it first hand. It's become quite a problem, especially in big cities and places with lax enforcement of rules regarding ebikes and mopeds.</p><p>It certainly doesn't help that we use our phones so much, and some people tend to wander around with their phones out, oblivious to the fact that they're putting their device at risk. Last time my wife and I both went to London, I repeatedly had to tell her to put her phone away because she has the awful habit of absentmindedly wandering around with her phone by her side. It's a problem made worse by the fact it's so hard to find women's clothing with phone-friendly pockets. </p><p>Really, we should know to keep our phones more secure. Not only are they expensive devices, the amount of data we keep in them is arguably worth more than the hardware itself. Banking apps, social media, personal photos and videos, the list is endless. The last thing you need is for someone to snatch your phone and gain access to all that data, simply because your phone was unlocked at the wrong moment.</p><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="FEW6JLUCgz8R9HCaQNPqoK" name="iPhone 18 Pro and Pro Max-13" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/FEW6JLUCgz8R9HCaQNPqoK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Obviously staying vigilant, and ensuring your phone is not exposed unnecessarily is always going to be the best way to avoid drive-by phone snatching. But it's foolish to assume that you can stay safe 100% of the time, and there will be points where you need to use your phone and your guard is down just enough for an opportunistic thief to swoop by and grab it from your hands.</p><p>Having a system that locks your phone down means it's that bit harder for a thief to access your data, or attempt to wipe the phone and sell it on for a profit. Crucially it gives you a little more time to find a way to get into Find My Device and lock the device down — significantly reducing its value to the potential thieves.</p><p>AutoLock wouldn't be the only system helping to safeguard your data. Stolen Device Protection has measures to stop potential thieves from accessing key areas of your device — including Find My settings, your Apple account and factory reset. Most importantly, it also works if the thief knows your PIN, since it relies on biometric security. Apple also forces your iPhone to <a href="https://www.tomsguide.com/phones/iphones/ios-18-will-force-your-iphone-to-reboot-after-3-days-heres-why-that-matters"><u>restart after 72 hours of inactivity</u></a>, which encrypts your device and makes it even harder for thieves to try and break in.</p><p>Replacing a phone sucks, especially if it isn't covered by AppleCare+ or some other form of insurance. But the cost of a new phone pales in comparison to the cost of losing control of your accounts and data.</p><h2 id="bottom-line-4">Bottom line</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3858px;"><p class="vanilla-image-block" style="padding-top:52.57%;"><img id="D8JHojF7g6q5yQJozcyjDN" name="shutterstock_2746260993" alt="iOS 27 features" src="https://cdn.mos.cms.futurecdn.net/D8JHojF7g6q5yQJozcyjDN-1920-80.jpg" mos="" align="middle" fullscreen="" width="3858" height="2028" 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>It's important to keep tabs on your phone, no matter where you are or how secure you might feel in the moment. Constant vigilance is a nice idea in theory, but it's not realistically possible. For that reason, it's great that phone companies are continually adding features to keep your devices secure, and lock everything down in the event that your phone is stolen.</p><p>I'm mainly an Android user, and I've lost track of the number of times I've looked at my phone and been met with a notification telling me the screen has auto-locked because it thought someone was stealing it. Some may find that slightly irritating, but not me. Considering how easy it is to unlock a smartphone with biometrics (be it a fingerprint or Face ID), I'd rather the software be a little more cautious and ask me to unlock my phone again than face the alternative. </p><p>And the sooner Apple implements that feature on iPhones, the better.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><a href="https://www.tomsguide.com/phones/android-phones/googles-android-president-on-apple-iphone-duo-android-is-usually-where-you-see-the-future-first">Android president on Apple's iPhone Duo: 'I'm glad to see more people joining what is now the obvious party'</a></li><li><a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20">Forget iPhone 18 Pro — 9 reasons to wait for the iPhone 20</a></li><li><a href="https://www.tomsguide.com/phones/i-finally-unlinked-my-iphone-alarm-from-my-ringer-volume-here-is-where-apple-hid-it-in-ios-27">I finally unlinked my iPhone alarm from my ringer volume — here is where Apple hid it in iOS 27</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Forget iPhone 18 Pro — 9 reasons to wait for the iPhone 20 ]]></title>
                                                                                                <dc:content><![CDATA[ <p>The<a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review"> iPhone 18 Pro and 18 Pro Max </a>are definitely the best phones Apple has ever made, but that doesn't necessarily mean you should rush out to buy one. In fact, there's a strong case to be made for waiting another year and picking up the <a href="https://www.tomsguide.com/phones/iphones/new-iphone-20-video-reveals-the-8-biggest-upgrades-to-expect-from-the-20th-anniversary-iphone">iPhone 20</a> instead.</p><p>The 20th anniversary model is expected to follow in the iPhone X's footsteps, with Apple reportedly releasing a device that will set the standard for the next decade of iPhone flagships. This means if you've found yourself disappointed with the level of upgrades Apple has offered over the past few years, the iPhone 20 could make up for a lot of it.</p><p>Here are nine reasons why you should skip the iPhone 18 Pro and wait for the iPhone 20.</p><h3 class="article-body__section" id="section-quad-curved-all-glass-display"><span>Quad-curved, all-glass display</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1355px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="66rdtKsZd3eqsFETAE5tiM" name="Screenshot 2025-08-11 150943" alt="iphone all glass design patent, possibly iphone 20 like design" src="https://cdn.mos.cms.futurecdn.net/66rdtKsZd3eqsFETAE5tiM-1920-80.png" mos="" align="middle" fullscreen="" width="1355" height="762" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The most noticeable iPhone 20 change is shaping up to be the <a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-iphone-20-tipped-to-get-apples-biggest-screen-upgrade-ever">quad-curved all-glass display</a>. While a screen with four curved edges is fairly common among Chinese brands, it never really took off in the U.S. and other regions. However, Apple's version is a little different.</p><p>The design reportedly wraps around all four corners, connecting with a separate glass back-plate to give the illusion that this device is made from nothing but glass. Obviously, the interior will still have the usual metal frame and other components, but it should ensure the iPhone 20 is one of the most visually striking phones Apple has made in a while.</p><h3 class="article-body__section" id="section-better-oled-screens"><span>Better OLED screens</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="SyKqWzPHHsm9QoPfYUnKqK" name="iPhone 18 Pro and Pro Max-16" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/SyKqWzPHHsm9QoPfYUnKqK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The iPhone 20's design may not be the only thing changing about the screen. Apple is rumored to be offering <a href="https://www.etnews.com/20250919000194https://www.tomsguide.com/phones/iphones/iphone-20-leaks-are-here-and-apple-may-be-planning-a-dramatic-redesign-unlike-anything-weve-seen-before">new OLED display panels</a> that are brighter and thinner than what we have now. The panels themselves are expected to come from Samsung, complete with the Color Filter on Encapsulation (COE, not to be confused with the Church of England) technology. </p><p>This tech is said to be able to reduce the thickness of the display itself, while also allowing more light through. This improves the overall brightness, but in a way that doesn't increase the power consumption. Considering how much battery power a phone display can use, this could potentially be a massive win for battery life.</p><h3 class="article-body__section" id="section-under-display-face-id-and-cameras"><span>Under display Face ID and cameras</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="XALHQfMSz6kMiVmo75Cbwe" name="shutterstock_2593361461" alt="woman holding an iphone that she's unlocking with face id" src="https://cdn.mos.cms.futurecdn.net/XALHQfMSz6kMiVmo75Cbwe-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Pranav Kukreja / Shutterstock)</span></figcaption></figure><p>We know Apple can make under-display cameras, since it's added that technology to the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo's</a> foldable display. One of the long-standing rumors for the iPhone 20 is that both the camera and Face ID will vanish beneath the display, <a href="https://www.tomsguide.com/phones/iphones/apples-20th-anniversary-iphone-could-use-this-breakthrough-camera-tech">offering a true, uninterrupted display</a> — though the Dynamic Island may still stick around.</p><p>Face ID hardware has slowly been making that migration for a few years, and it makes sense Apple would be ready to make the jump next year. The camera is a different matter, especially with under-display cameras' reputation for mediocre quality. Even the iPhone Duo's hidden camera is only designed for FaceTime and video calls, and it's unclear whether Apple can fix that issue before next year.</p><h3 class="article-body__section" id="section-solid-state-buttons"><span>Solid state buttons</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="taYqbXicKNonvyYk6rYnwA" name="iPhone 16 Pro Max Camera Control button" alt="Closeup of iPhone 16 Pro Max Camera Control button." src="https://cdn.mos.cms.futurecdn.net/taYqbXicKNonvyYk6rYnwA-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>There have been rumors circulating about Apple switching from mechanical to solid-state buttons for years, and <a href="https://www.tomsguide.com/phones/iphones/no-more-buttons-iphone-20-design-just-leaked">iPhone 20 could be the year it finally happens.</a> Such a move would see traditional buttons replaced with haptic alternatives that are built directly into the device itself — which would aid that uninterrupted glass look. </p><p>Those buttons would not have any moving parts, which has two benefits. Fewer chances to break down, and fewer gaps in the frame that could be damaged and invite water or dust inside the phone. All while retaining a tactile button-like response from the built-in haptic feedback.</p><h3 class="article-body__section" id="section-a21-pro"><span>A21 Pro</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:2321px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="36uFQPaegizL2WM4jr82pH" name="iPhone 18 Pro and Pro Max-18" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/36uFQPaegizL2WM4jr82pH-1920-80.jpg" mos="" align="middle" fullscreen="" width="2321" height="1306" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>One thing we can all but guarantee is the inclusion of the A21 Pro chipset. As is the case with new Apple chips, this will likely come with increased computing and graphical performance, alongside gains in AI processing. </p><p>The level of improvement isn't clear right now, but we should expect the iPhone 20 to be the most powerful iPhone Apple has made — and among the most powerful phones on sale. Naturally, we should also expect improvements to power consumption and energy efficiency, which should in turn improve the overall battery life.</p><h3 class="article-body__section" id="section-no-qualcomm-modems-in-sight"><span>No Qualcomm modems in sight</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:55.90%;"><img id="RGR7aTDxA4Cy9XHN2hQM3A" name="Screenshot 2026-09-21 114745" alt="iphone 18 pro teardowns" src="https://cdn.mos.cms.futurecdn.net/RGR7aTDxA4Cy9XHN2hQM3A-1920-80.png" mos="" align="middle" fullscreen="" width="2560" height="1431" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: iFixit)</span></figcaption></figure><p>While Apple was keen to hype up the addition of the C2 modem in the iPhone 18 Pro series, it turns out that Qualcomm modems are still being utilized.<a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-teardown-reveals-the-ins-and-outs-of-the-latest-iphone-models-including-one-annoying-repair-issue"> iFixit teardowns revealed that the iPhone 18 Pro Max still uses a Qualcomm modem</a>, and they have a reputation for being a little power-hungry.</p><p>The reason Apple hasn't ditched Qualcomm in its entirety is all very legal. Suffice it to say Apple was obligated to continue using some Qualcomm modems in its devices until this year. As far as we know, the end of 2026 means Apple is free to use its own modems across the entire iPhone lineup — including iPhone 20. </p><h3 class="article-body__section" id="section-silicon-carbon-batteries"><span>Silicon carbon batteries</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.21%;"><img id="4ALsrPjxc7ma3q24FGt74K" name="iPhone 18 Pro and Pro Max-LIST1" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/4ALsrPjxc7ma3q24FGt74K-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1439" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>More and more phones are adopting Silicon Carbon battery technology, and the iPhone 20 could be the first Apple smartphone to make the switch. These batteries use a silicon-coated anode and are able to offer much better energy density as a result. Effectively meaning Apple can reduce the size of the iPhone 20 battery without lowering the actual capacity in the process.</p><p><a href="https://www.tomsguide.com/phones/oneplus-phones/oneplus-15-review">OnePlus 15</a> did this with its monster 7,300 mAh battery, without adding any meaningful amount of weight or thickness to the phone. Samsung did it with the <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-review-wide-for-the-win">Galaxy Z Fold 8</a> too, increasing the total battery capacity while maintaining a sleek, thin foldable profile. So there's little reason for Apple not to follow suit.</p><h3 class="article-body__section" id="section-better-cameras"><span>Better cameras</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="473VNvCMPfhDkYKpe3aJjK" name="iPhone 18 Pro and Pro Max-12" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/473VNvCMPfhDkYKpe3aJjK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Apple could be <a href="https://www.tomsguide.com/news/apple-could-revolutionize-the-iphones-camera-with-this-groundbreaking-change">developing a stacked image sensor</a> for the iPhone 20's cameras, effectively replacing the Sony sensors iPhones have relied on for years. The benefit of this is that the camera would be able to capture even more detail in bright and darker areas, without losing any information in the process. In other words, better picture quality and dynamic range rolled into one.</p><p>It's also been rumored that Apple may copy Samsung and <a href="https://www.tomsguide.com/phones/iphones/future-iphones-could-pack-a-200mp-camera-heres-what-that-means-for-you">adopt a 200MP main camera</a> on the iPhone 20 — up from 48MP on the iPhone 18 Pro and Pro Max. It seems like quite a big leap, especially since Apple generally focuses on improving photography software, but if it's going to happen, it might as well be on the iPhone 20.</p><h3 class="article-body__section" id="section-new-screen-sizes"><span>New screen sizes</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4edCqgzDe6Geozici7QFqK" name="iPhone 18 Pro and Pro Max-14" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/4edCqgzDe6Geozici7QFqK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The all-glass displays also mean the iPhone 20 could come with slightly larger screens. A recent rumor from <a href="https://weibo.com/6048569942/Rj6MNs5hS" target="_blank">Digital Chat Station</a> claims that the iPhone 20 Pro will feature a 6.41-inch display, and the Pro Max model will have a 6.96-inch display. That's up from a respective 6.3 inches and 6.9 inches on the iPhone 18 Pro and Pro Max. </p><p>Both new phones are rumored to come with resolutions of 2,686 x 1,236 and 2,912 x 1,340 — suggesting that they will be incrementally taller and wider as a result of the larger screen. Not by much, but that extra screen space has to come from somewhere, right?</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/i-put-the-iphone-18-pro-max-vs-iphone-17-pro-max-through-a-7-round-face-off-heres-the-winner">I put the iPhone 18 Pro Max vs. iPhone 17 Pro Max through a 7-round face-off — here’s the winner</a></li><li><a href="https://www.tomsguide.com/phones/i-finally-unlinked-my-iphone-alarm-from-my-ringer-volume-here-is-where-apple-hid-it-in-ios-27">I finally unlinked my iPhone alarm from my ringer volume — here is where Apple hid it in iOS 27</a></li><li><a href="https://www.tomsguide.com/phones/android-phones/snapdragon-8-elite-gen-6-benchmark-test-results-hands-on-vs-a20-pro-iphone-18-pro">I tested Snapdragon 8 Elite Extreme Gen 6 — 16% faster CPU and huge AI-infused gaming upgrades, but Apple’s A20 Pro pulls ahead in some areas</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20</link>
                                                                            <description>
                            <![CDATA[ iPhone 20 is coming next year, and it has a bunch of upgrades that make it much more exciting than the iPhone 18 Pro. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">ZhnWVa9oceoVF9jwgpFodc</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/FdNNYSWsV5M3LW8bs4GeuY-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 23 Sep 2026 11:25:05 +0000</pubDate>                                                                                                                                <updated>Wed, 23 Sep 2026 17:40:27 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ tom.pritchard@futurenet.com (Tom Pritchard) ]]></author>                    <dc:creator><![CDATA[ Tom Pritchard ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/biCewUkKfSA6QnT2HxVc3f-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/FdNNYSWsV5M3LW8bs4GeuY-1920-80.jpg">
                                                            <media:credit><![CDATA[Ice Universe/X]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 20 render ]]></media:description>                                                            <media:text><![CDATA[iPhone 20 render ]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 20 render ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/FdNNYSWsV5M3LW8bs4GeuY-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The<a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review"> iPhone 18 Pro and 18 Pro Max </a>are definitely the best phones Apple has ever made, but that doesn't necessarily mean you should rush out to buy one. In fact, there's a strong case to be made for waiting another year and picking up the <a href="https://www.tomsguide.com/phones/iphones/new-iphone-20-video-reveals-the-8-biggest-upgrades-to-expect-from-the-20th-anniversary-iphone">iPhone 20</a> instead.</p><p>The 20th anniversary model is expected to follow in the iPhone X's footsteps, with Apple reportedly releasing a device that will set the standard for the next decade of iPhone flagships. This means if you've found yourself disappointed with the level of upgrades Apple has offered over the past few years, the iPhone 20 could make up for a lot of it.</p><p>Here are nine reasons why you should skip the iPhone 18 Pro and wait for the iPhone 20.</p><h3 class="article-body__section" id="section-quad-curved-all-glass-display"><span>Quad-curved, all-glass display</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1355px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="66rdtKsZd3eqsFETAE5tiM" name="Screenshot 2025-08-11 150943" alt="iphone all glass design patent, possibly iphone 20 like design" src="https://cdn.mos.cms.futurecdn.net/66rdtKsZd3eqsFETAE5tiM-1920-80.png" mos="" align="middle" fullscreen="" width="1355" height="762" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The most noticeable iPhone 20 change is shaping up to be the <a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-iphone-20-tipped-to-get-apples-biggest-screen-upgrade-ever">quad-curved all-glass display</a>. While a screen with four curved edges is fairly common among Chinese brands, it never really took off in the U.S. and other regions. However, Apple's version is a little different.</p><p>The design reportedly wraps around all four corners, connecting with a separate glass back-plate to give the illusion that this device is made from nothing but glass. Obviously, the interior will still have the usual metal frame and other components, but it should ensure the iPhone 20 is one of the most visually striking phones Apple has made in a while.</p><h3 class="article-body__section" id="section-better-oled-screens"><span>Better OLED screens</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="SyKqWzPHHsm9QoPfYUnKqK" name="iPhone 18 Pro and Pro Max-16" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/SyKqWzPHHsm9QoPfYUnKqK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The iPhone 20's design may not be the only thing changing about the screen. Apple is rumored to be offering <a href="https://www.etnews.com/20250919000194https://www.tomsguide.com/phones/iphones/iphone-20-leaks-are-here-and-apple-may-be-planning-a-dramatic-redesign-unlike-anything-weve-seen-before">new OLED display panels</a> that are brighter and thinner than what we have now. The panels themselves are expected to come from Samsung, complete with the Color Filter on Encapsulation (COE, not to be confused with the Church of England) technology. </p><p>This tech is said to be able to reduce the thickness of the display itself, while also allowing more light through. This improves the overall brightness, but in a way that doesn't increase the power consumption. Considering how much battery power a phone display can use, this could potentially be a massive win for battery life.</p><h3 class="article-body__section" id="section-under-display-face-id-and-cameras"><span>Under display Face ID and cameras</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="XALHQfMSz6kMiVmo75Cbwe" name="shutterstock_2593361461" alt="woman holding an iphone that she's unlocking with face id" src="https://cdn.mos.cms.futurecdn.net/XALHQfMSz6kMiVmo75Cbwe-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Pranav Kukreja / Shutterstock)</span></figcaption></figure><p>We know Apple can make under-display cameras, since it's added that technology to the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo's</a> foldable display. One of the long-standing rumors for the iPhone 20 is that both the camera and Face ID will vanish beneath the display, <a href="https://www.tomsguide.com/phones/iphones/apples-20th-anniversary-iphone-could-use-this-breakthrough-camera-tech">offering a true, uninterrupted display</a> — though the Dynamic Island may still stick around.</p><p>Face ID hardware has slowly been making that migration for a few years, and it makes sense Apple would be ready to make the jump next year. The camera is a different matter, especially with under-display cameras' reputation for mediocre quality. Even the iPhone Duo's hidden camera is only designed for FaceTime and video calls, and it's unclear whether Apple can fix that issue before next year.</p><h3 class="article-body__section" id="section-solid-state-buttons"><span>Solid state buttons</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="taYqbXicKNonvyYk6rYnwA" name="iPhone 16 Pro Max Camera Control button" alt="Closeup of iPhone 16 Pro Max Camera Control button." src="https://cdn.mos.cms.futurecdn.net/taYqbXicKNonvyYk6rYnwA-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>There have been rumors circulating about Apple switching from mechanical to solid-state buttons for years, and <a href="https://www.tomsguide.com/phones/iphones/no-more-buttons-iphone-20-design-just-leaked">iPhone 20 could be the year it finally happens.</a> Such a move would see traditional buttons replaced with haptic alternatives that are built directly into the device itself — which would aid that uninterrupted glass look. </p><p>Those buttons would not have any moving parts, which has two benefits. Fewer chances to break down, and fewer gaps in the frame that could be damaged and invite water or dust inside the phone. All while retaining a tactile button-like response from the built-in haptic feedback.</p><h3 class="article-body__section" id="section-a21-pro"><span>A21 Pro</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:2321px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="36uFQPaegizL2WM4jr82pH" name="iPhone 18 Pro and Pro Max-18" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/36uFQPaegizL2WM4jr82pH-1920-80.jpg" mos="" align="middle" fullscreen="" width="2321" height="1306" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>One thing we can all but guarantee is the inclusion of the A21 Pro chipset. As is the case with new Apple chips, this will likely come with increased computing and graphical performance, alongside gains in AI processing. </p><p>The level of improvement isn't clear right now, but we should expect the iPhone 20 to be the most powerful iPhone Apple has made — and among the most powerful phones on sale. Naturally, we should also expect improvements to power consumption and energy efficiency, which should in turn improve the overall battery life.</p><h3 class="article-body__section" id="section-no-qualcomm-modems-in-sight"><span>No Qualcomm modems in sight</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:55.90%;"><img id="RGR7aTDxA4Cy9XHN2hQM3A" name="Screenshot 2026-09-21 114745" alt="iphone 18 pro teardowns" src="https://cdn.mos.cms.futurecdn.net/RGR7aTDxA4Cy9XHN2hQM3A-1920-80.png" mos="" align="middle" fullscreen="" width="2560" height="1431" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: iFixit)</span></figcaption></figure><p>While Apple was keen to hype up the addition of the C2 modem in the iPhone 18 Pro series, it turns out that Qualcomm modems are still being utilized.<a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-teardown-reveals-the-ins-and-outs-of-the-latest-iphone-models-including-one-annoying-repair-issue"> iFixit teardowns revealed that the iPhone 18 Pro Max still uses a Qualcomm modem</a>, and they have a reputation for being a little power-hungry.</p><p>The reason Apple hasn't ditched Qualcomm in its entirety is all very legal. Suffice it to say Apple was obligated to continue using some Qualcomm modems in its devices until this year. As far as we know, the end of 2026 means Apple is free to use its own modems across the entire iPhone lineup — including iPhone 20. </p><h3 class="article-body__section" id="section-silicon-carbon-batteries"><span>Silicon carbon batteries</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.21%;"><img id="4ALsrPjxc7ma3q24FGt74K" name="iPhone 18 Pro and Pro Max-LIST1" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/4ALsrPjxc7ma3q24FGt74K-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1439" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>More and more phones are adopting Silicon Carbon battery technology, and the iPhone 20 could be the first Apple smartphone to make the switch. These batteries use a silicon-coated anode and are able to offer much better energy density as a result. Effectively meaning Apple can reduce the size of the iPhone 20 battery without lowering the actual capacity in the process.</p><p><a href="https://www.tomsguide.com/phones/oneplus-phones/oneplus-15-review">OnePlus 15</a> did this with its monster 7,300 mAh battery, without adding any meaningful amount of weight or thickness to the phone. Samsung did it with the <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-review-wide-for-the-win">Galaxy Z Fold 8</a> too, increasing the total battery capacity while maintaining a sleek, thin foldable profile. So there's little reason for Apple not to follow suit.</p><h3 class="article-body__section" id="section-better-cameras"><span>Better cameras</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="473VNvCMPfhDkYKpe3aJjK" name="iPhone 18 Pro and Pro Max-12" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/473VNvCMPfhDkYKpe3aJjK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Apple could be <a href="https://www.tomsguide.com/news/apple-could-revolutionize-the-iphones-camera-with-this-groundbreaking-change">developing a stacked image sensor</a> for the iPhone 20's cameras, effectively replacing the Sony sensors iPhones have relied on for years. The benefit of this is that the camera would be able to capture even more detail in bright and darker areas, without losing any information in the process. In other words, better picture quality and dynamic range rolled into one.</p><p>It's also been rumored that Apple may copy Samsung and <a href="https://www.tomsguide.com/phones/iphones/future-iphones-could-pack-a-200mp-camera-heres-what-that-means-for-you">adopt a 200MP main camera</a> on the iPhone 20 — up from 48MP on the iPhone 18 Pro and Pro Max. It seems like quite a big leap, especially since Apple generally focuses on improving photography software, but if it's going to happen, it might as well be on the iPhone 20.</p><h3 class="article-body__section" id="section-new-screen-sizes"><span>New screen sizes</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4edCqgzDe6Geozici7QFqK" name="iPhone 18 Pro and Pro Max-14" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/4edCqgzDe6Geozici7QFqK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The all-glass displays also mean the iPhone 20 could come with slightly larger screens. A recent rumor from <a href="https://weibo.com/6048569942/Rj6MNs5hS" target="_blank">Digital Chat Station</a> claims that the iPhone 20 Pro will feature a 6.41-inch display, and the Pro Max model will have a 6.96-inch display. That's up from a respective 6.3 inches and 6.9 inches on the iPhone 18 Pro and Pro Max. </p><p>Both new phones are rumored to come with resolutions of 2,686 x 1,236 and 2,912 x 1,340 — suggesting that they will be incrementally taller and wider as a result of the larger screen. Not by much, but that extra screen space has to come from somewhere, right?</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/i-put-the-iphone-18-pro-max-vs-iphone-17-pro-max-through-a-7-round-face-off-heres-the-winner">I put the iPhone 18 Pro Max vs. iPhone 17 Pro Max through a 7-round face-off — here’s the winner</a></li><li><a href="https://www.tomsguide.com/phones/i-finally-unlinked-my-iphone-alarm-from-my-ringer-volume-here-is-where-apple-hid-it-in-ios-27">I finally unlinked my iPhone alarm from my ringer volume — here is where Apple hid it in iOS 27</a></li><li><a href="https://www.tomsguide.com/phones/android-phones/snapdragon-8-elite-gen-6-benchmark-test-results-hands-on-vs-a20-pro-iphone-18-pro">I tested Snapdragon 8 Elite Extreme Gen 6 — 16% faster CPU and huge AI-infused gaming upgrades, but Apple’s A20 Pro pulls ahead in some areas</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ iPhone Duo preorder deals — the best discounts to watch before October 16 ]]></title>
                                                                                                <dc:content><![CDATA[ <p><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> preorders don't start until October 16 at 8:00 a.m. ET — but that doesn't mean you can't start hunting for deals and discounts now. Apple's first foldable device was announced during the company's <a href="https://www.tomsguide.com/news/live/apple-event-live-foldable-iphone-iphone-18-pro-max-apple-watch-12-and-all-the-big-news">"Surprise and Shine" event</a> and will be available for purchase on October 23. </p><p>The new 5.4-inch phone and tablet in one device opens up to revel a huge 7.6-inch nano-texture display starts at $1,999, making it Apple's most expensive phone yet. That's a tough pill to swallow in today's economy, but I'm here to help you find the best iPhone Duo preorder deals well in advance of the release date.</p><p>iPhone Duo preorder deals have yet to start, but the <a href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow">Apple Store is already offering $35 to $885 in credit via trade-in</a>. For example, an iPhone 8 Plus will land you a $35 credit, whereas an iPhone 17 Pro Max will get you the maximum $885 off credit. I expect to see many more iPhone Duo preorder deals in the weeks to come as carriers release their own offers. </p><p>Below I've listed the best early deals on Apple's iPhone Duo from top carriers and retailers.</p><h3 class="article-body__section" id="section-what-you-need-to-know"><span>What you need to know</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="q4DNX2SeEFU5sCTTt45wEa" name="iphone duo edit 5" alt="iPhone Duo" src="https://cdn.mos.cms.futurecdn.net/q4DNX2SeEFU5sCTTt45wEa-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Current iPhone 18 Pro Max orders are seeing delays, with deliveries showing October 14 to October 21. Considering the strong interest in the iPhone Duo, we expect much longer delivery times with this model — so placing a pre-order as soon as possible is critical if you want to get it with the least amount of wait.</p><p>So far, Apple and major carriers are set to sell the iPhone Duo. While we expect other MVNOs to sell Apple's first foldable phone, it may be a long while before it happens. At the same time, we suspect that unlocked versions of the Duo might be in short supply due to demand. </p><h3 class="article-body__section" id="section-quick-links"><span>Quick Links</span></h3><ul><li><strong>iPhone Duo: </strong><a href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow"><strong>up to $885 w/ trade-in @ Apple Store</strong></a></li><li><strong>iPhone Duo: </strong><a href="https://www.t-mobile.com/cell-phone/apple-iphone-duo?"><strong>preorder October 16 @ T-Mobile</strong></a></li><li><strong>iPhone Duo: </strong><a href="https://www.verizon.com/smartphones/apple-iphone-duo/" target="_blank" rel="nofollow"><strong>waived activation fee @ Verizon</strong></a></li><li><strong>iPhone Duo: </strong><a href="https://www.att.com/buy/phones/apple-iphone-duo.html" target="_blank" rel="nofollow"><strong>preorder October 16 @ AT&T</strong></a></li></ul><h3 class="article-body__section" id="section-iphone-duo"><span>iPhone Duo</span></h3><div class="product"><a data-dimension112="6cc6be5a-b691-11f1-bc79-596df37e8fe3" data-action="Deal Block" data-label="iPhone Duo: up to $885 w/ trade-in @ Apple Store" data-dimension48="iPhone Duo: up to $885 w/ trade-in @ Apple Store" href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:728px;"><p class="vanilla-image-block" style="padding-top:91.48%;"><img id="xkXTUQ8A4RPbEuJRLjy2WH" name="iPhone Deuo" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/xkXTUQ8A4RPbEuJRLjy2WH-1920-80.jpg" mos="" align="middle" fullscreen="" width="728" height="666" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone Duo: </strong><a href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow" data-dimension112="6cc6be5a-b691-11f1-bc79-596df37e8fe3" data-action="Deal Block" data-label="iPhone Duo: up to $885 w/ trade-in @ Apple Store" data-dimension48="iPhone Duo: up to $885 w/ trade-in @ Apple Store" data-dimension25=""><strong>up to $885 w/ trade-in @ Apple Store</strong></a><br>The Apple Store is offering up to a $885 credit when you trade-in your old smartphone for the iPhone Duo. For example, an iPhone 15 will get you up to a $305 credit, while an iPhone 13 Pro will get you up to a $255 credit. Clearly newer models have more value, evident in how an iPhone 17 Pro Max will get you up to $885 off.<a class="view-deal button" href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow" data-dimension112="6cc6be5a-b691-11f1-bc79-596df37e8fe3" data-action="Deal Block" data-label="iPhone Duo: up to $885 w/ trade-in @ Apple Store" data-dimension48="iPhone Duo: up to $885 w/ trade-in @ Apple Store" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="6cc6bedc-b691-11f1-a180-cf86370157dd" data-action="Deal Block" data-label="iPhone Duo: preorder October 16 @ T-Mobile" data-dimension48="iPhone Duo: preorder October 16 @ T-Mobile" href="https://www.t-mobile.com/cell-phone/apple-iphone-duo?" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:50.00%;"><img id="Y26QJd7Ff7aeQmTHuW8nCP" name="NEW T-Mobile Logo" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Y26QJd7Ff7aeQmTHuW8nCP-1920-80.png" mos="" align="middle" fullscreen="" width="600" height="300" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone Duo: </strong><a href="https://www.t-mobile.com/cell-phone/apple-iphone-duo?" data-dimension112="6cc6bedc-b691-11f1-a180-cf86370157dd" data-action="Deal Block" data-label="iPhone Duo: preorder October 16 @ T-Mobile" data-dimension48="iPhone Duo: preorder October 16 @ T-Mobile" data-dimension25=""><strong>preorder October 16 @ T-Mobile</strong></a><br>T-Mobile doesn't have any discounts on the iPhone Duo yet but you preorders will be available on October 16. Despite that, it offers some of the best rates with its unlimited plans.<a class="view-deal button" href="https://www.t-mobile.com/cell-phone/apple-iphone-duo?" target="_blank" rel="nofollow" data-dimension112="6cc6bedc-b691-11f1-a180-cf86370157dd" data-action="Deal Block" data-label="iPhone Duo: preorder October 16 @ T-Mobile" data-dimension48="iPhone Duo: preorder October 16 @ T-Mobile" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="6cc6bf40-b691-11f1-b7b4-11ddb26f0b74" data-action="Deal Block" data-label="iPhone Duo: waived activation fee @ Verizon" data-dimension48="iPhone Duo: waived activation fee @ Verizon" href="https://www.verizon.com/smartphones/apple-iphone-duo/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:400px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="bhuNLVbkmhJxHuYhoz9cuY" name="verizon-redesign-thumb.jpeg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/bhuNLVbkmhJxHuYhoz9cuY-1920-80.jpg" mos="" align="middle" fullscreen="" width="400" height="400" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone Duo: </strong><a href="https://www.verizon.com/smartphones/apple-iphone-duo/" target="_blank" rel="nofollow" data-dimension112="6cc6bf40-b691-11f1-b7b4-11ddb26f0b74" data-action="Deal Block" data-label="iPhone Duo: waived activation fee @ Verizon" data-dimension48="iPhone Duo: waived activation fee @ Verizon" data-dimension25=""><strong>waived activation fee @ Verizon</strong></a><br>Verizon waiving activation and upgrade fees for customers on its Simplicity Plan who enroll in its Verizon Loyalty program. We expect there to be full trade-in offers and deals when iPhone Duo preorders officially open. <a class="view-deal button" href="https://www.verizon.com/smartphones/apple-iphone-duo/" target="_blank" rel="nofollow" data-dimension112="6cc6bf40-b691-11f1-b7b4-11ddb26f0b74" data-action="Deal Block" data-label="iPhone Duo: waived activation fee @ Verizon" data-dimension48="iPhone Duo: waived activation fee @ Verizon" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="6cc6bfae-b691-11f1-b9ce-ff072f7891a3" data-action="Deal Block" data-label="iPhone Duo: preorder October 16 @ AT&amp;T" data-dimension48="iPhone Duo: preorder October 16 @ AT&amp;T" href="https://www.att.com/buy/phones/apple-iphone-duo.html" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:225px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="o9PdShQsgAk95AN7C5UMNR" name="AT&T Logo.jpeg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/o9PdShQsgAk95AN7C5UMNR-1920-80.jpeg" mos="" align="middle" fullscreen="" width="225" height="225" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone Duo: </strong><a href="https://www.att.com/buy/phones/apple-iphone-duo.html" target="_blank" rel="nofollow" data-dimension112="6cc6bfae-b691-11f1-b9ce-ff072f7891a3" data-action="Deal Block" data-label="iPhone Duo: preorder October 16 @ AT&amp;T" data-dimension48="iPhone Duo: preorder October 16 @ AT&amp;T" data-dimension25=""><strong>preorder October 16 @ AT&T</strong></a><br>AT&T doesn't have any discounts on the iPhone Duo yet but you preorders will be available on October 16. <a class="view-deal button" href="https://www.att.com/buy/phones/apple-iphone-duo.html" target="_blank" rel="nofollow" data-dimension112="6cc6bfae-b691-11f1-b9ce-ff072f7891a3" data-action="Deal Block" data-label="iPhone Duo: preorder October 16 @ AT&amp;T" data-dimension48="iPhone Duo: preorder October 16 @ AT&amp;T" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="8bb67c0a-b697-11f1-94a1-afa23a3a111a" data-action="Deal Block" data-label="iPhone Duo: $55.56/month preorder October 16 @ Best Buy" data-dimension48="iPhone Duo: $55.56/month preorder October 16 @ Best Buy" href="https://www.bestbuy.com/product/apple-iphone-duo-256gb-star-white-at-t/JCQ6HTJYJQ" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1331px;"><p class="vanilla-image-block" style="padding-top:68.52%;"><img id="yjsgCbZzcWDLMuhHtLHa7K" name="Best Buy deal block 2022.jpeg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/yjsgCbZzcWDLMuhHtLHa7K-1920-80.jpeg" mos="" align="middle" fullscreen="" width="1331" height="912" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone Duo: </strong><a href="https://www.bestbuy.com/product/apple-iphone-duo-256gb-star-white-at-t/JCQ6HTJYJQ" target="_blank" rel="nofollow" data-dimension112="8bb67c0a-b697-11f1-94a1-afa23a3a111a" data-action="Deal Block" data-label="iPhone Duo: $55.56/month preorder October 16 @ Best Buy" data-dimension48="iPhone Duo: $55.56/month preorder October 16 @ Best Buy" data-dimension25=""><strong>$55.56/month preorder October 16 @ Best Buy</strong></a><br>Right now, Best Buy is showing preorder deals on the iPhone Duo for as low as $55.56/month when it's activated with a 36-month AT&T Installment plan. You'll be able to get this offer starting on October 16. <a class="view-deal button" href="https://www.bestbuy.com/product/apple-iphone-duo-256gb-star-white-at-t/JCQ6HTJYJQ" target="_blank" rel="nofollow" data-dimension112="8bb67c0a-b697-11f1-94a1-afa23a3a111a" data-action="Deal Block" data-label="iPhone Duo: $55.56/month preorder October 16 @ Best Buy" data-dimension48="iPhone Duo: $55.56/month preorder October 16 @ Best Buy" data-dimension25="">View Deal</a></p></div><h3 class="article-body__section" id="section-shop-more-deals"><span>Shop more deals</span></h3><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?brands=Apple&rows=6&view_mode=savings_squad&widget_title=Top+Deals+Handpicked+by+Our+Editors&widget_subtitle=Discover+the+best+discounts+currently+available%2C+curated+daily+by+the+Tom%27s+Guide+Savings+Squad.&bg_color=transparent" data-vizualizer-embed="true"></div>    <script>    /**     * Tom's Guide Deals Finder - Vanilla JS Encapsulated Engine     */    (function() {      // --- Freyr Analytics Adapter ---      function initAnalytics() {        window.dataLayer = window.dataLayer || [];        window.googletag = window.googletag || {};        window.googletag.cmd = window.googletag.cmd || [];        window.hawk = window.hawk || { analytics: { freyr: [] } };        window.hawk.analytics = window.hawk.analytics || { freyr: [] };        window.hawk.analytics.freyr = window.hawk.analytics.freyr || [];        window.freyr = window.freyr || { cmd: [] };        const scriptSrc = 'https://freyr.futurecdn.net/freyr.js';        const hostname = typeof window !== 'undefined' ? window.location.hostname : '';        const isTestEnv = typeof window.navigator !== 'undefined' && (window.navigator.webdriver || window.navigator.userAgent.includes('Headless'));        const shouldSendRealAnalytics = !isTestEnv && hostname && hostname !== 'localhost' && hostname !== '127.0.0.1' && !hostname.includes('run.app');        if (shouldSendRealAnalytics && !document.querySelector(`script[src="${scriptSrc}"]`)) {          const script = document.createElement('script');          script.src = scriptSrc;          script.async = true;          document.head.appendChild(script);        }      }      function storeEventForDebug(name, data) {        if (!window.hawk || !window.hawk.analytics || !window.hawk.analytics.freyr) return;        window.hawk.analytics.freyr.push({ name, data });        try {          if (typeof window !== 'undefined' && window.localStorage) {            window.localStorage.setItem("hawk", JSON.stringify(window.hawk));          }        } catch (e) {          // Ignore storage issues        }        try {          window.dispatchEvent(new CustomEvent("hawk-analytics-update"));        } catch (e) {}      }      function sendToFreyr(eventName, data) {        if (typeof window === 'undefined') return;        window.freyr = window.freyr || { cmd: [] };        window.freyr.cmd.push(() => {          if (window.freyr && window.freyr.pushAndUpdate) {            window.freyr.pushAndUpdate(eventName, data);          }        });      }      function sendEvent(event, skip = false) {        try {          storeEventForDebug(event.name, event.data);          if (!skip) {            sendToFreyr(event.name, event.data);          }        } catch (e) {          // Ensure tracking errors don't surface to the user        }      }      function getCookie(name) {        try {          const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));          return match ? match[2] : null;        } catch (e) {          return null;        }      }      function getTimeAgo(dateString) {        if (!dateString) return '';        const date = new Date(dateString);        const now = new Date();        const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);        if (diffInSeconds < 60) return 'Just now';        const diffInMinutes = Math.floor(diffInSeconds / 60);        if (diffInMinutes < 60) return `${diffInMinutes} min${diffInMinutes > 1 ? 's' : ''} ago`;        const diffInHours = Math.floor(diffInMinutes / 60);        if (diffInHours < 24) return `${diffInHours} hr${diffInHours > 1 ? 's' : ''} ago`;        const diffInDays = Math.floor(diffInHours / 24);        if (diffInDays < 30) return `${diffInDays} day${diffInDays > 1 ? 's' : ''} ago`;        const diffInMonths = Math.floor(diffInDays / 30);        if (diffInMonths < 12) return `${diffInMonths} mo${diffInMonths > 1 ? 's' : ''} ago`;        const diffInYears = Math.floor(diffInDays / 365);        return `${diffInYears} yr${diffInYears > 1 ? 's' : ''} ago`;      }      function normalizeCurrency(symbol) {        const map = {          '£': 'GBP',          '$': 'USD',          'A$': 'AUD',          'CA$': 'CAD',          '€': 'EUR'        };        return map[symbol] || symbol;      }      function trackElementInteraction(props) {        sendEvent({          name: 'elementInteraction',          data: {            element: {              action: props.action || "click",              id: props.id || undefined,              class: props.class || undefined,              name: props.name || undefined,              text: props.text || undefined,              label: props.label || undefined,              container: props.container || undefined,              url: props.url || undefined,              articleId: props.articleId || undefined            }          }        });      }      function generateRevenueId(url, productName, merchantName, modelId) {        const str = `${window.location.href}|${productName}|${merchantName}|${modelId || ''}|${new Date().toDateString()}|tomsguide`;        let hash = 0;        for (let i = 0; i < str.length; i++) {          const char = str.charCodeAt(i);          hash = ((hash << 5) - hash) + char;          hash = hash & hash;        }        let numericStr = Math.abs(hash).toString();        while (numericStr.length < 19) {          numericStr += Math.floor(Math.random() * 10).toString();        }        return numericStr.substring(0, 19);      }      function rewriteAffiliateLink(url, territory, revenueId) {        if (!url) return url;        const t = (territory || 'gb').toLowerCase();        return url.replace(/hawk-custom-tracking/g, `tomsguide-${t}-${revenueId}`);      }      function trackHawkEvent(params) {        const { clickType, widgetId, productCategoryName, product, productsArray, zeroBasedProductIndexOrNull, totalDealsOrProducts, areaClicked, merchant, revenueId, isoCurrencyCode, queryName, widgetTypeName } = params;        const data = {          event: "hawkEvent",          category: "Affiliates",          affiliate: {            action: {              type: clickType,              id: widgetId,              event: clickType === "appeared" ? "viewed" : "Click from",              timestamp: Date.now()            },            component: {              flag: "Editor",              product: productCategoryName || "deals",              category: `Signal Deal Finder ${widgetTypeName || "Carousel"} widget`,              type: clickType === "appeared" ? "review" : "signal product",              label: queryName || (product ? (product.name || "") : ""),              index: zeroBasedProductIndexOrNull === null || zeroBasedProductIndexOrNull === undefined ? -1 : zeroBasedProductIndexOrNull,              linkCount: totalDealsOrProducts || 0,              blockLayout: "",              areaClicked: areaClicked || ""            }          },          products: productsArray || (product && merchant ? [            {              product: {                primary: {                  id: product.id || product.matchId || null,                  name: product.name,                  type: "deal",                  price: product.price,                  previousPrice: product.previousPrice || null,                  currency: isoCurrencyCode || "USD",                  preorder: false,                  labels: [],                  link: product.link,                  originalLink: product.originalLink || null,                  revenueId: revenueId || null,                  startTime: null,                  endTime: null,                  voucherCode: null,                  voucherAudience: null,                  voucherPercentageSaving: null,                  voucherMoneySaving: null,                  voucherType: null,                  offerExclusive: false,                  offerScope: null,                  globalId: product.globalId || null,                  inStock: product.inStock !== false,                  contractProvider: null,                  contractMinutes: null,                  contractTexts: null,                  contractData: null,                  contractLength: null,                  contractMonthlyPrice: null,                  contractCurrency: isoCurrencyCode || "USD"                }              },              merchant: {                id: merchant.id || null,                name: merchant.name,                url: merchant.url || null,                network: merchant.network || null              },              model: {                id: product.modelId || null,                brand: product.brand || null,                name: product.name,                parent: product.parent || null              }            }          ] : []),          reviews: [],          _clear: true,          "gtm.uniqueEventId": Date.now() % 10000        };        sendEvent({ name: 'hawkEvent', data });      }      function trackDealClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Product Card" });      }      function trackViewSimilarClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Product Card View Similar" });      }      function trackPriceComparisonClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Price Comparison" });      }      function trackReviewClick(params) {        trackHawkEvent({ ...params, clickType: "review", areaClicked: "Signal Product Card Review Link" });      }      function trackShare(params) {        trackHawkEvent({ ...params, clickType: "share", areaClicked: "Signal Product Card Share" });      }      function trackDealsAppeared(widgetId, deals, revenueId, currency, queryName, widgetTypeName) {         if (!deals || deals.length === 0) return;                  const productsArray = deals.slice(0, 50).map((deal) => {            let voucherPct = null;            let rawPrice = parseFloat(deal.rawPrice) || parseFloat(deal.price) || null;            let rawMsrp = parseFloat(deal.rawMsrp) || parseFloat(deal.msrp) || null;            if (rawMsrp > rawPrice && rawPrice > 0) {              voucherPct = Math.round((1 - (rawPrice / rawMsrp)) * 100);            }            let numId = null;            if (deal.externalProductId && !isNaN(parseInt(deal.externalProductId))) {              numId = parseInt(deal.externalProductId);            } else if (deal.id && !isNaN(parseInt(deal.id))) {              numId = parseInt(deal.id);            } else {              numId = deal.matchId || null;            }            return {              product: {                primary: {                  id: numId,                  name: deal.productName || deal.title || "",                  type: "deal",                  price: rawPrice,                  previousPrice: rawMsrp,                  currency: currency || 'USD',                  preorder: false,                  labels: deal.modelBrand || deal.brand ? [                     { type: "brand", value: deal.modelBrand || deal.brand }                  ] : [],                  link: deal.url,                  originalLink: deal.url,                  revenueId: revenueId || null,                  startTime: null,                  endTime: null,                  voucherCode: null,                  voucherAudience: null,                  voucherPercentageSaving: voucherPct,                  voucherMoneySaving: null,                  voucherType: null,                  offerExclusive: false,                  offerScope: null,                  globalId: deal.productKey || null,                  inStock: deal.inStock !== false,                  contractProvider: null,                  contractMinutes: null,                  contractTexts: null,                  contractData: null,                  contractLength: null,                  contractMonthlyPrice: null,                  contractCurrency: currency || 'USD'                }              },              merchant: {                id: deal.merchantId ? parseInt(deal.merchantId) : null,                name: deal.merchant || "Retailer",                url: deal.merchantUrl || null,                network: deal.merchantNetwork || null              },              model: {                id: deal.modelId ? parseInt(deal.modelId) : null,                brand: deal.modelBrand || deal.brand || null,                name: deal.productName || deal.title || "",                parent: deal.modelParent || null              }            };         });                  trackHawkEvent({             clickType: "appeared",             widgetId: widgetId,             productCategoryName: "deals",             zeroBasedProductIndexOrNull: null,             totalDealsOrProducts: deals.length,             productsArray: productsArray,             queryName: queryName,             widgetTypeName: widgetTypeName         });      }      // 1. Setup Shadow DOM Sandbox      const currentScript = document.currentScript;      let hostContainer = null;      let template = null;            if (currentScript) {        let prev = currentScript.previousElementSibling;        while (prev) {          if (prev.tagName === 'TEMPLATE' && prev.classList.contains('tg-df-widget-template')) {            template = prev;          } else if (prev.tagName === 'DIV' && prev.classList.contains('tg-df-widget-host') && !prev.hasAttribute('data-initialized')) {            hostContainer = prev;            break;          }          prev = prev.previousElementSibling;        }      }            // Fallbacks in case script is deferred      if (!hostContainer) {        const hosts = document.querySelectorAll('.tg-df-widget-host:not([data-initialized])');        if (hosts.length > 0) hostContainer = hosts[0];      }            // Safely embedded template for CMS environments      const rawTemplate = `  \x3Cstyle>    /* --- Shadow DOM Base Reset --- */    *, *::before, *::after {      box-sizing: border-box;    }    img, picture, svg, video {      max-width: 100%;      height: auto;      display: block;    }    /*       1. Scoped CSS for Tom's Guide Deals Widget       All classes are prefixed with \`tg-df-\` to prevent CMS style leakage.    */    .tg-df-container {      container-type: inline-size;      container-name: tg-df;      --tg-df-blue: #1F69FF;      --tg-df-blue-hover: #004d8c;      --tg-df-text: #222222;      --tg-df-text-muted: #555555;      --tg-df-bg: #ffffff;      --tg-df-bg-secondary: #f4f4f4;      --tg-df-border: #e2e8f0;      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;      color: var(--tg-df-text);      background-color: transparent;       width: 100%;      max-width: 1200px;      margin: 0 auto;      padding-bottom: 24px;    }    .tg-df-container *, .tg-df-container *::before, .tg-df-container *::after {      margin: 0;      padding: 0;      box-sizing: border-box;    }    .tg-df-container img {      border: none;      margin: 0;      padding: 0;    }    .tg-df-container a {      text-decoration: none;      color: inherit;    }    /*       2. Search & Filter Bar    */    .tg-df-controls {      display: flex;      flex-direction: column;      align-items: center;      gap: 20px;      margin-bottom: 32px;      width: 100%;      position: relative;      z-index: 20;    }    .tg-df-top-bar {      display: flex;      width: 100%;      max-width: 760px;      gap: 12px;      margin: 0 auto;      align-items: center;    }    .tg-df-search-wrapper {      position: relative;      flex: 1;      width: 100%;      box-shadow: 0 8px 24px rgba(0,0,0,0.06);      border-radius: 40px;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      z-index: 100;    }    .tg-df-autocomplete-dropdown {      position: absolute;      top: calc(100% + 4px);      left: 0;      right: 0;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 12px;      box-shadow: 0 8px 32px rgba(0,0,0,0.12);      max-height: 300px;      overflow-y: auto;      z-index: 200;      display: none;    }    .tg-df-autocomplete-dropdown.active {      display: block;    }    .tg-df-autocomplete-item {      padding: 12px 24px;      cursor: pointer;      font-size: 14px;      color: var(--tg-df-text);      transition: background 0.1s ease;    }    .tg-df-autocomplete-item:hover {      background: var(--tg-df-bg-secondary);    }    .tg-df-search-input {      width: 100%;      padding: 16px 64px 16px 24px;      font-size: 16px;      border: 2px solid transparent;      border-radius: 40px;      outline: none;      transition: border-color 0.2s ease, box-shadow 0.2s ease;      color: var(--tg-df-text);      background: transparent;    }    .tg-df-search-input:focus {      border-color: transparent;      box-shadow: 0 0 0 3px rgba(0, 108, 196, 0.15);    }    .tg-df-search-input::placeholder {      color: #999999;    }        .tg-df-search-btn {      position: absolute;      right: 8px;      top: 50%;      transform: translateY(-50%);      width: 40px;      height: 40px;      border-radius: 50%;      background: #222;      border: none;      display: flex;      align-items: center;      justify-content: center;      cursor: pointer;      transition: background 0.2s ease;    }        .tg-df-search-btn:hover {      background: #000;    }    .tg-df-search-icon {      width: 16px;      height: 16px;      fill: #fff;    }    .tg-df-settings-wrapper {      position: relative;    }        .tg-df-settings-btn {      width: 48px;      height: 48px;      border-radius: 50%;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      box-shadow: 0 4px 12px rgba(0,0,0,0.04);      display: flex;      align-items: center;      justify-content: center;      cursor: pointer;      transition: all 0.2s ease;      color: var(--tg-df-text-muted);      flex-shrink: 0;    }    .tg-df-settings-btn:hover {      background: var(--tg-df-bg-secondary);      border-color: #0000ff;      color: var(--tg-df-text);    }    .tg-df-settings-btn svg {      width: 24px;      height: 24px;      fill: currentColor;    }    .tg-df-settings-dropdown {      position: absolute;      top: calc(100% + 8px);      right: 0;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 12px;      box-shadow: 0 8px 32px rgba(0,0,0,0.12);      width: 280px;      padding: 20px;      display: none;      z-index: 100;      flex-direction: column;      gap: 20px;    }    .tg-df-settings-dropdown.active {      display: flex;    }        .tg-df-settings-dropdown-backdrop {      display: none;      position: fixed;      inset: 0;      z-index: 99;    }        .tg-df-settings-dropdown-backdrop.active {      display: block;    }    .tg-df-setting-item {      display: flex;      flex-direction: column;      gap: 10px;    }    .tg-df-setting-label {      font-size: 11px;      font-weight: 700;      color: var(--tg-df-text-muted);      text-transform: uppercase;      letter-spacing: 0.5px;    }        .tg-df-region-select {        padding: 10px 12px;        border-radius: 8px;        border: 1px solid var(--tg-df-border);        font-size: 15px;        outline: none;        background: var(--tg-df-bg-secondary);        color: var(--tg-df-text);        cursor: pointer;        width: 100%;    }    .tg-df-toggle {        position: relative;        display: inline-block;        width: 44px;        height: 24px;        flex-shrink: 0;    }    .tg-df-toggle input {        opacity: 0;        width: 0;        height: 0;    }    .tg-df-slider {        position: absolute;        cursor: pointer;        top: 0; left: 0; right: 0; bottom: 0;        background-color: #ccc;        transition: .2s;        border-radius: 24px;    }    .tg-df-slider:before {        position: absolute;        content: "";        height: 18px;        width: 18px;        left: 3px;        bottom: 3px;        background-color: white;        transition: .2s;        border-radius: 50%;    }    .tg-df-toggle input:checked + .tg-df-slider {        background-color: #1F69FF;    }    .tg-df-toggle input:checked + .tg-df-slider:before {        transform: translateX(20px);    }    .tg-df-dl-row {        flex-direction: row;        align-items: center;        justify-content: space-between;    }    .tg-df-dl-row-text {        font-size: 14px;        font-weight: 600;        color: var(--tg-df-text);    }    .tg-df-dl-row-subtext {        font-size: 12px;        font-weight: 400;        line-height: 1.3;        color: var(--tg-df-text-muted);        margin-top: 4px;        display: block;    }    .tg-df-filters-container {      position: relative;      width: 100%;      max-width: 800px;    }    .tg-df-scroll-btn {      display: none;      position: absolute;      top: 50%;      transform: translateY(-50%);      width: 32px;      height: 32px;      background: white;      border: 1px solid var(--tg-df-border);      border-radius: 50%;      align-items: center;      justify-content: center;      cursor: pointer;      z-index: 10;      box-shadow: 0 2px 8px rgba(0,0,0,0.1);      color: var(--tg-df-text-primary);      padding: 0;    }    .tg-df-scroll-btn svg {      width: 16px;      height: 16px;    }    .tg-df-scroll-btn:hover {      background: #f4f4f4;    }    .tg-df-scroll-btn.left {      left: 0px;    }    .tg-df-scroll-btn.right {      right: 0px;    }    @container tg-df (max-width: 768px) {      .tg-df-scroll-btn {        display: flex;        top: 22px; /* vertically center within the 44px high filter buttons */      }    }    .tg-df-filters {      display: grid;      width: 100%;      grid-template-columns: repeat(4, 1fr);      gap: 12px;      margin: 0 auto;      max-width: 800px;    }                 .tg-df-sort-wrapper {      position: relative;      display: flex;      align-items: center;      width: 100%;    }        .tg-df-sort-icon {      position: absolute;      left: 14px;      width: 14px;      height: 14px;      fill: var(--tg-df-text-muted);      pointer-events: none;    }    .tg-df-sort-select, .tg-df-filter-select {      width: 100%;      padding: 10px 36px 10px 38px;      font-size: 14px;      border: 1px solid var(--tg-df-border);      border-radius: 100px;      outline: none;      appearance: none;      background-color: var(--tg-df-bg-secondary);      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12'%3E%3Cpath fill='%23555555' d='M6 8L1 3h10z'/%3E%3C/svg%3E");      background-repeat: no-repeat;      background-position: right 14px center;      color: var(--tg-df-text);      cursor: pointer;      font-weight: 500;      transition: all 0.2s ease;    }        .tg-df-price-input::-webkit-outer-spin-button,    .tg-df-price-input::-webkit-inner-spin-button {      -webkit-appearance: none;      margin: 0;    }    .tg-df-price-input {      -moz-appearance: textfield;    }    .tg-df-sort-select:hover, .tg-df-filter-select:hover {      background-color: #e2e8f0;    }    .tg-df-multiselect-container {      position: relative;    }    @container tg-df (max-width: 768px) {      .tg-df-filters-container {      position: relative;      width: 100%;      max-width: 800px;    }    .tg-df-scroll-btn {      display: none;      position: absolute;      top: 50%;      transform: translateY(-50%);      width: 32px;      height: 32px;      background: white;      border: 1px solid var(--tg-df-border);      border-radius: 50%;      align-items: center;      justify-content: center;      cursor: pointer;      z-index: 10;      box-shadow: 0 2px 8px rgba(0,0,0,0.1);      color: var(--tg-df-text-primary);      padding: 0;    }    .tg-df-scroll-btn svg {      width: 16px;      height: 16px;    }    .tg-df-scroll-btn:hover {      background: #f4f4f4;    }    .tg-df-scroll-btn.left {      left: 0px;    }    .tg-df-scroll-btn.right {      right: 0px;    }    @container tg-df (max-width: 768px) {      .tg-df-scroll-btn {        display: flex;        top: 22px; /* vertically center within the 44px high filter buttons */      }    }    .tg-df-filters {        width: 100%;        margin: 0;        margin-bottom: -320px;        padding: 0 16px 320px 16px;        display: flex;        flex-wrap: nowrap;        gap: 8px;        overflow-x: auto;        overflow-y: hidden;        pointer-events: none;        scrollbar-width: none;        -webkit-overflow-scrolling: touch;      }      .tg-df-filters::-webkit-scrollbar {        display: none;      }      .tg-df-sort-wrapper {        pointer-events: auto;        flex: 0 0 auto;        width: 175px;        min-width: 175px;      }    }        .tg-df-multiselect-trigger {      display: block;      background: #fff;      user-select: none;      width: 100%;      overflow: hidden;      white-space: nowrap;      text-overflow: ellipsis;    }        .tg-df-multiselect-dropdown {      display: none;      position: absolute;      top: calc(100% + 4px);      left: 0;      width: 100%;      min-width: 220px;      max-height: 300px;      overflow-y: auto;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 8px;      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);      z-index: 100;      padding: 8px 0;    }    .tg-df-multiselect-dropdown.active {      display: block;    }    .tg-df-ms-option {      padding: 8px 16px;      display: flex;      align-items: center;      gap: 8px;      cursor: pointer;      font-size: 14px;    }    .tg-df-ms-option:hover {      background-color: var(--tg-df-bg-secondary);    }        .tg-df-ms-option input {      cursor: pointer;      accent-color: #1f69ff;    }    .tg-df-sort-select:focus, .tg-df-filter-select:focus {      border-color: #0000ff;      box-shadow: 0 0 0 3px rgba(0, 0, 255, 0.2);      background-color: var(--tg-df-bg);    }    /*       3. Deal Grid Layout    */    .tg-df-grid.tg-df-grid-auto {      padding-top: 24px;    }    .tg-df-grid, .tg-df-grid.layout-grid {      display: grid;      grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));      gap: 10px;    }    .tg-df-grid.layout-row {      grid-template-columns: 1fr;      gap: 16px;    }        .tg-df-grid.layout-row .tg-df-card {      flex-direction: row;      align-items: stretch;      height: auto;      box-shadow: none;      border-bottom: 1px solid var(--tg-df-border);    }    .tg-df-grid.layout-row .tg-df-card:hover {      box-shadow: none;    }    .tg-df-grid.layout-row .tg-df-card-image-box {      width: 140px;      min-width: 140px;      aspect-ratio: 3/4;      border-right: none;      padding: 16px 16px 16px 32px;    }    .tg-df-grid.layout-row .tg-df-card-body {      padding: 16px;      justify-content: space-between;    }    .tg-df-grid.layout-row .tg-df-card-title {      font-size: 15px;      margin-bottom: 16px;    }    .tg-df-grid.layout-row .tg-df-card-stars { margin-bottom: 8px; }    .tg-df-grid.layout-row .tg-df-card-footer {      flex-direction: column;      align-items: flex-start;      gap: 0;    }    .tg-df-grid.layout-row .tg-df-card-merchant-pill {      margin-bottom: 4px;    }    .tg-df-grid.layout-row .tg-df-card-price-group {      margin-bottom: 8px;    }    .tg-df-grid.layout-row .tg-df-price-group {      width: auto;    }    .tg-df-grid.layout-row .tg-df-card-cta {      width: 100%;      max-width: 200px;      padding: 10px 24px;      font-size: 13px;      flex-shrink: 0;      text-align: center;      justify-content: center;    }    /*       4. Deal Card Design    */    .tg-df-card {      position: relative;      display: flex;      flex-direction: column;      background-color: #ffffff;      border-radius: 0;      overflow: hidden;      transition: transform 0.2s ease, box-shadow 0.2s ease;      text-decoration: none;      color: inherit;      height: 100%;      box-shadow: 0 0 16px rgba(0, 0, 0, 0.08);      border: 1px solid var(--tg-df-border);    }    .tg-df-card:hover {      box-shadow: 0 0 24px rgba(0, 0, 0, 0.12);    }    .tg-df-card-image-box {      width: 100%;      aspect-ratio: 3/4;      background-color: #f8f8f8;      display: flex;      align-items: center;      justify-content: center;      position: relative;      overflow: hidden;      padding: 32px;      flex: 0 0 auto;    }    .tg-df-card-image {      max-width: 100%;      max-height: 100%;      width: auto;      height: auto;      object-fit: contain;      mix-blend-mode: multiply; /* Helps white background images blend into secondary bg */      transition: transform 0.3s ease;    }    .tg-df-card:hover .tg-df-card-image {      transform: scale(1.05); /* Zoom in on hover */    }    .tg-df-card-discount-badge {      position: absolute;      top: 12px;      left: 12px;      background: #dc2626; /* Red */      color: #ffffff;      padding: 6px 8px;      font-size: 11px;      font-weight: 500;      text-transform: uppercase;      letter-spacing: 0.5px;      border-radius: 0;      z-index: 10;    }        .tg-df-card-merchant-pill {      display: block;      padding: 0;      font-size: 11px;      font-weight: 600;      text-transform: uppercase;      letter-spacing: 0.5px;      border-radius: 0;      color: var(--tg-df-text-muted);      margin-bottom: 8px;      white-space: nowrap;      overflow: hidden;      text-overflow: ellipsis;    }    .tg-df-card-body {      padding: 16px;      display: flex;      flex-direction: column;      flex-grow: 1;      min-width: 0;    }    .tg-df-card-badges {      display: flex;      flex-wrap: wrap;      gap: 6px;      margin-bottom: 8px;    }    .tg-df-tag {      display: inline-flex;      align-items: center;      padding: 4px 6px;      font-size: 11px;      font-weight: 700;      text-transform: uppercase;      border-radius: 4px;      gap: 4px;    }    .tg-df-tag-prime {      background-color: #00A8E1;      color: #fff;    }    .tg-df-tag-coupons {      background-color: #f1f5f9;      color: #334155;      border: 1px solid #cbd5e1;      cursor: pointer;      transition: background-color 0.2s;    }    .tg-df-tag-coupons:hover {      background-color: #e2e8f0;    }        .tg-df-tag-outline {      background-color: #f1f5f9;      color: #334155;      border: 1px solid #cbd5e1;      cursor: pointer;      transition: background-color 0.2s;    }    .tg-df-tag-outline:hover {      background-color: #e2e8f0;    }        @keyframes tg-df-spin {      0% { transform: rotate(0deg); }      100% { transform: rotate(360deg); }    }    .tg-df-coupon-spinner {      border: 2px solid #e2e8f0;      border-top: 2px solid #3b82f6;      border-radius: 50%;      width: 14px;      height: 14px;      animation: tg-df-spin 1s linear infinite;      margin: 4px 8px;      display: inline-block;    }        /* Vouchers Modal */    .tg-df-modal-backdrop {      position: fixed;      top: 0; left: 0; right: 0; bottom: 0;      background: rgba(0,0,0,0.5);      z-index: 10000;      display: flex;      align-items: center;      justify-content: center;      opacity: 0;      pointer-events: none;      transition: opacity 0.3s;    }    .tg-df-modal-backdrop.active {      opacity: 1;      pointer-events: auto;    }    .tg-df-modal {      background: #fff;      border-radius: 12px;      width: 90%;      max-width: 400px;      max-height: 80vh;      display: flex;      flex-direction: column;      box-shadow: 0 10px 40px rgba(0,0,0,0.2);      transform: translateY(20px);      transition: transform 0.3s;    }    .tg-df-modal-backdrop.active .tg-df-modal {      transform: translateY(0);    }    .tg-df-modal-header {      padding: 16px;      border-bottom: 1px solid #e2e8f0;      display: flex;      align-items: center;      justify-content: space-between;    }    .tg-df-modal-title {      font-size: 16px;      font-weight: 600;      margin: 0;    }    .tg-df-modal-close {      background: none;      border: none;      cursor: pointer;      padding: 4px;      color: #64748b;    }    .tg-df-modal-body {      padding: 16px;      overflow-y: auto;    }    .tg-df-voucher-item {      padding: 12px;      border: 1px dashed #cbd5e1;      border-radius: 8px;      margin-bottom: 10px;      background: #f8fafc;      display: flex;      align-items: center;      gap: 12px;      text-decoration: none;      color: inherit;      transition: background-color 0.2s, border-color 0.2s;    }    .tg-df-voucher-item:hover {      background: #f1f5f9;      border-color: #94a3b8;    }    .tg-df-voucher-item:last-child {      margin-bottom: 0;    }    .tg-df-voucher-logo {      width: 48px;      height: 48px;      object-fit: contain;      border-radius: 4px;      background: #fff;      border: 1px solid #e2e8f0;      flex-shrink: 0;    }    .tg-df-voucher-content {      flex: 1;      min-width: 0;    }    .tg-df-voucher-title {      font-size: 14px;      font-weight: 600;      margin: 0 0 4px 0;      line-height: 1.3;      color: #0f172a;    }    .tg-df-voucher-expiry {      font-size: 12px;      color: #64748b;      display: flex;      align-items: center;      gap: 4px;      margin-top: 6px;    }    .tg-df-voucher-code {      display: inline-flex;      align-items: center;      background: #f1f5f9;      border: 1px dashed #cbd5e1;      padding: 6px 10px;      font-family: monospace;      font-weight: 700;      font-size: 14px;      color: #0f172a;      border-radius: 4px;      margin-top: 8px;      cursor: pointer;      transition: all 0.2s ease;    }    .tg-df-voucher-code:hover {      background: #e2e8f0;      border-color: #94a3b8;    }    .tg-df-voucher-code.copied {      background: #ecfdf5;      border-color: #10b981;      color: #10b981;    }    .tg-df-voucher-cta {      display: inline-block;      margin-top: 8px;      font-size: 13px;      font-weight: 600;      color: #2563eb;      text-decoration: none;    }    .tg-df-card-title {      font-size: 15px;      font-weight: 400;      line-height: 1.4;      margin: 0 0 12px 0;      color: var(--tg-df-text);    }    .tg-df-card-footer {      margin-top: auto;      display: flex;      flex-direction: column;      width: 100%;    }    .tg-df-card-price-group {      display: flex;      flex-direction: row;      align-items: center;      gap: 8px;      margin-bottom: 12px;    }    .tg-df-card-price {      font-size: 16px;      font-weight: 700;      color: #dc2626; /* Red price */      line-height: 1;    }        .tg-df-card-msrp {      font-size: 13px;      color: var(--tg-df-text-muted);      text-decoration: line-through;    }    .tg-df-container .tg-df-card-cta {      display: flex;      align-items: center;      justify-content: center;      width: 100%;      box-sizing: border-box;      background-color: #1f69ff;      color: #ffffff;      font-size: 12px;      font-weight: 700;      text-transform: uppercase;      letter-spacing: 0.5px;      padding: 12px 16px;      border-radius: 0;      border: none;      cursor: pointer;      transition: background-color 0.2s ease;    }    .tg-df-card:hover .tg-df-card-cta,    .tg-df-card-cta:hover {      background-color: #1555cc;    }    /*       5. State & Skeleton Styles    */    .tg-df-message {      grid-column: 1 / -1;      text-align: center;      padding: 48px 24px;      color: var(--tg-df-text-muted);      font-size: 16px;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 8px;    }    @keyframes tg-df-shimmer {      0% { background-position: -200% 0; }      100% { background-position: 200% 0; }    }    .tg-df-skeleton {      background: linear-gradient(90deg, var(--tg-df-bg-secondary) 25%, #e2e8f0 50%, var(--tg-df-bg-secondary) 75%);      background-size: 200% 100%;      animation: tg-df-shimmer 1.5s infinite;      border-radius: 4px;    }    .tg-df-skeleton-img {      width: 100%;      height: 100%;      position: absolute;      top: 0; left: 0;    }        .tg-df-skeleton-text {      height: 16px;      margin-bottom: 8px;      width: 100%;    }    .tg-df-skeleton-text.short { width: 40%; }    .tg-df-skeleton-text.title { height: 20px; margin-bottom: 16px; }    /* Editor Floating Bar & Elements */    .tg-df-editor-bar {      position: sticky;      top: 120px;      z-index: 1000;      background: #111827;      color: #fff;      padding: 12px 16px;      border-radius: 8px;      margin-bottom: 16px;      display: flex;      align-items: center;      justify-content: space-between;      box-shadow: 0 4px 12px rgba(0,0,0,0.15);    }    .tg-df-editor-bar-text {      font-weight: 600;      font-size: 14px;    }    .tg-df-editor-copy-btn {      background: #10b981;      color: #fff;      padding: 6px 16px;      border: none;      border-radius: 4px;      font-weight: 600;      cursor: pointer;      display: flex;      align-items: center;      font-size: 13px;    }    .tg-df-editor-copy-btn:hover { background: #059669; }        .tg-df-deal-checkbox {      position: absolute;      top: 12px;      right: 12px;      z-index: 10;      width: 20px;      height: 20px;      cursor: pointer;      pointer-events: auto;    }    /*       6. Mobile List View (Stacks into a cleaner horizontal row/list)    */    @container tg-df (max-width: 599px) {      .tg-df-controls {        padding: 16px 16px 8px;      }            .tg-df-top-bar {        width: 100%;      }            .tg-df-settings-dropdown {        position: fixed;        top: auto;        bottom: 0;        left: 0;        right: 0;        width: 100%;        border-radius: 20px 20px 0 0;        padding: 24px;        box-shadow: 0 -8px 32px rgba(0,0,0,0.15);        z-index: 1000;        border: none;        border-top: 1px solid var(--tg-df-border);      }            .tg-df-settings-dropdown-backdrop.active {        background: rgba(0,0,0,0.4);      }            .tg-df-search-wrapper {        box-shadow: 0 0 16px rgba(0,0,0,0.08);      }                  .tg-df-sort-wrapper.tg-df-price-range-wrapper {        flex: 0 0 auto;        min-width: max-content;        width: auto;      }            .tg-df-sort-select, .tg-df-filter-select {        width: 100%;        text-align: left;        padding: 10px 24px 10px 32px;        background-position: right 8px center;        text-overflow: ellipsis;        white-space: nowrap;        overflow: hidden;      }      .tg-df-sort-icon {        left: 10px;      }      .tg-df-grid:not(.layout-grid):not(.layout-row),      .tg-df-grid.layout-row {        grid-template-columns: 1fr;        gap: 16px;      }            .tg-df-grid.tg-df-grid-auto {        padding-top: 24px;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card,      .tg-df-grid.layout-row .tg-df-card {        flex-direction: row;        align-items: stretch;        height: auto;        box-shadow: none; /* simple line on mobile if preferred, or keep */        border-bottom: 1px solid var(--tg-df-border);      }      .tg-df-grid.tg-df-grid-auto .tg-df-card:hover,      .tg-df-grid.layout-row .tg-df-card:hover {        box-shadow: none;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-image-box,      .tg-df-grid.layout-row .tg-df-card-image-box {        width: 120px;        min-width: 120px;        aspect-ratio: 3/4;        border-right: none;        padding: 12px;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-body,      .tg-df-grid.layout-row .tg-df-card-body {        padding: 12px;        justify-content: space-between;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-title,      .tg-df-grid.layout-row .tg-df-card-title {        font-size: 14px;        margin-bottom: 12px;      }      /* Single column mobile grid override */      .tg-df-grid.layout-grid {        grid-template-columns: 1fr;        gap: 16px;      }      .tg-df-grid.layout-grid .tg-df-card-image-box {        padding: 12px;      }      .tg-df-grid.layout-grid .tg-df-card-body {        padding: 10px;      }      .tg-df-grid.layout-grid .tg-df-card-title {        font-size: 13px;        margin-bottom: 8px;      }      .tg-df-grid.layout-grid .tg-df-card-price {        font-size: 14px;      }            .tg-df-card-footer {        flex-direction: column;        align-items: stretch;        gap: 0;        width: 100%;        min-width: 0;      }      .tg-df-card-merchant-pill {        margin-bottom: 4px;      }      .tg-df-card-price-group {        flex: 1 1 auto;        margin-bottom: 8px;      }      .tg-df-card-price {        font-size: 16px;      }      .tg-df-card-msrp {        display: block;       }      .tg-df-grid.layout-row .tg-df-card-cta,      .tg-df-container .tg-df-card-cta {        width: 100%;        max-width: none;        min-width: 0;        box-sizing: border-box;        padding: 8px 16px;        font-size: 12px;        flex: 0 0 auto;        text-align: center;        white-space: normal;        line-height: 1.2;      }    }    .tg-df-container.is-carousel {      min-height: 760px;      background-color: #E7F0FF;      padding: 0 0 24px 0;      border-radius: 24px;      width: 100vw;      max-width: 1200px;      position: relative;      left: 50%;      transform: translateX(-50%);    }    .tg-df-container.is-carousel.hide-header-details {      min-height: 480px;    }    /*       7. Carousel View Mode    */    .tg-df-container .tg-df-carousel-host {      /* Layout is now handled by container wrapper */    }    .tg-df-container .tg-df-carousel-eyebrow {      color: #1F69FF;      font-weight: 700;      font-size: 14px;      text-transform: uppercase;      letter-spacing: 1px;      padding: 24px 16px 0 16px;      display: none;    }    .tg-df-container .tg-df-carousel-query-title {      color: #011535;      font-size: 28px;      font-weight: 600;      padding: 0 16px 24px 16px;      line-height: 1.2;      display: none;    }    .tg-df-container .tg-df-carousel-blue-box {      background-color: transparent;      border-radius: 0;      padding: 24px 24px 0 24px;      margin: 0;      color: #1F69FF;          position: relative;      overflow: hidden;    }    .tg-df-container .tg-df-carousel-bg-circle-1 {      display: none;    }    .tg-df-container .tg-df-carousel-bg-circle-2 {      display: none;    }    .tg-df-container .tg-df-carousel-bg-circle-3 {      display: none;    }    .tg-df-container .tg-df-carousel-box-content {      position: relative;      z-index: 10;    }    .tg-df-container .tg-df-carousel-box-eyebrow {      background-color: transparent;      color: #1F69FF;      font-weight: 700;      font-size: 14px;      text-transform: uppercase;      letter-spacing: 1px;      display: inline-block;      padding: 0;      border-radius: 0;    }    .tg-df-container .tg-df-carousel-box-title {      font-size: 28px;      font-weight: 600;      line-height: 1.2;      margin-top: 8px;      color: #1e293b;    }    .tg-df-container .tg-df-countdown-wrapper {      position: absolute;      top: 0;      right: 0;      display: flex;      flex-direction: column;      align-items: flex-end;      gap: 12px;      transform: scale(0.67);      transform-origin: top right;    }    .tg-df-container .tg-df-countdown-title {      font-size: 14px;      font-weight: 600;      color: #011535;      margin: 0;    }    .tg-df-container .tg-df-countdown-blocks {      display: flex;      gap: 16px;    }    .tg-df-container .tg-df-countdown-item {      display: flex;      flex-direction: column;      align-items: center;      gap: 4px;    }    .tg-df-container .tg-df-countdown-box {      width: 59px;      height: 59px;      background: #03FE9E;      border-radius: 15px;      display: flex;      align-items: center;      justify-content: center;    }    .tg-df-container .tg-df-countdown-num {      font-family: 'Inter', sans-serif;      font-weight: 700;      font-size: 20px;      line-height: normal;      color: #011535;    }    .tg-df-container .tg-df-countdown-label {      font-family: 'Inter', sans-serif;      font-weight: 500;      font-size: 16px;      line-height: normal;      color: #1e293b;      text-transform: uppercase;    }    .tg-df-container .tg-df-carousel-box-subtitle {      font-size: 16px;      margin-top: 8px;      font-weight: 300;      color: #1e293b;      line-height: 24px;    }    .tg-df-container .tg-df-carousel-roundels-wrapper {      position: relative;      margin-top: 24px;      margin-left: -24px;      margin-right: -24px;    }    .tg-df-container .tg-df-carousel-roundels {      display: flex;      gap: 16px;      overflow-x: auto;            scrollbar-width: none;      padding-top: 12px;      padding-bottom: 24px;      padding-left: 24px;      padding-right: 24px;      margin-left: 0;      margin-right: 0;    }        .tg-df-container .tg-df-carousel-scroll-left,    .tg-df-container .tg-df-carousel-scroll-right {      position: absolute;      top: 50%;      transform: translateY(-50%);      height: 36px;      width: 36px;      display: flex;      align-items: center;      justify-content: center;      border-radius: 50%;      background-color: #ffffff;      border: 1px solid #e2e8f0;      box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);      color: #1F69FF;      cursor: pointer;      transition: all 0.2s;      margin-top: -4px;      z-index: 20;    }    .tg-df-container .tg-df-carousel-scroll-left { left: 8px; }    .tg-df-container .tg-df-carousel-scroll-right { right: 8px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-left { left: 0px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-right { right: 0px; }    .tg-df-carousel-filters-outer { margin-left: -24px; margin-right: -24px; padding-left: 24px; padding-right: 24px; }    .tg-df-grid-wrapper { position: relative; }    @container tg-df (max-width: 599px) { .tg-df-carousel-filters-outer { margin-left: -16px; margin-right: -16px; padding-left: 16px; padding-right: 16px; } }        .tg-df-container .tg-df-carousel-scroll-left:hover,    .tg-df-container .tg-df-carousel-scroll-right:hover {      background-color: rgba(255, 255, 255, 0.6);    }    .tg-df-container .tg-df-carousel-roundels::-webkit-scrollbar {      display: none;    }    .tg-df-container .tg-df-roundel {      display: flex;      flex-direction: column;      align-items: center;      gap: 8px;      cursor: pointer;      min-width: 120px;      flex-shrink: 0;    }    .tg-df-container .tg-df-roundel-img-box {      width: 120px;      height: 120px;      border-radius: 50%;      background: white;      display: flex;      align-items: center;      justify-content: center;      overflow: hidden;      box-shadow: 0px 3px 14px 0px rgba(30, 41, 59, 0.08);      transition: box-shadow 0.2s;    }    .tg-df-container .tg-df-roundel:hover .tg-df-roundel-img-box {      box-shadow: 0 0 0 2px #E7F0FF, 0 0 0 4px #1F69FF;    }    .tg-df-container .tg-df-roundel.active .tg-df-roundel-img-box {      box-shadow: 0 0 0 2px #E7F0FF, 0 0 0 4px #1F69FF;    }    .tg-df-container .tg-df-roundel:hover .tg-df-roundel-img-box img {      transform: scale(1.08);    }    .tg-df-container .tg-df-roundel-img-box img {      width: 100%;      height: 100%;      object-fit: contain;      padding: 10px;      box-sizing: border-box;      transition: transform 0.3s ease;    }    .tg-df-container .tg-df-roundel-label {      font-size: 13px;      font-weight: 400;      color: #1e293b;      text-align: center;    }    .tg-df-container .tg-df-carousel-filters-label {      font-size: 16px;      font-weight: 400;      color: #1e293b;      white-space: nowrap;      margin-right: 4px;    }    .tg-df-container .tg-df-carousel-filters-wrap {      display: flex;      align-items: center;      flex-wrap: nowrap;      gap: 8px;      margin-top: 8px;      overflow-x: auto;      scrollbar-width: none;      -webkit-overflow-scrolling: touch;      padding-bottom: 8px;      margin-left: -24px;      margin-right: -24px;      padding-left: 24px;      padding-right: 24px;    }    .tg-df-container .tg-df-carousel-filters-wrap::-webkit-scrollbar {      display: none;    }        .tg-df-container .tg-df-carousel-filter-btn img,    .tg-df-container .tg-df-carousel-filter-btn picture {      height: 20px;      width: 20px;      object-fit: contain;      object-position: center;      display: inline-flex;      align-items: center;      justify-content: center;      margin-right: 6px;    }    .tg-df-container .tg-df-carousel-filter-btn picture img {      margin-right: 0;      height: 100%;      width: 100%;    }    .tg-df-container .tg-df-carousel-filter-btn img.active-img,    .tg-df-container .tg-df-carousel-filter-btn picture:has(.active-img) {      display: none;    }    .tg-df-container .tg-df-carousel-filter-btn:hover img.inactive-img,    .tg-df-container .tg-df-carousel-filter-btn.active img.inactive-img,    .tg-df-container .tg-df-carousel-filter-btn:hover picture:has(.inactive-img),    .tg-df-container .tg-df-carousel-filter-btn.active picture:has(.inactive-img) {      display: none;    }    .tg-df-container .tg-df-carousel-filter-btn:hover img.active-img,    .tg-df-container .tg-df-carousel-filter-btn.active img.active-img,    .tg-df-container .tg-df-carousel-filter-btn:hover picture:has(.active-img),    .tg-df-container .tg-df-carousel-filter-btn.active picture:has(.active-img) {      display: inline-flex;    }    .tg-df-container .tg-df-carousel-filter-btn {      background: #ffffff;      border: 2px solid #1e293b;      color: #1e293b;      border-radius: 24px;      padding: 6px 16px;      font-size: 14px;      font-weight: 600;      cursor: pointer;      transition: all 0.2s;      flex-shrink: 0;      white-space: nowrap;    }    .tg-df-container .tg-df-carousel-filter-btn svg {      margin-right: 6px;    }    .tg-df-container .tg-df-carousel-filter-btn {      display: inline-flex;      align-items: center;    }    .tg-df-container .tg-df-carousel-filter-btn:hover {      background: #1e293b;      color: white;      border-color: #1e293b;    }    .tg-df-container .tg-df-carousel-filter-btn.active {      background: #1e293b;      color: white;      border-color: #1e293b;    }        .tg-df-grid.carousel-compact {      display: flex;      flex-wrap: nowrap;      overflow-x: auto;      gap: 16px;      padding: 16px 24px;      align-items: stretch;      scrollbar-width: none;    }    .tg-df-grid.carousel-compact::-webkit-scrollbar {      display: none;    }    .tg-df-grid.carousel-compact .tg-df-card {      flex: 0 0 auto;      width: 200px;      min-height: auto;      height: auto;      display: flex;      flex-direction: column;      border-radius: 15px;      border: none;      box-shadow: 0 0 16px rgba(0,0,0,0.08);      overflow: visible;    }    .tg-df-grid.carousel-compact .tg-df-card-image-box {      padding: 12px;      background-color: transparent;      border-radius: 15px 15px 0 0;      height: 130px;    }    .tg-df-grid.carousel-compact .tg-df-card-image {      mix-blend-mode: normal;    }    .tg-df-grid.carousel-compact .tg-df-card-discount-badge {      border-radius: 0;      top: 0px;      left: 0px;      padding: 4px 8px;      font-size: 11px;    }    .tg-df-grid.carousel-compact .tg-df-card-body {      padding: 8px 12px 12px 12px;    }    .tg-df-grid.carousel-compact .tg-df-card-title {      font-size: 14px;      font-weight: 400;      margin-bottom: 8px;      color: #011535;    }    .tg-df-grid.carousel-compact .tg-df-card-body:not(:has(.tg-df-card-stars)):not(:has(.tg-df-tag-prime)):not(:has(.tg-df-coupon-wrapper:not([style*="none"]))) > .tg-df-card-title,    .tg-df-grid.carousel-compact .tg-df-card-body:not(:has(.tg-df-card-stars)):has(> .tg-df-card-title:first-child) > .tg-df-card-title {    }    .tg-df-grid.carousel-compact .tg-df-card-cta {      border-radius: 5px;      padding: 8px 10px;      margin-top: 4px;      background-color: #1F69FF;    }    .tg-df-grid.carousel-compact .tg-df-card-price-group {      margin-bottom: 2px;    }    .tg-df-grid.carousel-compact .tg-df-card-merchant-pill {      margin-bottom: 2px;    }    @container tg-df (max-width: 599px) {      .tg-df-container .tg-df-carousel-blue-box-title {        font-size: 24px;      }      .tg-df-container .tg-df-countdown-title {        display: none;      }      .tg-df-container .tg-df-countdown-wrapper {        position: absolute;        top: 0;        right: 0;        align-items: flex-end;        transform: scale(0.40);        transform-origin: top right;      }      .tg-df-container .tg-df-roundel {        min-width: 88px;      }      .tg-df-container .tg-df-roundel-img-box {        width: 88px;        height: 88px;      }    }    /* REPLICA BLOCK STYLES */    .tg-df-grid.layout-replica-2 { grid-template-columns: repeat(2, 1fr) !important; gap: 20px; }    .tg-df-grid.layout-replica-1 { grid-template-columns: 1fr !important; gap: 20px; }        .tg-df-container .hawk-deal-widget-container { border-bottom: 1px solid #e5e7eb; display: flex; flex-direction: column; margin: 0; padding: 20px 0; box-sizing: border-box; font-family: inherit; }    .tg-df-container .hawk-deal-widget-wrap { display: flex; flex-direction: row; align-items: flex-start; width: 100%; gap: 24px; }    .tg-df-container .hawk-deal-widget-image-container { display: flex; flex-shrink: 0; justify-content: center; width: 160px; height: 160px; align-items: center; background: white; margin-bottom: 0px; }    .tg-df-container .hawk-deal-widget-title-product-title { color: #111827; font-size: 18px; font-weight: 700; line-height: 1.4; display: inline; }    .tg-df-container .hawk-deal-widget-title-price { font-size: 18px; font-weight: 700; line-height: 1.4; white-space: nowrap; color: #2563eb; }    .tg-df-container .hawk-deal-widget-title-price-now { font-weight: 700; }    .tg-df-container .hawk-deal-widget-title-retailer-price:hover { text-decoration: underline; }    .tg-df-container .hawk-deal-widget-title-retailer { font-size: 18px; font-weight: 700; line-height: 1.4; color: #2563eb; }    .tg-df-container .hawk-deal-widget-title-was-price { color: #dc2626; font-size: 16px; font-weight: 500; line-height: 1.4; text-decoration: line-through; white-space: nowrap; margin-left: 8px; margin-right: 8px; }    .tg-df-container .hawk-deal-widget-text-body-container { position: relative; width: 100%; box-sizing: border-box; }    .tg-df-container .hawk-deal-widget-text-body-main { font-size: 16px; width: 100%; margin-bottom: 12px; }    .tg-df-container .hawk-deal-widget-text-body-description { display: block; font-size: 15px; margin-top: 12px; color: #4b5563; line-height: 1.6; }    .tg-df-container .hawk-deal-widget-text-body-description p { margin: 0; line-height: 1.6; }    .tg-df-container .hawk-deal-widget-text-cta-container { display: flex; flex-direction: column; gap: 12px; width: 100%; flex: 1; min-width: 0; box-sizing: border-box; }    .tg-df-container .hawk-deal-widget-footer { display: flex; justify-content: flex-end; width: 100%; margin-top: auto; }    .tg-df-container .hawk-deal-widget-button-wrapper { display: flex; flex-direction: column; align-items: flex-end; justify-content: flex-end; width: 100%; }    .tg-df-container .hawk-deal-widget-preferred-partner-wrapper { display: flex; flex-direction: row; }        @container tg-df (min-width: 600px) {      .tg-df-mobile-only { display: none !important; }    }    @container tg-df (max-width: 599px) {      .tg-df-desktop-only { display: none !important; }      .tg-df-grid.layout-replica-2 { grid-template-columns: 1fr !important; }      .tg-df-grid.savings-squad-cards { grid-template-columns: 1fr !important; display: flex; flex-direction: column; }    }    .tg-df-grid.savings-squad-cards .tg-df-card-title {      -webkit-line-clamp: unset !important;      display: block !important;      overflow: visible !important;    }    @container tg-df (max-width: 500px) {      .tg-df-container .hawk-deal-widget-wrap { display: block; }      .tg-df-container .hawk-deal-widget-image-container { display: block; float: left; margin: 0 16px 8px 0; width: 120px; max-width: 120px; height: auto; align-items: normal; justify-content: normal; }      .tg-df-container .hawk-deal-widget-text-cta-container { display: block; text-align: left; }      .tg-df-container .hawk-deal-widget-footer { display: block; margin-top: 16px; clear: both; width: 100%; }      .tg-df-container .hawk-deal-widget-button-wrapper { display: block; width: 100%; }      .tg-df-container .hawk-deal-widget-button-wrapper .hawk-deal-widget-preferred-partner-wrapper { display: block; width: 100%; }      .tg-df-container .hawk-affiliate-link-deal-button { box-sizing: border-box !important; display: flex !important; max-width: none !important; width: 100% !important; margin: 0 !important; }    }        .tg-df-container .hawk-affiliate-link-deal-button {       align-items: center; background-color: #1f69ff; box-sizing: border-box; color: #ffffff !important; display: flex; font-size: 14px; font-weight: 700; justify-content: center; letter-spacing: 0.5px; line-height: 1; min-width: 160px; padding: 14px 24px; text-align: center; text-decoration: none; text-transform: uppercase; width: 100%; word-break: normal; border-radius: 4px; border: 0; transition: background-color 0.2s;     }    .tg-df-container .hawk-affiliate-link-deal-button:hover { background-color: #0056e0; text-decoration: none; }    .tg-df-container .hawk-lazy-image-deal-widget { display: block; height: auto; margin: auto; max-height: 160px; max-width: 100%; mix-blend-mode: multiply; object-fit: contain; }    .tg-df-container .hawk-deal-widget-text-cta-container a { color: #2563eb; text-decoration: none; display: inline; }    .tg-df-container .hawk-deal-widget-text-cta-container a:hover { text-decoration: underline; }    .tg-df-container .hawk-deal-widget-text-cta-container a:has(.hawk-deal-widget-title-product-title) { color: #111827; }    .tg-df-container .hawk-deal-widget-text-cta-container a:hover .hawk-deal-widget-title-product-title,    .tg-df-container .hawk-deal-widget-text-cta-container a:hover .hawk-deal-widget-title-retailer-price { text-decoration: underline; }    .tg-df-savings-squad-header { margin-bottom: 24px; text-align: center; display: none; }    .tg-df-banner-img-desktop { display: block; width: 100%; height: auto; margin-bottom: 32px; }    .tg-df-banner-img-mobile { display: none; width: 100%; height: auto; margin-bottom: 32px; }    @container tg-df (max-width: 600px) {      .tg-df-banner-img-desktop { display: none; }      .tg-df-banner-img-mobile { display: block; }    }    .tg-df-header-title { font-size: 28px; font-weight: 700; color: var(--tg-df-text); margin: 32px 0 12px 0; line-height: 1.3; }    .tg-df-header-subtitle { font-size: 16px; color: var(--tg-df-text-muted); margin: 0 0 32px 0; line-height: 1.5; }  \x3C/style>  \x3C!-- Widget Container --\x3E  \x3Cdiv class="tg-df-container" id="signal-deals-finder-root">    \x3Cdiv class="tg-df-savings-squad-header" id="tg-df-savings-squad-header">      \x3Cpicture>        \x3Cimg src="https://cdn.mos.cms.futurecdn.net/flexiimages/xkh2og7m3d1778189998.png" alt="Deals Banner" class="tg-df-banner-img-desktop" />        \x3Cimg src="https://cdn.mos.cms.futurecdn.net/flexiimages/gmak6rtdf41778245089.png" alt="Deals Banner Mobile" class="tg-df-banner-img-mobile" />      \x3C/picture>      \x3Cdiv class="tg-df-header-text">        \x3Ch2 class="tg-df-header-title" id="tg-df-header-title">Editor's Choice Deals\x3C/h2>        \x3Cp class="tg-df-header-subtitle" id="tg-df-header-subtitle">Discover the best discounts currently available, curated daily by the Tom's Guide Savings Squad.\x3C/p>      \x3C/div>    \x3C/div>    \x3C!-- Editor Floating Bar --\x3E    \x3Cdiv class="tg-df-editor-bar" id="tg-df-editor-bar" style="display:none;">      \x3Cdiv class="tg-df-editor-bar-text" style="display: flex; align-items: center;">        \x3Cspan id="tg-df-selected-count">0\x3C/span>\x26nbsp;Deals Selected        \x3Cbutton class="tg-df-editor-clear-btn" id="tg-df-editor-clear" type="button" style="margin-left: 12px; font-size: 13px; color: #9ca3af; background: none; border: none; cursor: pointer; text-decoration: underline;">Clear All\x3C/button>      \x3C/div>      \x3Cbutton class="tg-df-editor-copy-btn" id="tg-df-editor-copy" type="button">        \x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2">\x3C/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">\x3C/path>\x3C/svg>        Copy to CMS      \x3C/button>    \x3C/div>    \x3Cdiv class="tg-df-carousel-host" id="tg-df-carousel-host" style="display: none;">      \x3Cdiv class="tg-df-carousel-eyebrow">DEAL FINDER\x3C/div>      \x3Cdiv class="tg-df-carousel-query-title" id="tg-df-carousel-title-label">Best Deals\x3C/div>            \x3Cdiv class="tg-df-carousel-blue-box">        \x3Cdiv class="tg-df-carousel-bg-circle-1" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-bg-circle-2" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-bg-circle-3" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-box-content">          \x3Cdiv class="tg-df-countdown-wrapper" id="tg-df-countdown-wrapper" style="display:none;">            \x3Cdiv class="tg-df-countdown-title" id="tg-df-countdown-title">Prime Day starts in\x3C/div>            \x3Cdiv class="tg-df-countdown-blocks">              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-days">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">DAYS\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-hrs">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">HRS\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-min">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">MIN\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-sec">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">SEC\x3C/div>\x3C/div>            \x3C/div>          \x3C/div>          \x3Cdiv class="tg-df-carousel-box-eyebrow">DEAL FINDER\x3C/div>          \x3Cdiv class="tg-df-carousel-box-title">Find Deals Fast\x3C/div>          \x3Cdiv class="tg-df-carousel-box-subtitle">The latest deals from the biggest retailers, all in one place\x3C/div>                    \x3Cdiv class="tg-df-carousel-roundels-wrapper">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-roundels').scrollBy({left: -200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \x3Cdiv class="tg-df-carousel-roundels">                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Televisions" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/wcMxTsHgqu3roMbAx7RLnT-132-100.png" alt="TVs" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">TVs\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Phones" data-pr="over50">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/G3KGaRGzj24F6PUsw4bWpT-132-100.png" alt="Phones" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Phones\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Computing" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/znNvsLzx8NEgNkD9HSFSnT-132-100.png" alt="Computing" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Computing\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Gaming" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/Pgew8yaRQeZFHqHjTzvBnT-132-100.png" alt="Gaming" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Gaming\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Mattresses" data-pr="over500">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/cW7xsaLyesxkHFVSiC4kmT-132-100.png" alt="Mattresses" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Mattresses\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Audio" data-pr="over30">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/pCvBVHuhaQVjKt3VgCjbqT-132-100.png" alt="Audio" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Audio\x3C/span>            \x3C/div>                  \x3C/div>        \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" onclick="this.parentElement.querySelector('.tg-df-carousel-roundels').scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>        \x3C/div>        \x3C/div>        \x3Cdiv class="tg-df-carousel-filters-outer" style="position: relative;">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').scrollBy({left: -200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \x3Cdiv class="tg-df-carousel-filters-wrap">                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="0">All\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-ot="amazon_lightning">              \x3Cimg src="https://cdn.mos.cms.futurecdn.net/HqAui7w97ft2NPqBtQ5r38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/yWPQ5yyQRhUwVKzGwYbh38-600-100.png" class="active-img" alt="" /> Lightning deals\x3C/button>            \x3Cbutton class="tg-df-carousel-filter-btn" data-ot="amazon_prime">              \x3Cimg src="https://cdn.mos.cms.futurecdn.net/fwoVXvL79turN3Ph535m38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/u75QjVpt3w2EsMimJiRo38-600-100.png" class="active-img" alt="" /> Prime deals\x3C/button>            \x3Cbutton class="tg-df-carousel-filter-btn" data-d="10">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 10% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="15">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 15% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="25">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 25% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-pr="under50">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-badge-dollar-sign">\x3Cpath d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z">\x3C/path>\x3Cpath d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8">\x3C/path>\x3Cpath d="M12 18V6">\x3C/path>\x3C/svg>            Under $50\x3C/button>        \x3C/div>        \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>      \x3C/div>    \x3C/div>    \x3C/div>      \x3C!-- Search & Filter Controls --\x3E      \x3Cdiv class="tg-df-top-bar" id="tg-df-top-bar" style="position: relative; z-index: 100; margin: 0 auto 20px;">        \x3Cdiv class="tg-df-search-wrapper">          \x3Cinput type="text" class="tg-df-search-input" placeholder="Search for deals, products, or brands...">          \x3Cbutton type="button" class="tg-df-search-btn" aria-label="Search">              \x3Csvg class="tg-df-search-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">                \x3Cpath d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>              \x3C/svg>          \x3C/button>          \x3Cdiv class="tg-df-autocomplete-dropdown" id="tg-df-autocomplete">\x3C/div>        \x3C/div>      \x3C/div>    \x3Cdiv class="tg-df-controls" id="tg-df-controls" style="display:flex;">              \x3Cdiv class="tg-df-filters-container" style="position: relative; width: 100%; max-width: 800px; margin: 0 auto;">          \x3Cbutton class="tg-df-scroll-btn left" style="display: none;" onclick="this.parentElement.querySelector('.tg-df-filters').scrollBy({left: -200, behavior: 'smooth'})">            \x3Csvg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\x3Cpath d="M15 18l-6-6 6-6"/>\x3C/svg>          \x3C/button>          \x3Cbutton class="tg-df-scroll-btn right" style="display: none;" onclick="this.parentElement.querySelector('.tg-df-filters').scrollBy({left: 200, behavior: 'smooth'})">            \x3Csvg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\x3Cpath d="M9 18l6-6-6-6"/>\x3C/svg>          \x3C/button>          \x3Cdiv class="tg-df-filters">          \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-category-filter-wrapper" style="display: none;">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-category-filter" aria-label="Category">            \x3Coption value="all">All Categories\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper tg-df-multiselect-container" id="tg-df-brand-filter-wrapper" style="display:none;">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M4.25 5.61C6.27 8.2 10 13 10 13v6c0 .55.45 1 1 1h2c.55 0 1-.45 1-1v-6s3.72-4.8 5.74-7.39A.998.998 0 0 0 18.95 4H5.04c-.83 0-1.3.95-.79 1.61z"/>          \x3C/svg>          \x3Cdiv class="tg-df-filter-select tg-df-multiselect-trigger" id="tg-df-brand-trigger" tabindex="0">            Any Brand          \x3C/div>          \x3Cdiv class="tg-df-multiselect-dropdown" id="tg-df-brand-dropdown">            \x3C!-- Populated via script --\x3E          \x3C/div>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper tg-df-price-range-wrapper" id="tg-df-custom-price-wrapper" style="display: flex; align-items:center; justify-content:center; padding: 10px 20px; gap: 8px; border: 1px solid var(--tg-df-border); border-radius: 100px; background-color: var(--tg-df-bg);">          \x3Cspan style="font-size:14px; font-weight:500; color:var(--tg-df-text-primary);">Price\x3C/span>          \x3Cinput type="number" class="tg-df-price-input" id="tg-df-custom-price-min" placeholder="Min" style="width: 48px; background: transparent; border: none; color: var(--tg-df-text-primary); outline: none; font-size: 14px; text-align: center; padding: 0;">          \x3Cspan style="color:var(--tg-df-text-muted)">-\x3C/span>          \x3Cinput type="number" class="tg-df-price-input" id="tg-df-custom-price-max" placeholder="Max" style="width: 48px; background: transparent; border: none; color: var(--tg-df-text-primary); outline: none; font-size: 14px; text-align: center; padding: 0;">        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-legacy-price-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-price-filter" aria-label="Filter Prices">            \x3Coption value="all">All Prices\x3C/option>            \x3Coption value="under50">Under $50\x3C/option>            \x3Coption value="50_100">$50 - $100\x3C/option>            \x3Coption value="100_200">$100 - $200\x3C/option>            \x3Coption value="200_500">$200 - $500\x3C/option>            \x3Coption value="over500">Over $500\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-discount-filter-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">            \x3Cpath d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-discount-filter" aria-label="Discount Amount">            \x3Coption value="all">Any discount\x3C/option>            \x3Coption value="5">Min 5%\x3C/option>            \x3Coption value="10">Min 10%\x3C/option>            \x3Coption value="15">Min 15%\x3C/option>            \x3Coption value="20">Min 20%\x3C/option>            \x3Coption value="25">Min 25%\x3C/option>            \x3Coption value="30">Min 30%\x3C/option>            \x3Coption value="40">Min 40%\x3C/option>            \x3Coption value="50">Min 50%\x3C/option>            \x3Coption value="60">Min 60%\x3C/option>            \x3Coption value="70">Min 70%\x3C/option>          \x3C/select>          \x3C/div>        \x3C/div>        \x3C/div>      \x3C/div>    \x3C!-- Deals Grid Wrapper --\x3E    \x3Cdiv class="tg-df-grid-wrapper tg-df-carousel-cards-wrapper" id="tg-df-grid-wrapper">      \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').scrollBy({left: -200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>      \x3Cdiv class="tg-df-grid" id="tg-df-grid">        \x3C!-- Content populated by JavaScript --\x3E      \x3C/div>      \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>    \x3C/div>        \x3C!-- Vouchers Modal --\x3E    \x3Cdiv class="tg-df-modal-backdrop" id="tg-df-vouchers-modal">      \x3Cdiv class="tg-df-modal">        \x3Cdiv class="tg-df-modal-header">          \x3Ch3 class="tg-df-modal-title" id="tg-df-vouchers-title">Available Coupons & Deals\x3C/h3>          \x3Cbutton class="tg-df-modal-close" id="tg-df-vouchers-close">            \x3Csvg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">              \x3Cline x1="18" y1="6" x2="6" y2="18">\x3C/line>              \x3Cline x1="6" y1="6" x2="18" y2="18">\x3C/line>            \x3C/svg>          \x3C/button>        \x3C/div>        \x3Cdiv class="tg-df-modal-body" id="tg-df-vouchers-content">          \x3C!-- Vouchers injected here --\x3E        \x3C/div>      \x3C/div>    \x3C/div>  \x3C/div>`;      if (!template) {        template = document.createElement('template');        template.innerHTML = rawTemplate;      }      let shadowRoot = null;      if (hostContainer && template) {        hostContainer.setAttribute('data-initialized', 'true');        shadowRoot = hostContainer.attachShadow({ mode: 'open' });        shadowRoot.appendChild(template.content.cloneNode(true));      }      class DealsFinderWidget {        constructor(config) {          this.rootNode = config.rootNode || document;          this.hostContainer = config.hostContainer || null;          this.rootId = config.rootId || 'signal-deals-finder-root';          this.root = this.rootNode.querySelector('#' + this.rootId);          if (!this.root) return;          this.widgetId = (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : 'widget-' + Date.now() + '-' + Math.random().toString(36).slice(2);          this.grid = this.root.querySelector('#tg-df-grid');          this.tagsContainer = this.root.querySelector('#tg-df-tags-container');          this.categoryFilter = this.root.querySelector('#tg-df-category-filter');          this.categoryFilterWrapper = this.root.querySelector('#tg-df-category-filter-wrapper');          this.searchInput = this.root.querySelector('.tg-df-search-input');          this.autocompleteDropdown = this.root.querySelector('#tg-df-autocomplete');          this.sortSelect = this.root.querySelector('.tg-df-sort-select');          this.searchBtn = this.root.querySelector('.tg-df-search-btn');                    this.settingsToggle = this.root.querySelector('#tg-df-settings-toggle');          this.settingsPanel = this.root.querySelector('#tg-df-settings-panel');          this.settingsBackdrop = this.root.querySelector('#tg-df-settings-backdrop');          this.regionSelect = this.root.querySelector('#tg-df-region-select');          this.retailerSelect = this.root.querySelector('#tg-df-retailer-select');          this.offerTypeSelect = this.root.querySelector('#tg-df-offer-type-select');          this.viewModeSelect = this.root.querySelector('#tg-df-view-mode-select');          this.rowsSelect = this.root.querySelector('#tg-df-rows-select');          this.dealModeToggle = this.root.querySelector('#tg-df-deal-mode');          this.editorModeToggle = this.root.querySelector('#tg-df-editor-mode');          this.priceFilter = this.root.querySelector('#tg-df-price-filter');          this.discountFilter = this.root.querySelector('#tg-df-discount-filter');                    this.editorBar = this.root.querySelector('#tg-df-editor-bar');          this.editorSelectedCount = this.root.querySelector('#tg-df-selected-count');          this.editorCopyBtn = this.root.querySelector('#tg-df-editor-copy');          this.editorClearBtn = this.root.querySelector('#tg-df-editor-clear');                    this.apiUrl = 'https://search-api.fie.future.net.uk/widget.php';          this.deals = [];          this.displayLimit = 12;          this.airedaleArticles = null;          this.airedaleTags = [];          this.airedaleTagCounts = {};          this.activeDealTag = null;          this.selectedBrands = [];          this.currentQuery = '';          this.editorMode = this.hostContainer ? this.hostContainer.hasAttribute('data-editor-mode') : false;          this.viewModeOverride = this.hostContainer ? this.hostContainer.getAttribute('data-view-mode') : null;          this.selectedDeals = new Map();                    this.brandFilterWrapper = this.root.querySelector('#tg-df-brand-filter-wrapper');          this.brandTrigger = this.root.querySelector('#tg-df-brand-trigger');          this.brandDropdown = this.root.querySelector('#tg-df-brand-dropdown');                    this.customPriceWrapper = this.root.querySelector('#tg-df-custom-price-wrapper');          this.customPriceMin = this.root.querySelector('#tg-df-custom-price-min');          this.customPriceMax = this.root.querySelector('#tg-df-custom-price-max');          this.legacyPriceWrapper = this.root.querySelector('#tg-df-legacy-price-wrapper');          this.discountFilterWrapper = this.root.querySelector('#tg-df-discount-filter-wrapper');          this.initResizeObserver();          this.init();        }        getViewMode() {          console.log("DEBUG getViewMode -> override:", this.viewModeOverride, "editorMode:", this.editorMode);          if (this.viewModeOverride && (!this.editorMode || !this.viewModeSelect)) {            return this.viewModeOverride;          }          return (this.viewModeSelect && this.viewModeSelect.value) ? this.viewModeSelect.value : (this.viewModeOverride || 'auto');        }        applyLayoutMode() {          if (!this.grid) return;          const mode = this.getViewMode();          console.log("[DEBUG] applyLayoutMode CALLED! mode=", mode);          this.grid.classList.remove('layout-row', 'layout-grid', 'tg-df-grid-auto', 'carousel-compact', 'layout-replica-1', 'layout-replica-2');                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          const showHeaderDetails = params.get('show_header_details') !== 'false';          const carouselHost = this.root.querySelector('#tg-df-carousel-host');          const controlsDiv = this.root.querySelector('#tg-df-controls');          const topBarDiv = this.root.querySelector('#tg-df-top-bar');          const headerElement = this.root.querySelector('#tg-df-savings-squad-header');          if (headerElement) {             headerElement.style.display = (mode === 'savings_squad' && showHeaderDetails) ? 'block' : 'none';          }          if (mode === 'carousel') {             this.grid.classList.add('carousel-compact');             if (carouselHost) carouselHost.style.display = 'block';             if (controlsDiv) controlsDiv.style.display = 'none';             if (topBarDiv) topBarDiv.style.display = 'none';             if (this.root.classList.contains('tg-df-container')) {               this.root.classList.add('is-carousel');             }          } else {             if (carouselHost) carouselHost.style.display = 'none';             if (controlsDiv) controlsDiv.style.display = 'flex';             if (topBarDiv) topBarDiv.style.display = 'block';             if (this.root.classList.contains('tg-df-container')) {               this.root.classList.remove('is-carousel');             }          }          if (mode === 'grid') {            this.grid.classList.add('layout-grid');          } else if (mode === 'row') {            this.grid.classList.add('layout-row');          } else if (mode === 'savings_squad') {            this.grid.classList.add('tg-df-grid-auto', 'savings-squad-cards');          } else if (mode !== 'carousel') {            this.grid.classList.add('tg-df-grid-auto');          }                    const settingsWrapper = this.root.querySelector('.tg-df-settings-wrapper');          if (settingsWrapper) {            settingsWrapper.style.display = mode === 'auto' ? 'none' : 'block';          }          if (this.customPriceWrapper) {             this.customPriceWrapper.style.display = mode === 'auto' ? 'flex' : 'none';          }          if (this.legacyPriceWrapper) {             this.legacyPriceWrapper.style.display = mode === 'auto' ? 'none' : 'flex';          }          if (this.discountFilterWrapper) {             this.discountFilterWrapper.style.display = mode === 'auto' ? 'none' : 'flex';          }        }        initResizeObserver() {          try {            if (window.parent === window) return;          } catch (e) {            // cross origin frame check threw          }          const emitHeight = () => {            try {              const height = document.documentElement.scrollHeight || document.body.scrollHeight;              const msg = { type: 'embed-size', height: height };              if (window.parent && window.parent !== window) {                window.parent.postMessage(msg, '*');                window.parent.postMessage(JSON.stringify({ ...msg, sentinel: 'amp' }), '*');              }            } catch (e) {}          };                    if (window.ResizeObserver) {            try {              const ro = new ResizeObserver(() => emitHeight());              ro.observe(document.body);              if (this.root) ro.observe(this.root);            } catch(e){ console.warn(e); }          }          window.addEventListener('resize', emitHeight);          setTimeout(emitHeight, 300);        }        initCountdown() {          this.cdWrapper = this.root.querySelector('#tg-df-countdown-wrapper');                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          this.showCountdown = params.get('show_countdown') === 'true';          const showHeaderDetails = params.get('show_header_details') !== 'false';          const eyebrow = this.root.querySelector('.tg-df-carousel-box-eyebrow');          const title = this.root.querySelector('.tg-df-carousel-box-title');          const subtitle = this.root.querySelector('.tg-df-carousel-box-subtitle');          if (!showHeaderDetails) {            let containerElement = this.root.classList.contains('tg-df-container') ? this.root : this.root.querySelector('.tg-df-container');            if (containerElement) containerElement.classList.add('hide-header-details');            if (eyebrow) eyebrow.style.display = 'none';            if (title) title.style.display = 'none';            if (subtitle) subtitle.style.display = 'none';          }          if (!this.cdWrapper) return;          this.cdTitle = this.root.querySelector('#tg-df-countdown-title');          this.cdDays = this.root.querySelector('#tg-df-cd-days');          this.cdHrs = this.root.querySelector('#tg-df-cd-hrs');          this.cdMin = this.root.querySelector('#tg-df-cd-min');          this.cdSec = this.root.querySelector('#tg-df-cd-sec');          this.updateCountdown();          this.cdInterval = setInterval(() => this.updateCountdown(), 1000);        }        updateCountdown() {          if (!this.cdWrapper) return;          if (!this.showCountdown) {            this.cdWrapper.style.display = 'none';            return;          }          const area = this.getAreaCode();          let offset = '-04:00';          if (['DE', 'FR', 'IT', 'ES', 'NL'].includes(area)) {             offset = '+02:00';          } else if (['GB', 'IE', 'UK'].includes(area)) {             offset = '+01:00';          }          const startTime = new Date('2026-06-23T00:00:00' + offset).getTime();          const endTime = new Date('2026-06-26T00:00:00' + offset).getTime();          const now = Date.now();          let targetTime = 0;          if (now < startTime) {             targetTime = startTime;             if (this.cdTitle) this.cdTitle.textContent = 'Prime Day starts in';             this.cdWrapper.style.display = 'flex';          } else if (now < endTime) {             targetTime = endTime;             if (this.cdTitle) this.cdTitle.textContent = 'Prime Day ends in';             this.cdWrapper.style.display = 'flex';          } else {             this.cdWrapper.style.display = 'none';             if (this.cdInterval) clearInterval(this.cdInterval);             return;          }          const diff = Math.max(0, targetTime - now);          const d = Math.floor(diff / (1000 * 60 * 60 * 24));          const h = Math.floor((diff / (1000 * 60 * 60)) % 24);          const m = Math.floor((diff / 1000 / 60) % 60);          const s = Math.floor((diff / 1000) % 60);          if (this.cdDays) this.cdDays.textContent = d;          if (this.cdHrs) this.cdHrs.textContent = h;          if (this.cdMin) this.cdMin.textContent = m;          if (this.cdSec) this.cdSec.textContent = s;        }        init() {          this.initCountdown();          try {            initAnalytics();          } catch (e) {            console.warn('Deals Widget Analytics Error:', e);          }                    this.bindEvents();                    let initialQuery = '';                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          let initialViewMode = params.get('view_mode');          if (!this.viewModeOverride && initialViewMode) {            this.viewModeOverride = initialViewMode;          }          if (!params.has('search') && !params.has('q') && !params.has('query') && initialViewMode !== 'savings_squad') {             initialQuery = 'Gaming laptops';          }          const website = params.get('website') || 'tomsguide';          this.website = website;          if (website === 'techradar') {            const squadHeader = this.root.querySelector('.tg-df-savings-squad-header');            if (squadHeader) {               const pic = squadHeader.querySelector('picture');               if (pic) pic.style.display = 'none';            }            const style = document.createElement('style');            style.innerHTML = `              .tg-df-container .hawk-affiliate-link-deal-button, .tg-df-container .tg-df-card-cta { background-color: #5DAF08 !important; }              .tg-df-container .hawk-affiliate-link-deal-button:hover, .tg-df-container .tg-df-card-cta:hover { background-color: #4a8c06 !important; }            `;            this.root.appendChild(style);          }                    if (this.regionSelect) {            this.regionSelect.value = params.get('region') || 'auto';            this.updatePriceDropdownCurrency();          }                    if (this.retailerSelect && params.has('retailer')) {            this.retailerSelect.value = params.get('retailer');          }                    if (params.has('brands')) {            const b = params.get('brands');            if (b) {              this.selectedBrands = b.split(',');            }          }                    if (this.offerTypeSelect && params.has('offer_type')) {            this.offerTypeSelect.value = params.get('offer_type');          }          if (this.viewModeSelect && params.has('view_mode')) {            this.viewModeSelect.value = params.get('view_mode');          }          if (this.rowsSelect && params.has('rows')) {            this.rowsSelect.value = params.get('rows');          }          if (params.has('price')) {            const priceVal = params.get('price');            if (this.priceFilter) {               // Try assigning it directly to select. If it's not present implicitly ignores               this.priceFilter.value = priceVal;            }            if (priceVal.includes('_')) {               const parts = priceVal.split('_');               if (this.customPriceMin && parts[0]) this.customPriceMin.value = parts[0];               if (this.customPriceMax && parts[1]) this.customPriceMax.value = parts[1];            }          }          if (this.discountFilter && params.has('min_discount_ratio')) {            // Need to convert back from ratio (e.g. 0.8) to select value (e.g. "20")            const ratioStr = params.get('min_discount_ratio');            const ratioFloat = parseFloat(ratioStr);            if (!isNaN(ratioFloat)) {               const percentage = Math.round((1 - ratioFloat) * 100);               this.discountFilter.value = percentage.toString();            }          }          if (this.sortSelect) {            this.sortSelect.value = params.get('sort') || 'date_desc';          }          if (this.dealModeToggle && params.has('deal_mode')) {            this.dealModeToggle.checked = params.get('deal_mode') === 'true' || params.get('deal_mode') === '1';          }          const headerTitleEl = this.root.querySelector('#tg-df-header-title');          const headerSubtitleEl = this.root.querySelector('#tg-df-header-subtitle');          if (params.has('widget_title') && headerTitleEl) {             headerTitleEl.textContent = params.get('widget_title');          }          if (params.has('widget_subtitle') && headerSubtitleEl) {             headerSubtitleEl.textContent = params.get('widget_subtitle');          }                    // Re-apply layout after params have updated control values          this.applyLayoutMode();                    if (params.get('search')) {            initialQuery = params.get('search');          } else if (params.get('q')) {            initialQuery = params.get('q');          } else if (params.get('query')) {            initialQuery = params.get('query');          }                    this.currentQuery = initialQuery;          if (this.searchInput) {            if (this.getViewMode() === 'savings_squad') {              this.searchInput.value = '';            } else {              this.searchInput.value = this.currentQuery;            }          }                    if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {            this.fetchDeals(this.currentQuery);          } else {            this.render();          }        }        updatePriceDropdownCurrency() {          if (!this.priceFilter || !this.regionSelect) return;          const currencySymbols = {            'US': '$',            'GB': '£',            'CA': '$CA',            'AU': '$AU',            'DE': '€',            'FR': '€',            'IT': '€',          };          const area = this.getAreaCode();          const cur = currencySymbols[area || 'US'] || '$';                    const options = this.priceFilter.options;          for (let i = 0; i < options.length; i++) {            const opt = options[i];            if (opt.value === 'all') {              opt.innerText = 'All Prices';            } else if (opt.value === 'under50') {              opt.innerText = `Under ${cur}50`;            } else if (opt.value === '50_100') {              opt.innerText = `${cur}50 - ${cur}100`;            } else if (opt.value === '100_200') {              opt.innerText = `${cur}100 - ${cur}200`;            } else if (opt.value === '200_500') {              opt.innerText = `${cur}200 - ${cur}500`;            } else if (opt.value === 'over500') {              opt.innerText = `Over ${cur}500`;            }          }        }        populateBrandDropdown(values) {          if (!this.brandDropdown || !this.brandFilterWrapper) return;          this.brandFilterWrapper.style.display = 'flex'; // show the wrapper                    let html = '';          const allChecked = this.selectedBrands.length === 0 ? 'checked' : '';          const _div = '<' + '/div>';          const _span = '<' + '/span>';          html += `\x3Cdiv class="tg-df-ms-option">\x3Cinput type="checkbox" value="" ${allChecked} class="tg-df-brand-chk"> Any Brand${_div}`;                    values.forEach(v => {             if (!v.formatted_value || v.formatted_value === 'Any Brand') return;             const isChecked = this.selectedBrands.includes(v.formatted_value) ? 'checked' : '';             html += `\x3Cdiv class="tg-df-ms-option">\x3Cinput type="checkbox" value="${this.escapeHTML(v.formatted_value)}" ${isChecked} class="tg-df-brand-chk"> ${this.escapeHTML(v.formatted_value)} \x3Cspan style="color:var(--tg-df-text-muted);font-size:12px">(${v.count || 0})${_span}${_div}`;          });                    this.brandDropdown.innerHTML = html;                    // Re-bind listeners          const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');          chks.forEach(chk => {            chk.addEventListener('change', (e) => {              const val = e.target.value;              if (val === '') {                this.selectedBrands = [];              } else {                if (e.target.checked) {                   if (!this.selectedBrands.includes(val)) this.selectedBrands.push(val);                } else {                   this.selectedBrands = this.selectedBrands.filter(b => b !== val);                }              }                            if (this.selectedBrands.length === 0) {                 this.brandTrigger.innerText = 'Any Brand';              } else if (this.selectedBrands.length === 1) {                 this.brandTrigger.innerText = this.selectedBrands[0];              } else {                 this.brandTrigger.innerText = `${this.selectedBrands.length} Brands selected`;              }                            // Only call API if changed from UI interactions              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                 this.updateURLParams();                 this.fetchDeals(this.currentQuery);              }            });          });                    // Update button text on load          if (this.selectedBrands.length === 0) {             this.brandTrigger.innerText = 'Any Brand';          } else if (this.selectedBrands.length === 1) {             this.brandTrigger.innerText = this.selectedBrands[0];          } else {             this.brandTrigger.innerText = `${this.selectedBrands.length} Brands selected`;          }        }        updateURLParams() {          const url = new URL(window.location);          if (this.currentQuery && this.currentQuery !== 'Gaming laptops') {            url.searchParams.set('q', this.currentQuery);          } else {            url.searchParams.delete('q');            url.searchParams.delete('search');            url.searchParams.delete('query');          }                    if (this.regionSelect && this.regionSelect.value !== 'auto') {            url.searchParams.set('region', this.regionSelect.value);          } else {            url.searchParams.delete('region');          }                    if (this.retailerSelect && this.retailerSelect.value) {            url.searchParams.set('retailer', this.retailerSelect.value);          } else {            url.searchParams.delete('retailer');          }                    if (this.selectedBrands && this.selectedBrands.length > 0) {            url.searchParams.set('brands', this.selectedBrands.join(','));          } else {            url.searchParams.delete('brands');          }                    if (this.offerTypeSelect && this.offerTypeSelect.value) {            url.searchParams.set('offer_type', this.offerTypeSelect.value);          } else {            url.searchParams.delete('offer_type');          }                    if (this.viewModeSelect && this.viewModeSelect.value !== 'auto') {            url.searchParams.set('view_mode', this.viewModeSelect.value);          } else {            url.searchParams.delete('view_mode');          }                    if (this.rowsSelect && this.rowsSelect.value !== '12') {            url.searchParams.set('rows', this.rowsSelect.value);          } else {            url.searchParams.delete('rows');          }                    const min = this.customPriceMin ? this.customPriceMin.value : '';          const max = this.customPriceMax ? this.customPriceMax.value : '';          if (min || max) {             url.searchParams.set('price', `${min}_${max}`);          } else if (this.priceFilter && this.priceFilter.value !== 'all') {            url.searchParams.set('price', this.priceFilter.value);          } else {            url.searchParams.delete('price');          }                    if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {            const v = parseInt(this.discountFilter.value);            if (!isNaN(v) && v > 0) {               const ratio = (100 - v) / 100;               url.searchParams.set('min_discount_ratio', ratio.toString());            }          } else {            url.searchParams.delete('min_discount_ratio');          }                    if (this.sortSelect && this.sortSelect.value !== 'date_desc') {            url.searchParams.set('sort', this.sortSelect.value);          } else {            url.searchParams.delete('sort');          }                    if (this.dealModeToggle && this.dealModeToggle.checked) {            url.searchParams.set('deal_mode', 'true');          } else {            url.searchParams.delete('deal_mode');          }                    window.history.replaceState({}, '', url);        }        bindEvents() {          const handleFiltersScroll = () => {            const filters = this.root.querySelector('.tg-df-filters');            const leftBtn = this.root.querySelector('.tg-df-scroll-btn.left');            const rightBtn = this.root.querySelector('.tg-df-scroll-btn.right');            if (filters && leftBtn && rightBtn) {              const { scrollLeft, scrollWidth, clientWidth } = filters;              leftBtn.style.display = scrollLeft > 0 ? 'flex' : 'none';              rightBtn.style.display = Math.ceil(scrollLeft + clientWidth) < scrollWidth - 5 ? 'flex' : 'none';            }          };          const filters = this.root.querySelector('.tg-df-filters');          if (filters) {            filters.addEventListener('scroll', handleFiltersScroll);            window.addEventListener('resize', handleFiltersScroll);            setTimeout(handleFiltersScroll, 100);                        // Also call after rendering dropdowns            const origRenderCategories = this.renderCategories;            if (origRenderCategories) {               this.renderCategories = (...args) => {                 origRenderCategories.apply(this, args);                 setTimeout(handleFiltersScroll, 50);               };            }          }                const roundels = this.root.querySelectorAll('.tg-df-carousel-cat');          roundels.forEach(r => {             r.addEventListener('click', () => {                const q = r.getAttribute('data-query');                const pr = r.getAttribute('data-pr');                if (typeof trackHawkEvent !== 'undefined') {                     trackHawkEvent({                         clickType: "CC",                         widgetId: this.widgetId,                         productCategoryName: "deals",                         zeroBasedProductIndexOrNull: null,                         totalDealsOrProducts: null,                         areaClicked: "Category Roundel",                         revenueId: this.revenueId,                         isoCurrencyCode: typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD',                         queryName: q,                         widgetTypeName: this.widgetTypeName                     });                 }                this.currentQuery = q;                const label = this.root.querySelector('#tg-df-carousel-title-label');                if (label) label.textContent = 'Best ' + q;                if (this.priceFilter) this.priceFilter.value = pr || 'all';                if (this.discountFilter) this.discountFilter.value = '5';                if (this.searchInput) this.searchInput.value = q;                                roundels.forEach(ro => ro.classList.remove('active'));                r.classList.add('active');                this.fetchDeals(this.currentQuery);             });          });          const discBtns = this.root.querySelectorAll('.tg-df-carousel-filter-btn');          discBtns.forEach(b => {             b.addEventListener('click', () => {                const d = b.getAttribute('data-d');                const pr = b.getAttribute('data-pr');                const ot = b.getAttribute('data-ot');                let label = b.innerText ? b.innerText.trim() : '';                let filterType = 'unknown';                let filterVal = 'unknown';                if (d !== null) { filterType = 'discount'; filterVal = d; }                else if (pr !== null) { filterType = 'price'; filterVal = pr; }                else if (ot !== null) { filterType = 'offertype'; filterVal = ot; }                if (typeof trackElementInteraction === 'function') trackElementInteraction({ id: `filter-${filterType}-${filterVal}`, name: 'Filter Button', label: label });                                if (d !== null) {                   if (this.discountFilter) this.discountFilter.value = this.discountFilter.value === d ? '0' : d;                } else if (pr !== null) {                   if (this.priceFilter) this.priceFilter.value = this.priceFilter.value === pr ? 'all' : pr;                } else if (ot !== null) {                   if (this.offerTypeSelect) this.offerTypeSelect.value = this.offerTypeSelect.value === ot ? 'all' : ot;                } else {                   if (this.discountFilter) this.discountFilter.value = '0';                   if (this.priceFilter) this.priceFilter.value = 'all';                   if (this.offerTypeSelect) this.offerTypeSelect.value = 'all';                }                if (d === null && pr === null && ot === null && b.getAttribute("data-type") !== "custom") {                   discBtns.forEach(ro => ro.classList.remove('active'));                   b.classList.add('active');                } else if (b.getAttribute("data-type") !== "custom") {                   // Only operate on hardcoded buttons (those without data-type)                   discBtns.forEach(ro => {                      if (!ro.getAttribute('data-d') && !ro.getAttribute('data-pr') && !ro.getAttribute('data-ot') && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active');                   });                                      let makeActive = true;                   if (d !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-d') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   } else if (pr !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-pr') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   } else if (ot !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-ot') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   }                                      if (makeActive) b.classList.add('active');                                      // Check if anything is active, if not activate "All"                   let anyActive = false;                   discBtns.forEach(ro => { if (ro.classList.contains('active') && ro.getAttribute('data-type') !== 'custom') anyActive = true; });                   if (!anyActive) {                       discBtns.forEach(ro => { if (!ro.getAttribute('data-d') && !ro.getAttribute('data-pr') && !ro.getAttribute('data-ot') && ro.getAttribute('data-type') !== 'custom') ro.classList.add('active'); });                   }                }                                this.fetchDeals(this.currentQuery);             });          });          if (this.brandTrigger && this.brandDropdown) {            this.brandTrigger.addEventListener('click', () => {              this.brandDropdown.classList.toggle('active');            });            document.addEventListener('click', (e) => {              if (this.brandFilterWrapper && !e.composedPath().includes(this.brandFilterWrapper)) {                this.brandDropdown.classList.remove('active');              }            });          }          const showAutocomplete = () => {             if (this.getViewMode() !== 'savings_squad' || !this.autocompleteDropdown || !this.airedaleTags) return;                          let terms = this.airedaleTags;             if (this.airedaleBrands) {                terms = terms.concat(this.airedaleBrands.map(b => b.formatted_value));             }             terms = [...new Set(terms)];                          const query = this.searchInput.value.trim();             let matches = [];             if (query.length > 0) {                 matches = terms.filter(t => t.toLowerCase().includes(query.toLowerCase()) && t.toLowerCase() !== query.toLowerCase());             } else {                 matches = terms;             }                          if (matches.length > 0) {                 this.autocompleteDropdown.innerHTML = matches.map(m => `\x3Cdiv class="tg-df-autocomplete-item" data-tag="${this.escapeHTML(m)}">${this.escapeHTML(m)}<` + `/div>`).join('');                 this.autocompleteDropdown.classList.add('active');             } else {                 this.autocompleteDropdown.classList.remove('active');             }          };          let debounceTimer;          if(this.searchInput) {            this.searchInput.addEventListener('focus', showAutocomplete);            this.searchInput.addEventListener('input', (e) => {              clearTimeout(debounceTimer);              const query = e.target.value.trim();              this.currentQuery = query;              showAutocomplete();              debounceTimer = setTimeout(() => {                this.updateURLParams();                if (query.length > 2) {                  this.fetchDeals(query);                } else if (query.length === 0) {                  if (this.getViewMode() === 'savings_squad') {                    this.activeDealTag = null;                    this.currentQuery = '';                    if (this.categoryFilter) this.categoryFilter.value = 'all';                    this.fetchDeals('');                  } else {                    this.deals = [];                    this.render();                  }                }              }, 400);            });            this.searchInput.addEventListener('keypress', (e) => {              if (e.key === 'Enter') {                if (this.autocompleteDropdown) this.autocompleteDropdown.classList.remove('active');                clearTimeout(debounceTimer);                const query = e.target.value.trim();                this.currentQuery = query;                                let isTag = false;                if (this.airedaleTags && this.airedaleTags.includes(query)) isTag = true;                if (this.airedaleBrands && this.airedaleBrands.some(b => b.formatted_value === query)) isTag = true;                this.activeDealTag = isTag ? query : null;                                trackElementInteraction({ id: 'search-submit', name: 'Ask', label: 'Ask (main search)', text: query });                this.updateURLParams();                if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                   if (query.length === 0 && this.getViewMode() === 'savings_squad') {                       if (this.categoryFilter) this.categoryFilter.value = 'all';                   }                   this.fetchDeals(query);                }              }            });          }          if (this.autocompleteDropdown) {             this.autocompleteDropdown.addEventListener('click', (e) => {                const item = e.target.closest('.tg-df-autocomplete-item');                if (item) {                   const tag = item.getAttribute('data-tag');                   this.currentQuery = tag;                   if (this.searchInput) this.searchInput.value = tag;                   this.activeDealTag = tag;                   if (this.categoryFilter && this.airedaleTags.includes(tag)) {                       this.categoryFilter.value = tag;                   }                   this.autocompleteDropdown.classList.remove('active');                   this.updateURLParams();                   this.fetchDeals(tag);                }             });             document.addEventListener('click', (e) => {               if (this.autocompleteDropdown && this.searchInput && !e.composedPath().includes(this.searchInput) && !e.composedPath().includes(this.autocompleteDropdown)) {                 this.autocompleteDropdown.classList.remove('active');               }             });          }          if (this.searchBtn) {            this.searchBtn.addEventListener('click', () => {              if (this.autocompleteDropdown) this.autocompleteDropdown.classList.remove('active');              clearTimeout(debounceTimer);              const query = this.searchInput.value.trim();              trackElementInteraction({ id: 'search-submit', name: 'Ask', label: 'Ask (main search)', text: query });                            let isTag = false;              if (this.airedaleTags && this.airedaleTags.includes(query)) isTag = true;              if (this.airedaleBrands && this.airedaleBrands.some(b => b.formatted_value === query)) isTag = true;              this.activeDealTag = isTag ? query : null;                            this.currentQuery = query;              this.updateURLParams();              if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                 if (query.length === 0 && this.getViewMode() === 'savings_squad') {                     if (this.categoryFilter) this.categoryFilter.value = 'all';                 }                 this.fetchDeals(query);              }            });          }          if(this.sortSelect && this.sortSelect.querySelector('option[value="date_desc"]') === null) {              const option = document.createElement('option');              option.value = "date_desc";              option.text = "Newest First";              this.sortSelect.insertBefore(option, this.sortSelect.firstChild);          }          if(this.sortSelect) this.sortSelect.addEventListener('change', () => {            trackElementInteraction({ id: `sort-option-${this.sortSelect.value}`, name: 'Sort', label: `Sort: ${this.sortSelect.options[this.sortSelect.selectedIndex].text}` });            this.updateURLParams();            if (this.deals.length > 0) {              this.sortData();              this.render();            }          });                    const priceFilter = this.root.querySelector('#tg-df-price-filter');          if (priceFilter) {            this.priceFilter = priceFilter;            this.priceFilter.addEventListener('change', () => {              trackElementInteraction({ id: `filter-price-${this.priceFilter.value}`, name: 'Price', label: this.priceFilter.options[this.priceFilter.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }            });          }          const updateCustomPrice = () => {             this.updateURLParams();             if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);             } else {                this.render();             }          };          if (this.customPriceMin) {             this.customPriceMin.addEventListener('change', updateCustomPrice);             this.customPriceMin.addEventListener('keypress', (e) => {                if (e.key === 'Enter') updateCustomPrice();             });          }          if (this.customPriceMax) {             this.customPriceMax.addEventListener('change', updateCustomPrice);             this.customPriceMax.addEventListener('keypress', (e) => {                if (e.key === 'Enter') updateCustomPrice();             });          }          const discountFilter = this.root.querySelector('#tg-df-discount-filter');          if (discountFilter) {            this.discountFilter = discountFilter;            this.discountFilter.addEventListener('change', () => {              trackElementInteraction({ id: `filter-discount-${this.discountFilter.value}`, name: 'Discount', label: this.discountFilter.options[this.discountFilter.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }            });          }          if (this.categoryFilter) {            this.categoryFilter.addEventListener('change', (e) => {               const val = e.target.value === 'all' ? null : e.target.value;               this.activeDealTag = val;               if (val) {                 this.currentQuery = val;               } else {                 if (this.searchInput && this.currentQuery === document.querySelector('#tg-df-brand-trigger')?.getAttribute('data-active-brand')) {                     // don't clear current query if a brand is selected                 } else if (this.searchInput) {                     this.currentQuery = '';                     this.searchInput.value = '';                 }               }               this.fetchSavingsSquad();            });          }                    if (this.settingsToggle) {            this.settingsToggle.addEventListener('click', () => {              const o = this.settingsPanel.classList.toggle('active');              this.settingsBackdrop.classList.toggle('active');              if (o) trackElementInteraction({ id: 'filter-open', name: 'Filters', label: 'Open filters' });            });          }                    if (this.settingsBackdrop) {            this.settingsBackdrop.addEventListener('click', () => {              this.settingsPanel.classList.remove('active');              this.settingsBackdrop.classList.remove('active');            });          }                    if (this.regionSelect) {            this.regionSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-region-${this.regionSelect.value}`, name: 'Region', label: this.regionSelect.options[this.regionSelect.selectedIndex].text });              this.updateURLParams();              this.updatePriceDropdownCurrency();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.retailerSelect) {            this.retailerSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-merchant-${this.retailerSelect.value}`, name: 'Retailer', label: this.retailerSelect.options[this.retailerSelect.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.offerTypeSelect) {            this.offerTypeSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-offertype-${this.offerTypeSelect.value}`, name: 'Offer Type', label: this.offerTypeSelect.options[this.offerTypeSelect.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.viewModeSelect) {            this._prevViewMode = this.viewModeSelect.value;            this.viewModeSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-viewmode-${this.viewModeSelect.value}`, name: 'View Mode', label: this.viewModeSelect.options[this.viewModeSelect.selectedIndex].text });                            // Reset all active toggles and filters to prevent config carry-over              this.selectedBrands = [];              if (this.brandTrigger) this.brandTrigger.innerText = 'Select Brands';              if (this.brandDropdown) {                const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                chks.forEach(chk => { chk.checked = false; });              }              if (this.priceFilter) this.priceFilter.value = 'all';              if (this.customPriceMin) this.customPriceMin.value = '';              if (this.customPriceMax) this.customPriceMax.value = '';              if (this.sortSelect) this.sortSelect.value = 'date_desc';              if (this.discountFilter) this.discountFilter.value = '0';              if (this.retailerSelect) this.retailerSelect.value = '';              if (this.offerTypeSelect) this.offerTypeSelect.value = '';              if (this.rowsSelect) this.rowsSelect.value = '12';              if (this.categoryFilter) this.categoryFilter.value = 'all';              this.activeDealTag = null;              this.updateURLParams();              this.applyLayoutMode();                            if (this.getViewMode() === 'savings_squad' || this._prevViewMode === 'savings_squad') {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }              this._prevViewMode = this.viewModeSelect.value;            });          }                    if (this.rowsSelect) {            this.rowsSelect.addEventListener('change', () => {              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.dealModeToggle) {            this.dealModeToggle.addEventListener('change', () => {              this.updateURLParams();              this.render();            });          }          if (this.editorModeToggle) {             this.editorModeToggle.addEventListener('change', (e) => {                this.editorMode = e.target.checked;                this.render();                this.updateFloatingCopyBar();             });          }          if (this.editorCopyBtn) {             this.editorCopyBtn.addEventListener('click', () => {                this.copySelectedDealsToCMS();             });          }          if (this.editorClearBtn) {             this.editorClearBtn.addEventListener('click', () => {                this.selectedDeals.clear();                this.render();                this.updateFloatingCopyBar();             });          }          if (this.grid) {            this.grid.addEventListener('change', (e) => {               if (e.target.classList.contains('tg-df-deal-checkbox')) {                  const dealId = e.target.getAttribute('data-id');                  if (e.target.checked) {                     const dealObj = this.deals.find(d => d.id === dealId);                     if (dealObj) this.selectedDeals.set(dealId, dealObj);                  } else {                     this.selectedDeals.delete(dealId);                  }                  this.updateFloatingCopyBar();               }            });            this.grid.addEventListener('click', (e) => {              const dealCard = e.target.closest('[data-action="deal-click"]');              const similarCard = e.target.closest('[data-action="view-similar-click"]');              const cardLink = dealCard || similarCard;              if (cardLink) {                const productName = cardLink.getAttribute('data-product-name');                const merchantName = cardLink.getAttribute('data-merchant-name');                const productId = cardLink.getAttribute('data-analytics-id');                const price = parseFloat(cardLink.getAttribute('data-price')) || null;                const prevPriceStr = cardLink.getAttribute('data-previous-price');                const previousPrice = prevPriceStr ? parseFloat(prevPriceStr) : null;                const originalLink = cardLink.getAttribute('data-original-link');                const rewrittenLink = cardLink.getAttribute('href');                const revenueId = cardLink.getAttribute('data-revenue-id');                const index = parseInt(cardLink.getAttribute('data-index'), 10) || 0;                const inStock = cardLink.getAttribute('data-in-stock') === 'true';                const totalText = cardLink.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: cardLink.getAttribute('data-model-id') || null,                    matchId: cardLink.getAttribute('data-match-id') || null,                    brand: cardLink.getAttribute('data-model-brand') || null,                    parent: cardLink.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: cardLink.getAttribute('data-merchant-id') || null,                    network: cardLink.getAttribute('data-merchant-network') || null,                    url: cardLink.getAttribute('data-merchant-url') || null,                    name: merchantName                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: normalizeCurrency(this.escapeHTML(cardLink.getAttribute('data-currency') || '$'))                };                if (dealCard) {                  trackDealClick(trackingParams);                } else {                  trackViewSimilarClick(trackingParams);                }              }              const couponsBtn = e.target.closest('[data-action="coupons-click"]');              if (couponsBtn) {                trackElementInteraction({                  id: 'product-card-show-coupons',                  name: 'Coupons',                  label: `Product card coupons: ${couponsBtn.getAttribute('data-merchant')}`                });              }            });          }          this.setupScrollListeners();        }        setupScrollListeners() {          const containers = [             this.root.querySelector('.tg-df-carousel-roundels'),             this.root.querySelector('.tg-df-carousel-filters-wrap'),             this.root.querySelector('#tg-df-grid')          ];                    containers.forEach(container => {             if (!container) return;                          const checkScroll = () => {                if (!container.parentElement) return;                const leftBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-left');                const rightBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-right');                                if (leftBtn) {                   if (container.scrollLeft <= 5) leftBtn.style.display = 'none';                   else leftBtn.style.display = 'flex';                }                                if (rightBtn) {                   if (container.scrollWidth <= container.clientWidth) {                       rightBtn.style.display = 'none';                   } else if (container.scrollLeft >= container.scrollWidth - container.clientWidth - 5) {                       rightBtn.style.display = 'none';                   } else {                       rightBtn.style.display = 'flex';                   }                }             };                          container.addEventListener('scroll', checkScroll);             checkScroll();                          window.addEventListener('resize', checkScroll);                          const observer = new MutationObserver(checkScroll);             observer.observe(container, { childList: true, subtree: true, characterData: false });          });        }        get widgetTypeName() {          const mode = this.viewModeSelect ? this.viewModeSelect.value : (this.viewModeOverride || 'auto');          switch(mode) {              case 'carousel': return 'Carousel';              case 'savings_squad': return 'Savings Squad';              case 'grid': return 'Grid';              case 'row': return 'Row';              default: return 'Auto Collection';          }        }        getRowsLimit() {          if (this.rowsSelect && this.rowsSelect.value) return parseInt(this.rowsSelect.value, 10);          let configSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {             configSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {             configSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(configSource);          if (params.has('rows')) return parseInt(params.get('rows'), 10) || 12;          return 12;        }        getAreaCode() {          if (this.regionSelect && this.regionSelect.value) {            if (this.regionSelect.value === 'auto') return null;            return this.regionSelect.value;          }          let area = null;          try {            const locale = window.navigator.language || window.navigator.userLanguage;            if (locale && locale.includes('-')) {              area = locale.split('-')[1].toUpperCase();            } else if (locale && locale.length === 2) {              if (locale.toUpperCase() === 'EN') { area = 'US'; }              else { area = locale.toUpperCase(); }            }          } catch (e) { /* Ignore */ }                    // Map to known valid options or fallback to US          const valid = ['US', 'GB', 'CA', 'AU', 'DE', 'FR', 'IT'];          if (area === 'UK') area = 'GB';          if (valid.includes(area)) {             return area;          }          return 'US';        }        async fetchDeals(query) {          this.showLoading();          this.deals = [];          this.displayLimit = this.getRowsLimit();                    try {            console.log("getViewMode returns:", this.getViewMode());            if (this.getViewMode() === 'savings_squad') {               await this.fetchSavingsSquad();            } else {               if (this.isBroadQuery(query)) {                 await this.fetchAdviserDeals(query);               } else {                 await this.fetchHawkDeals(query);                 if (this.deals.length === 0) {                   await this.fetchAdviserDeals(query);                 }               }            }          } catch (error) {            console.warn("[Tom's Guide Widget] Fetch error:", error);            this.showError();          }        }        async fetchSavingsSquad() {          let topArticles = this.airedaleArticles;          if (!topArticles) {            const siteParam = this.website || 'tomsguide';            const airedaleUrl = `https://airedale.futurecdn.net/feeds/feed_1781000519267.json?site=${siteParam}&articleType=deals&limit=50`;            let res;            try {               res = await fetch(airedaleUrl);            } catch(e) {               try { res = await fetch(`https://airedale.futurecdn.net/feeds/feed_1776420579726.json?site=${siteParam}&articleType=deals&limit=50`); } catch (err) { console.warn("Fallback fetch failed", err); return; }            }            if (!res.ok) throw new Error('Airedale API Error');            const articles = await res.json();            topArticles = Array.isArray(articles) ? articles.slice(0, 50) : ((articles.data && Array.isArray(articles.data)) ? articles.data.slice(0, 50) : []);            this.airedaleArticles = topArticles;                        let tagCounts = {};            topArticles.forEach((a) => {              let articleTags = new Set();              if (a.articlecategory && Array.isArray(a.articlecategory)) {                 a.articlecategory.forEach((t) => articleTags.add(t));              }              articleTags.forEach(t => {                 tagCounts[t] = (tagCounts[t] || 0) + 1;              });            });                        this.airedaleTags = Object.keys(tagCounts).sort((a, b) => tagCounts[b] - tagCounts[a]);            this.airedaleTagCounts = tagCounts;          }                    let targetArticles = topArticles;          if (!this.activeDealTag && this.currentQuery) {             const tagMatch = this.airedaleTags.find(t => t.toLowerCase() === this.currentQuery.toLowerCase());             if (tagMatch) {                this.activeDealTag = tagMatch;             }          }          if (this.activeDealTag) {             const cleanTag = this.activeDealTag.toLowerCase().replace(/&/g, '').replace(/[^a-z0-9]+/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');             const encodedTag = encodeURIComponent(cleanTag);             const siteParam = this.website || 'tomsguide';             const url = `https://airedale.futurecdn.net/feeds/feed_1781000519267.json?site=${siteParam}&articleType=deals&limit=50&articleCategoryHandle=${encodedTag}`;             try {                const res = await fetch(url);                if (res.ok) {                   const articles = await res.json();                   targetArticles = Array.isArray(articles) ? articles.slice(0, 50) : ((articles.data && Array.isArray(articles.data)) ? articles.data.slice(0, 50) : []);                }             } catch(e) {                console.warn("Failed to fetch by activeDealTag", e);             }          }          let extractedDeals = [];          let seenUrls = new Set();                    let overallBrandsCounts = {};                    // First pass: extract ALL brands from topArticles so the dropdown has all options          topArticles.forEach((article) => {             if (!article.articlepage) return;             let pageData = [];             try { pageData = JSON.parse(article.articlepage[0]); } catch(e){ console.warn(e); }             const savingsSquad = pageData.filter((p) => p.type === 'deal' || p.type === 'featured-product');             savingsSquad.forEach((block) => {                const data = block.data || {};                if (data.brand) {                   const cleanBrand = data.brand.replace(/^\d+\.\s*/, '').trim();                   overallBrandsCounts[cleanBrand] = (overallBrandsCounts[cleanBrand] || 0) + 1;                }             });          });          targetArticles.forEach((article) => {             if (!article.articlepage) return;                          let pageData = [];             try {                pageData = JSON.parse(article.articlepage[0]);             } catch(e){ console.warn(e); }                          const savingsSquad = pageData.filter((p) => p.type === 'deal' || p.type === 'featured-product');                          savingsSquad.forEach((block, idx) => {                const data = block.data || {};                const isFeatured = block.type === 'featured-product';                                const link = data.link || {};                const priceObj = data.price || {};                const image = data.image || {};                                if (data.brand) {                   data.brand = data.brand.replace(/^\d+\.\s*/, '').trim();                }                const externalUrl = isFeatured ? data.url : (link.href || null);                let summaryTitle = isFeatured ? (data.name || data.brand) : (data.productName || link.label || article.articlename);                let description = isFeatured ? (data.strapline || '') : (data.text || '');                                if (!isFeatured && !data.productName && data.text) {                   const brSplit = data.text.split(new RegExp('\x3Cbr\\s*\\/?\\x3E', 'i'));                   if (brSplit.length > 1) {                     summaryTitle = brSplit[0].replace(/<[^>]+>/g, '').trim();                     description = brSplit.slice(1).join(' ').replace(/<br\s*\/?>/gi, ' ').replace(/<\/?(p|div)[^>]*>/gi, ' ').replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').trim();                   } else {                     const match = data.text.match(/\x3Cstrong>(.*?)<\/strong>/);                     if (match) {                       summaryTitle = match[1].replace(/<[^>]+>/g, '').trim();                       if (summaryTitle.endsWith(':')) summaryTitle = summaryTitle.slice(0, -1);                     }                   }                }                                let imageUrl = isFeatured ? image.mos : (image.src || null);                if (imageUrl && imageUrl.startsWith('//')) imageUrl = 'https:' + imageUrl;                                description = description.replace(/<br\s*\/?>/gi, ' ').replace(/<\/?(p|div)[^>]*>/gi, ' ').replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').replace(/View Deal$/i, '').trim();                                let merchantName = data.retailer || '';                if (!merchantName && externalUrl) {                   try {                     merchantName = new URL(externalUrl).hostname.replace('www.', '').split('.')[0];                     merchantName = merchantName.charAt(0).toUpperCase() + merchantName.slice(1);                   }catch(e){ console.warn(e); }                }                if (!merchantName) merchantName = 'Retailer';                const q = (this.currentQuery || '').toLowerCase();                const activeTagLogic = (this.activeDealTag || '').toLowerCase();                if (q.length > 2 && q !== activeTagLogic) {                   const searchTarget = `${summaryTitle || ''} ${description || ''}`.toLowerCase();                   if (!searchTarget.includes(q)) return;                }                let rawPrice = 0;                let rawMsrp = 0;                let currencyStr = '$';                if (isFeatured) {                   rawPrice = typeof data.salePrice === 'number' && data.salePrice > 0 ? data.salePrice : (typeof data.price === 'number' ? data.price : 0);                   rawMsrp = typeof data.salePrice === 'number' && typeof data.price === 'number' && data.price > data.salePrice ? data.price : 0;                   currencyStr = data.currency === 'GBP' ? '£' : '$';                } else {                   rawPrice = priceObj.amount ? parseFloat(priceObj.amount) : 0;                   rawMsrp = priceObj.amountWas ? parseFloat(priceObj.amountWas) : 0;                   currencyStr = priceObj.currency === 'GBP' ? '£' : '$';                }                                let savingAmt = 0;                let savingLabel = '';                if (rawPrice > 0 && rawMsrp > rawPrice) {                   savingAmt = parseFloat((rawMsrp - rawPrice).toFixed(2));                   savingLabel = `Save ${currencyStr}${savingAmt}`;                }                                // Apply Brand filter                if (this.selectedBrands && this.selectedBrands.length > 0) {                   const itemBrand = (data.brand || '').toLowerCase();                   const hasMatch = this.selectedBrands.some(sb => sb.toLowerCase() === itemBrand);                   if (!hasMatch) return;                }                // Apply Price filter                let priceFilterVal = null;                const min = this.customPriceMin ? this.customPriceMin.value : '';                const max = this.customPriceMax ? this.customPriceMax.value : '';                if (min || max) {                   priceFilterVal = `${min}_${max}`;                } else if (this.priceFilter && this.priceFilter.value !== 'all') {                   priceFilterVal = this.priceFilter.value;                }                if (priceFilterVal && rawPrice > 0) {                   if (priceFilterVal === 'under50' && rawPrice >= 50) return;                   if (priceFilterVal === 'over50' && rawPrice <= 50) return;                   if (priceFilterVal === 'over30' && rawPrice <= 30) return;                   if (priceFilterVal === 'over500' && rawPrice <= 500) return;                   if (priceFilterVal.includes('_')) {                      const parts = priceFilterVal.split('_');                      const min = parseFloat(parts[0]);                      const max = parseFloat(parts[1]);                      if (!isNaN(min) && rawPrice < min) return;                      if (!isNaN(max) && rawPrice > max) return;                   }                }                // Apply Discount filter                if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {                   const requiredDiscount = parseInt(this.discountFilter.value);                   if (!isNaN(requiredDiscount) && requiredDiscount > 0) {                      if (!rawMsrp || rawMsrp <= rawPrice) return;                      const ratio = Math.round((1 - (rawPrice / rawMsrp)) * 100);                      if (ratio < requiredDiscount) return;                   }                }                                if (externalUrl) {                   if (seenUrls.has(externalUrl)) return;                  seenUrls.add(externalUrl);                }                                extractedDeals.push({                   id: `airedale-${article.id || Math.random()}-${idx}`,                   url: externalUrl,                   image: imageUrl,                   fallbackImage: imageUrl,                   title: summaryTitle,                   brand: data.brand || '',                   productName: data.productName || '',                   merchant: merchantName,                   rawPrice: rawPrice,                   rawMsrp: rawMsrp,                   price: rawPrice > 0 ? rawPrice.toString() : '',                   msrp: rawMsrp > 0 ? rawMsrp.toString() : '',                   currency: currencyStr,                   isCheckPrice: !rawPrice,                   savingLabel: savingLabel,                   savingType: rawMsrp > rawPrice ? 'amount' : 'none',                   isPrime: false,                   starRating: null,                   description: description,                   text: data.text || '',                   authorName: article.articleauthortext ? article.articleauthortext[0] : (article.articleauthor ? article.articleauthor[0] : ''),                   authorRole: article.articleauthorrole ? article.articleauthorrole[0] : '',                   authorImage: article.articleauthormedia ? article.articleauthormedia[0] : '',                   documentUrl: article.documenturl ? article.documenturl[0] : '',                   modifiedDate: article.contentmodifieddate || article.modifieddate || ''                });             });          });                    const airedaleBrandsList = Object.keys(overallBrandsCounts).map(b => ({              formatted_value: b,              count: overallBrandsCounts[b]          })).sort((a,b) => b.count - a.count);                    if (this.getViewMode() === 'savings_squad') {             this.populateBrandDropdown(airedaleBrandsList.slice(0, 15));             if (this.brandFilterWrapper) {                if (airedaleBrandsList.length === 0) {                    this.brandFilterWrapper.style.display = 'none';                } else {                    this.brandFilterWrapper.style.display = 'flex';                }             }          }                    this.deals = extractedDeals;          this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        isBroadQuery(query) {          const q = query.toLowerCase();          const intentModifiers = ['deals', 'best', 'sale', 'under', 'cheap', 'offers', 'discount'];          return intentModifiers.some(term => q.includes(term));        }        async fetchHawkDeals(query) {          const url = new URL(this.apiUrl);          url.searchParams.append('model_name', query);          const areaCode = this.getAreaCode();          if (areaCode) {            url.searchParams.append('area', areaCode);          }                    if (this.retailerSelect && this.retailerSelect.value) {            url.searchParams.append('filter_merchant_name', this.retailerSelect.value);          }                    if (this.selectedBrands && this.selectedBrands.length > 0) {            url.searchParams.append('filter_label[text_brand]', this.selectedBrands.join(','));          }                    let priceVal = null;          const min = this.customPriceMin ? this.customPriceMin.value : '';          const max = this.customPriceMax ? this.customPriceMax.value : '';          if (min || max) {             priceVal = `${min}_${max}`;          } else if (this.priceFilter && this.priceFilter.value !== 'all') {             priceVal = this.priceFilter.value;          }          if (priceVal) {            if (priceVal === 'under50') {              url.searchParams.append('filter_max_price', '50');            } else if (priceVal === 'over50') {              url.searchParams.append('filter_min_price', '50');            } else if (priceVal === 'over30') {              url.searchParams.append('filter_min_price', '30');            } else if (priceVal === 'over500') {              url.searchParams.append('filter_min_price', '500');            } else if (priceVal.includes('_')) {              const parts = priceVal.split('_');              if (parts[0]) url.searchParams.append('filter_min_price', parts[0]);              if (parts[1]) url.searchParams.append('filter_max_price', parts[1]);            }          }                    if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {            const v = parseInt(this.discountFilter.value);            if (!isNaN(v) && v > 0) {              const ratio = (100 - v) / 100;              url.searchParams.append('min_discount_ratio', ratio.toString());            }          }                    if (this.offerTypeSelect && this.offerTypeSelect.value) {            url.searchParams.append('offer', this.offerTypeSelect.value);          }                    url.searchParams.append('filter_product_types', 'deals');                    url.searchParams.append('rows', this.getRowsLimit().toString());          let response;          try {             response = await fetch(url.toString());          } catch(e) {             if (window.location.protocol === 'file:') {                console.warn("[Tom's Guide Widget] fetch from file:// blocked by local CORS policy, falling back to Adviser mock.");                await this.fetchAdviserDeals(query);                return;             }             console.warn("Hawk fetch failed", e);             this.deals = [];             this.render();             return;          }          if (!response.ok) {            throw new Error('Hawk API Response Error');          }          const rawData = await response.json();          // Safely locate data array from potentially wrapped response          let offers = [];          let modelInfoArray = [];                    let brandFilterData = null;          if (rawData && rawData.widget && rawData.widget.data && Array.isArray(rawData.widget.data.filters)) {             brandFilterData = rawData.widget.data.filters.find(f => f.type === 'label_text_brand');          } else if (rawData && rawData.data && Array.isArray(rawData.data.filters)) {             brandFilterData = rawData.data.filters.find(f => f.type === 'label_text_brand');          }          if (brandFilterData && Array.isArray(brandFilterData.values) && brandFilterData.values.length > 0) {             this.populateBrandDropdown(brandFilterData.values);          } else {             if (this.brandFilterWrapper && this.selectedBrands.length === 0) {                this.brandFilterWrapper.style.display = 'none';             }          }                    if (rawData && rawData.widget && rawData.widget.data) {            if (Array.isArray(rawData.widget.data.offers)) offers = rawData.widget.data.offers;            if (rawData.widget.data.model_info && typeof rawData.widget.data.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.widget.data.model_info) ? rawData.widget.data.model_info : Object.values(rawData.widget.data.model_info);            }          } else if (rawData && rawData.data) {            if (Array.isArray(rawData.data.offers)) offers = rawData.data.offers;            if (rawData.data.model_info && typeof rawData.data.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.data.model_info) ? rawData.data.model_info : Object.values(rawData.data.model_info);            }          } else {            if (Array.isArray(rawData)) offers = rawData;            else if (rawData && Array.isArray(rawData.offers)) offers = rawData.offers;            else if (rawData && rawData.offers && Array.isArray(rawData.offers.offer)) offers = rawData.offers.offer;            else if (rawData && rawData.offers) offers = [].concat(rawData.offers);                        if (rawData && rawData.model_info && typeof rawData.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.model_info) ? rawData.model_info : Object.values(rawData.model_info);            }          }          let modelDetails = {};          modelInfoArray.forEach(m => {            const mId = m.model_id || m.id;            if (mId) {              modelDetails[mId] = {                score: m.score != null ? parseFloat(m.score) : null,                brand: m.brand || null,                parent: (m.parents && Array.isArray(m.parents) && m.parents.length > 0) ? m.parents[0].name : null              };            }          });          offers.forEach(item => {            let data = { ...item };            const mId = data.model_id;            if (mId && modelDetails[mId]) {              data.review_score = modelDetails[mId].score;              data.model_brand = modelDetails[mId].brand;              data.model_parent = modelDetails[mId].parent;            } else {              data.review_score = null;            }                        let itemOffers = [];            if (Array.isArray(item.offers)) itemOffers = item.offers;            else if (Array.isArray(item.offer)) itemOffers = item.offer;            else if (item.offers && typeof item.offers === 'object') itemOffers = [item.offers];            else if (item.offer && typeof item.offer === 'object') itemOffers = [item.offer];            if (itemOffers.length > 0) {              itemOffers.forEach(subItem => {                let subData = { ...item, ...subItem };                const subId = subData.model_id;                if (subId && modelDetails[subId]) {                  subData.review_score = modelDetails[subId].score;                  subData.model_brand = modelDetails[subId].brand;                  subData.model_parent = modelDetails[subId].parent;                } else if (data.review_score != null) {                  subData.review_score = data.review_score;                }                if (subData.merchant && typeof subData.merchant === 'object') {                  subData.merchant_name = subData.merchant.name;                }                this.deals.push(this.extractDealData(subData));              });              return;            }                        if (item.merchant && typeof item.merchant === 'object') {              data.merchant_name = item.merchant.name;            }                        this.deals.push(this.extractDealData(data));          });                    this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        async fetchAdviserDeals(query) {          // ======================================================================          // TODO: ADVISER API REPLACEMENT          // The code below simulates the Adviser API response using mock data.          // Once the real endpoint is ready, remove getAdviserMockData() and           // perform an actual fetch() request similar to fetchHawkDeals().          // Example:          // const area = this.getAreaCode();          // let apiUrl = `https://your-adviser-api.com/search?q=${query}&area=${area}`;          // if (this.priceFilter && this.priceFilter.value !== 'all') {          //   const val = this.priceFilter.value;          //   if (val === 'under50') apiUrl += '&filter_max_price=50';          //   else if (val === '50_100') apiUrl += '&filter_max_price=100';          //   else if (val === '100_200') apiUrl += '&filter_max_price=200';          //   else if (val === '200_500') apiUrl += '&filter_max_price=500';          // }          // const res = await fetch(apiUrl);          // const rawData = await res.json();          // ======================================================================          // Simulating network latency          await new Promise(resolve => setTimeout(resolve, 400));                    const rawData = this.getAdviserMockData();          let offers = [];                    if (rawData && rawData.data && rawData.data.Get && Array.isArray(rawData.data.Get.Deal)) {            offers = rawData.data.Get.Deal;          }                    // Basic client-side filtering for the mock if we want it to react to the query          const q = query.toLowerCase();          const selectedRetailer = (this.retailerSelect && this.retailerSelect.value) ? this.retailerSelect.value.toLowerCase() : null;                    offers.forEach(item => {            const dataObj = item;                        // Apply retailer filter            const itemRetailer = (dataObj.dataRetailer || '').toLowerCase();            if (selectedRetailer && itemRetailer !== selectedRetailer && !itemRetailer.includes(selectedRetailer)) {              return;            }                        // Apply mock price filter            let price = dataObj.dataDiscountedPrice || 0;            if (typeof price === 'string') {              price = parseFloat(price.replace(/[^0-9.]/g, ''));            }            let priceVal = null;            const min = this.customPriceMin ? this.customPriceMin.value : '';            const max = this.customPriceMax ? this.customPriceMax.value : '';            if (min || max) {               priceVal = `${min}_${max}`;            } else if (this.priceFilter && this.priceFilter.value !== 'all') {               priceVal = this.priceFilter.value;            }            if (priceVal) {              if (priceVal === 'under50' && price >= 50) return;              if (priceVal === 'over50' && price <= 50) return;              if (priceVal === 'over30' && price <= 30) return;              if (priceVal === 'over500' && price <= 500) return;              if (priceVal.includes('_')) {                 const parts = priceVal.split('_');                 if (parts[0] && price < parseFloat(parts[0])) return;                 if (parts[1] && price > parseFloat(parts[1])) return;              }            }                        // Map Adviser schema to our widget's expected schema            const mappedData = {              url: dataObj.linkHREF || dataObj.dataLink || '#',              image: dataObj.imageURL || (dataObj.image && dataObj.image.src) || '',              title: dataObj.dataProduct || (dataObj.product && dataObj.product.name) || 'Product Deal',              merchant: dataObj.dataRetailer || 'Retailer',              price: dataObj.dataDiscountedPrice || 0,              currency: dataObj.dataCurrency === 'USD' ? '$' : (dataObj.dataCurrency || '$'),              msrp: dataObj.dataOriginalPrice || null            };                        const titleLow = mappedData.title.toLowerCase();            const merchLow = mappedData.merchant.toLowerCase();                        // Smarter mock filtering            let isMatch = false;            if (q === '' || this.isBroadQuery(q)) {              isMatch = true;            } else if (titleLow.includes(q) || merchLow.includes(q)) {              isMatch = true;            } else if ((q.includes('laptop') || q.includes('mac') || q.includes('pc')) && (titleLow.includes('macbook') || titleLow.includes('laptop'))) {              isMatch = true;            } else if ((q.includes('tv') || q.includes('television')) && (titleLow.includes('tv') || titleLow.includes('oled') || titleLow.includes('qled'))) {              isMatch = true;            } else if ((q.includes('phone') || q.includes('smartphone')) && (titleLow.includes('galaxy') || titleLow.includes('phone'))) {              isMatch = true;            } else if ((q.match(/watch|fitness|run|shoe/)) && (titleLow.includes('forerunner') || titleLow.includes('saucony') || titleLow.includes('watch'))) {              isMatch = true;            }                        if (isMatch) {               this.deals.push(this.extractDealData(mappedData));            }          });                    let rowLimit = this.getRowsLimit();          // Intentionally omitting the slice here to allow "Load More" to work if the API returns more                    this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        getAdviserMockData() {          return {            "data": {              "Get": {                "Deal": [                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 300,                    "dataOriginalPrice": 399,                    "dataProduct": "Samsung Galaxy A36",                    "dataRetailer": "Samsung",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/MqDYsukV3JBG54te6dEs7j.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 14,                    "dataOriginalPrice": 24,                    "dataProduct": "Blink Mini",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/3JurmAjHsDa5tPdaHAwEV8.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 59,                    "dataOriginalPrice": 99,                    "dataProduct": "Ring Video Doorbell",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/rAh4uR7AsAsALCCLTXnLNJ.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 10,                    "dataOriginalPrice": 599,                    "dataProduct": "MacBook Neo",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/Lg4Dvg68j9SbB5CPNrTEpH.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 749,                    "dataOriginalPrice": 849,                    "dataProduct": "65\\\" Fire TV Omni 4K QLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/SG34ZWodUkLTxJvMTbjPYR.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 71,                    "dataOriginalPrice": 160,                    "dataProduct": "Saucony Hurricane 24",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/vxf7UD5T2Am7guVzFoFcZ4.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 649,                    "dataOriginalPrice": 749,                    "dataProduct": "Garmin Forerunner 970",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/3GKnEu7CdhtxPMfnPCMCiA.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1049,                    "dataOriginalPrice": 1499,                    "dataProduct": "LG 48\\\" C4 4K OLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/imvwZV9zoMD6fn9Afuge35.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1499,                    "dataOriginalPrice": 2199,                    "dataProduct": "Samsung 49\\\" Odyssey Neo G9 4K Gaming Monitor",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/XWDEJ5dUAE2nhK8k3Jk7k7.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 299,                    "dataOriginalPrice": 699,                    "dataProduct": "EGOHOME Black Memory Foam Mattress (queen)",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/hMUemtAejNETLVYxNrktzm.jpg"                  }                ]              }            }          };        }        decodeHTML(html) {          if (!html) return '';          const txt = document.createElement("textarea");          txt.innerHTML = String(html);          return txt.value;        }        extractDealData(item) {          const priceRawStr = String(item.price || item.current_price || '0');          const msrpRawStr = String(item.was_price || item.msrp || item.original_price || '0');          const rawPrice = parseFloat(priceRawStr.replace(/[^\d.]/g, '')) || 0;          const rawMsrp = parseFloat(msrpRawStr.replace(/[^\d.]/g, '')) || 0;          const isCheckPrice = rawPrice === 0 || priceRawStr === '0.00' || priceRawStr === '0';                    let originalImageUrl = item.image || item.image_url || item.product_image || '';          let imageUrl = originalImageUrl;          if ((!imageUrl || isCheckPrice) && item.model_image_url) {             imageUrl = item.model_image_url;             originalImageUrl = imageUrl;          } else if ((!imageUrl || isCheckPrice) && item.model_image) {             imageUrl = item.model_image;             originalImageUrl = imageUrl;          }                    if (imageUrl) {            imageUrl = imageUrl.replace(/-(\d+)-(\d+)(\.[a-z.]+)$/i, '$3');          }                    let fallbackImage = '';          if (originalImageUrl && originalImageUrl !== imageUrl) {             fallbackImage = originalImageUrl;          } else if (item.model_image && item.model_image !== imageUrl) {             fallbackImage = item.model_image;          } else if (item.model_image_url && item.model_image_url !== imageUrl) {             fallbackImage = item.model_image_url;          }                    const rawCurrency = item.currency || item.currency_symbol || '$';                    let savingLabel = item.percentage_saving_label || '';          if (!savingLabel && rawMsrp > rawPrice && rawPrice > 0) {            const pct = Math.round(((rawMsrp - rawPrice) / rawMsrp) * 100);            if (pct > 0) {              savingLabel = `${pct}% OFF`;            }          }                    const isPrime = item.shipping && item.shipping.prime === true;                    let scoreRaw = (item.review_score !== undefined && item.review_score !== null && item.review_score > 0) ? parseFloat(item.review_score) : null;          let starRating = 0;          if (scoreRaw !== null) {            starRating = Math.round((scoreRaw > 10 ? scoreRaw / 20 : scoreRaw / 2) * 2) / 2;          }                    return {            id: item.offer_id || item.link || item.url || item.offer_link || Math.random().toString(),            url: item.link || item.url || item.offer_link || '#',            image: imageUrl,            fallbackImage: fallbackImage,            title: item.name || item.title || item.model_name || item.product_name || 'Unknown Product',            brand: item.brand || '',            productName: item.model_name || item.product_name || item.name || '',            merchant: item.merchant_name || item.merchant || item.retailer || 'Retailer',            price: item.price !== undefined ? String(item.price) : '0.00',            currency: this.decodeHTML(rawCurrency),            msrp: item.was_price || item.msrp || item.original_price || null,            rawPrice: rawPrice,            rawMsrp: rawMsrp,            hasWasPrice: (item.was_price !== undefined && item.was_price !== null),            isCheckPrice: isCheckPrice,            savingLabel: savingLabel,            isPrime: isPrime,            starRating: starRating > 0 ? starRating : null,            modelId: item.model_id || '',            productKey: item.product_key || '',            merchantId: (item.merchant && typeof item.merchant === 'object') ? item.merchant.id || '' : '',            matchId: item.match_id || '',            merchantNetwork: (item.merchant && typeof item.merchant === 'object') ? item.merchant.an || '' : '',            merchantUrl: (item.merchant && typeof item.merchant === 'object') ? item.merchant.url || '' : '',            modelBrand: item.model_brand || item.brand || '',            modelParent: item.model_parent || ''          };        }        sortData() {          const sortVal = this.sortSelect ? this.sortSelect.value : 'date_desc';          if (sortVal === 'price_asc') {            this.deals.sort((a, b) => a.rawPrice - b.rawPrice);          } else if (sortVal === 'price_desc') {            this.deals.sort((a, b) => b.rawPrice - a.rawPrice);          } else if (sortVal === 'discount_desc') {            this.deals.sort((a, b) => {              const aDiscount = a.rawMsrp > a.rawPrice ? (a.rawMsrp - a.rawPrice) : 0;              const bDiscount = b.rawMsrp > b.rawPrice ? (b.rawMsrp - b.rawPrice) : 0;              return bDiscount - aDiscount;            });          } else if (sortVal === 'date_desc') {             this.deals.sort((a, b) => {                let dateA = 0;                let dateB = 0;                if (a && a.modifiedDate) {                   const valA = Array.isArray(a.modifiedDate) ? a.modifiedDate[0] : a.modifiedDate;                   dateA = new Date(valA).getTime();                   if (isNaN(dateA)) dateA = 0;                }                if (b && b.modifiedDate) {                   const valB = Array.isArray(b.modifiedDate) ? b.modifiedDate[0] : b.modifiedDate;                   dateB = new Date(valB).getTime();                   if (isNaN(dateB)) dateB = 0;                }                return dateB - dateA;             });          }        }        getFilteredDeals() {          let filteredDeals = [...this.deals];                    if (this.dealModeToggle && this.dealModeToggle.checked) {            filteredDeals = filteredDeals.filter(d => d.hasWasPrice || (d.msrp && d.rawMsrp > d.rawPrice));          }                    return filteredDeals;        }        showLoading() {          const _div = '<' + '/div>';          const skeletonCardHtml = `            \x3Cdiv class="tg-df-card">              \x3Cdiv class="tg-df-card-image-box">                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-img">${_div}              ${_div}              \x3Cdiv class="tg-df-card-body">                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short">${_div}                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text title">${_div}                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text title">${_div}                \x3Cdiv class="tg-df-card-footer mt-auto">                  \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="height:24px;">${_div}                ${_div}              ${_div}              \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text" style="height:44px; margin:0; border-radius:0;">${_div}            ${_div}`;          this.grid.innerHTML = Array(4).fill(skeletonCardHtml).join('');        }        showError() {          const _div = '<' + '/div>';          this.grid.innerHTML = `\x3Cdiv class="tg-df-message">            An error occurred while finding deals. Please check your connection and try again.          ${_div}`;        }        escapeHTML(str) {          if (!str) return '';          return String(str).replace(/[&<>'"]/g, tag => ({              '&': '&', '<': '<', '>': '>', "'": ''', '"': '"'          }[tag] || tag));        }                bindCouponButtons() {          const btns = this.root.querySelectorAll('.tg-df-tag-coupons');          btns.forEach(btn => {            btn.addEventListener('click', (e) => {              e.preventDefault();              e.stopPropagation();              const merchant = btn.getAttribute('data-merchant');              this.openVouchersModal(merchant);            });          });                    const closeBtn = this.root.querySelector('#tg-df-vouchers-close');          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          if (closeBtn) {            closeBtn.onclick = () => this.closeVouchersModal();          }          if (backdrop) {            backdrop.onclick = (e) => {              if (e.target === backdrop) this.closeVouchersModal();            };          }        }                closeVouchersModal() {          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          if (backdrop) backdrop.classList.remove('active');        }                async checkMerchantsCouponsBulk(merchants) {          if (!merchants || merchants.length === 0) return {};          const controller = new AbortController();          const timeoutId = setTimeout(() => controller.abort(), 4000);          try {            const area = this.getAreaCode();            const url = new URL('https://search-api.fie.future.net.uk/widget.php');            url.searchParams.append('model_name', 'Everything');            url.searchParams.append('language', 'en-GB');            if (area) url.searchParams.append('area', area);            url.searchParams.append('combine_product_types', '1');            url.searchParams.append('filter_merchant_name', merchants.join(','));            url.searchParams.append('all_filters', 'false');            url.searchParams.append('exclude_unlabelled', 'false');            url.searchParams.append('include_specs', 'false');            url.searchParams.append('sort', 'voucher');            url.searchParams.append('distinct_merchants', 'natural');            url.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');            url.searchParams.append('rows', '120');            url.searchParams.append('origin', 'widgets-clientside');                        let res; try { res = await fetch(url.toString(), { signal: controller.signal }); } catch (e) { return {}; }            clearTimeout(timeoutId);            if (!res.ok) return {};            const data = await res.json();                        let offers = [];            if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {              offers = data.widget.data.offers;            } else if (data && data.data && Array.isArray(data.data.offers)) {              offers = data.data.offers;            } else if (Array.isArray(data)) {              offers = data;            } else if (data && Array.isArray(data.offers)) {              offers = data.offers;            } else if (data && data.offers && Array.isArray(data.offers.offer)) {              offers = data.offers.offer;            } else if (data && Array.isArray(data.data)) {              offers = data.data;            }                        const foundMerchants = new Set();            offers.forEach(o => {              let mName = o.merchant_name || o.merchant || o.retailer;              if (mName && typeof mName === 'object') mName = mName.name;              if (mName) foundMerchants.add(String(mName).toLowerCase());            });            const resultMap = {};            merchants.forEach(m => {              if (m) resultMap[m] = foundMerchants.has(String(m).toLowerCase());            });            return resultMap;          } catch (e) {            return {};          }        }                async openVouchersModal(merchantName) {          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          const title = this.root.querySelector('#tg-df-vouchers-title');          const content = this.root.querySelector('#tg-df-vouchers-content');                    if (!backdrop || !content) return;                    // HACK: Hide closing tags          const _div = '<' + '/div>';          const _span = '<' + '/span>';          const _a = '<' + '/a>';          const _h4 = '<' + '/h4>';          const _svg = '<' + '/svg>';          const _circle = '<' + '/circle>';          const _polyline = '<' + '/polyline>';          const _rect = '<' + '/rect>';          const _path = '<' + '/path>';                    title.innerText = `${merchantName} Coupons & Deals`;          content.innerHTML = `\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text">${_div}                               \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text">${_div}`;          backdrop.classList.add('active');                    try {            const area = this.getAreaCode();            const url = new URL('https://search-api.fie.future.net.uk/widget.php');            url.searchParams.append('model_name', 'Everything');            url.searchParams.append('language', 'en-GB');            if (area) url.searchParams.append('area', area);            url.searchParams.append('combine_product_types', '1');            url.searchParams.append('filter_merchant_name', merchantName);            url.searchParams.append('all_filters', 'false');            url.searchParams.append('exclude_unlabelled', 'false');            url.searchParams.append('include_specs', 'false');            url.searchParams.append('sort', 'voucher');            url.searchParams.append('distinct_merchants', 'natural');            url.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');            url.searchParams.append('rows', '50');            url.searchParams.append('origin', 'widgets-clientside');                        const res = await fetch(url.toString());            if (!res.ok) throw new Error('API Error');            const data = await res.json();                        let offers = [];            if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {              offers = data.widget.data.offers;            } else if (data && data.data && Array.isArray(data.data.offers)) {              offers = data.data.offers;            } else if (Array.isArray(data)) {              offers = data;            } else if (data && Array.isArray(data.offers)) {              offers = data.offers;            } else if (data && data.offers && Array.isArray(data.offers.offer)) {              offers = data.offers.offer;            } else if (data && Array.isArray(data.data)) {              offers = data.data;            }                        if (offers.length === 0) {              content.innerHTML = `\x3Cdiv class="tg-df-message">No vouchers currently available for ${this.escapeHTML(merchantName)}.${_div}`;              return;            }                        content.innerHTML = offers.map((v, idx) => {              let offerObj = v;              if (v.offers && v.offers.offer) {                offerObj = Array.isArray(v.offers.offer) ? v.offers.offer[0] : v.offers.offer;              } else if (v.offer) {                offerObj = Array.isArray(v.offer) ? v.offer[0] : v.offer;              }              let logoUrl = v.logo_url || offerObj.logo_url || '';              if (!logoUrl && v.merchant) {                if (Array.isArray(v.merchant) && v.merchant.length > 0) logoUrl = v.merchant[0].logo_url || '';                else logoUrl = v.merchant.logo_url || '';              }                            const offerName = offerObj.name || offerObj.title || v.name || v.title || 'Special Offer';              const endTime = offerObj.end_time || v.end_time || '';              const linkUrl = offerObj.link || offerObj.url || v.link || v.url || '#';                            let foundVoucherCode = '';              const findVoucherCode = (obj) => {                if (!obj || typeof obj !== 'object') return;                if (obj.type === 'voucher_code' && obj.display_value) {                  foundVoucherCode = obj.display_value;                  return;                }                if (Array.isArray(obj)) {                  for (const item of obj) {                    findVoucherCode(item);                    if (foundVoucherCode) return;                  }                } else {                  for (const k in obj) {                    if (Object.prototype.hasOwnProperty.call(obj, k)) {                      findVoucherCode(obj[k]);                      if (foundVoucherCode) return;                    }                  }                }              };              findVoucherCode(offerObj);              if (!foundVoucherCode) findVoucherCode(v);                            const voucherCode = foundVoucherCode || offerObj.voucher_code || v.voucher_code || '';              const codeHtml = voucherCode ? `\x3Cspan class="tg-df-voucher-code" data-action="copy-code" data-code="${this.escapeHTML(voucherCode)}" title="Copy to clipboard">                \x3Cspan class="tg-df-voucher-code-text">${this.escapeHTML(voucherCode)}${_span}                \x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-left:6px;flex-shrink:0;" class="tg-df-voucher-copy-icon">                  \x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2">${_rect}                  \x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">${_path}                ${_svg}              ${_span}` : '';                            const logoHtml = logoUrl                 ? `\x3Cimg src="${this.escapeHTML(logoUrl)}" alt="${this.escapeHTML(offerName)}" class="tg-df-voucher-logo" />`                 : `\x3Cdiv class="tg-df-voucher-logo" style="background:#e2e8f0;">${_div}`;                            let expiryHtml = '';              if (endTime) {                let dStr = endTime;                if (!isNaN(dStr) && String(dStr).length === 10) dStr = Number(dStr) * 1000;                const d = new Date(dStr);                if (!isNaN(d.getTime())) {                  const options = { year: 'numeric', month: 'short', day: 'numeric' };                  expiryHtml = `                    \x3Cdiv class="tg-df-voucher-expiry">                      \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">                        \x3Ccircle cx="12" cy="12" r="10">${_circle}                        \x3Cpolyline points="12 6 12 12 16 14">${_polyline}                      ${_svg}                      Expires ${d.toLocaleDateString(undefined, options)}                    ${_div}`;                }              }              const revenueIdVal = generateRevenueId(linkUrl, offerName, merchantName, null);              const rewrittenLinkUrl = rewriteAffiliateLink(linkUrl, area, revenueIdVal);              return `                \x3Ca href="${this.escapeHTML(rewrittenLinkUrl)}" target="_blank" rel="noopener nofollow" class="tg-df-voucher-item"                  data-action="voucher-click"                  data-product-name="${this.escapeHTML(offerName)}"                  data-merchant-name="${this.escapeHTML(merchantName)}"                  data-analytics-id="${this.escapeHTML(offerObj.offer_id || offerObj.id || v.id || '')}"                  data-price=""                  data-previous-price=""                  data-original-link="${this.escapeHTML(linkUrl)}"                  data-revenue-id="${revenueIdVal}"                  data-index="${idx}"                  data-total="${offers.length}"                  data-in-stock="true"                  data-currency="USD"                  data-model-id="${this.escapeHTML(offerObj.model_id || v.model_id || offerObj.id || v.id || '')}"                  data-merchant-id="${this.escapeHTML(offerObj.merchant_id || offerObj.merchant?.id || '')}"                >                  ${logoHtml}                  \x3Cdiv class="tg-df-voucher-content">                    \x3Ch4 class="tg-df-voucher-title">${this.escapeHTML(offerName)}${_h4}                    ${codeHtml}                    ${expiryHtml}                  ${_div}                ${_a}              `;            }).join('');                        // Attach copy functionality            const copyBtns = content.querySelectorAll('[data-action="copy-code"]');            copyBtns.forEach(btn => {              btn.addEventListener('click', async (e) => {                e.preventDefault();                e.stopPropagation();                                const code = btn.getAttribute('data-code');                if (!code) return;                                try {                  const copyToClipboard = async (text) => {                     if (window.navigator.clipboard && window.isSecureContext) {                        try { await window.navigator.clipboard.writeText(text); return; } catch (e) {}                     }                     const textArea = document.createElement("textarea");                     textArea.value = text;                     textArea.style.position = "fixed";                     document.body.appendChild(textArea);                     textArea.focus();                     textArea.select();                     document.execCommand('copy');                     textArea.remove();                  };                  await copyToClipboard(code);                                    // Visual feedback                  btn.classList.add('copied');                  const textSpan = btn.querySelector('.tg-df-voucher-code-text');                  const iconSvg = btn.querySelector('.tg-df-voucher-copy-icon');                                    const origText = textSpan.innerText;                  const origIcon = iconSvg.innerHTML;                                    textSpan.innerText = 'Copied!';                  iconSvg.innerHTML = `\x3Cpolyline points="20 6 9 17 4 12">${_polyline}`;                                    setTimeout(() => {                    if (btn) {                      btn.classList.remove('copied');                      if (textSpan) textSpan.innerText = origText;                      if (iconSvg) iconSvg.innerHTML = origIcon;                    }                  }, 2000);                                    trackElementInteraction({                    id: 'voucher-code-copy',                    name: 'Copy Voucher Code',                    label: `Copied ${code} for ${merchantName}`                  });                } catch (err) {                  console.warn('Failed to copy text: ', err);                }              });            });            // Attach voucher click tracking            const voucherBtns = content.querySelectorAll('[data-action="voucher-click"]');            voucherBtns.forEach(btn => {              btn.addEventListener('click', (e) => {                if (e.target.closest('[data-action="copy-code"]')) return;                                const productName = btn.getAttribute('data-product-name');                const merchantNameAttr = btn.getAttribute('data-merchant-name');                const productId = btn.getAttribute('data-analytics-id');                const price = parseFloat(btn.getAttribute('data-price')) || null;                const prevPriceStr = btn.getAttribute('data-previous-price');                const previousPrice = prevPriceStr ? parseFloat(prevPriceStr) : null;                const originalLink = btn.getAttribute('data-original-link');                const rewrittenLink = btn.getAttribute('href');                const revenueId = btn.getAttribute('data-revenue-id');                const index = parseInt(btn.getAttribute('data-index'), 10) || 0;                const inStock = btn.getAttribute('data-in-stock') === 'true';                const totalText = btn.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: btn.getAttribute('data-model-id') || null,                    matchId: btn.getAttribute('data-match-id') || null,                    brand: btn.getAttribute('data-model-brand') || null,                    parent: btn.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: btn.getAttribute('data-merchant-id') || null,                    network: btn.getAttribute('data-merchant-network') || null,                    url: btn.getAttribute('data-merchant-url') || null,                    name: merchantNameAttr                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: btn.getAttribute('data-currency') || 'USD'                };                if (typeof trackDealClick === 'function') {                  trackDealClick(trackingParams);                }              });            });                                  } catch (e) {            console.warn(e);            content.innerHTML = `\x3Cdiv class="tg-df-message">Failed to load vouchers.${_div}`;          }        }        render() {          try {            if (this.getViewMode() === 'savings_squad' && this.airedaleTags.length > 0) {              if (this.categoryFilterWrapper) {                 this.categoryFilterWrapper.style.display = 'flex';              }              if (this.categoryFilter) {                 const _option = '<' + '/option>';                 let optionsHtml = `\x3Coption value="all">All Categories${_option}`;                 this.airedaleTags.forEach(tag => {                    const isSelected = this.activeDealTag === tag ? 'selected' : '';                    optionsHtml += `\x3Coption value="${this.escapeHTML(tag)}" ${isSelected}>${this.escapeHTML(tag)}${_option}`;                 });                 this.categoryFilter.innerHTML = optionsHtml;                 this.categoryFilter.value = this.activeDealTag || 'all';              }            } else {               if (this.categoryFilterWrapper) {                  this.categoryFilterWrapper.style.display = 'none';               }            }            const displayDeals = this.getFilteredDeals();          // HACK: Hide closing tags from the CMS HTML sanitizer so it doesn't strip them during in-page injection          const _div = '<' + '/div>';          const _span = '<' + '/span>';          const _a = '<' + '/a>';          const _h3 = '<' + '/h3>';          const _p = '<' + '/p>';          const _strong = '<' + '/strong>';          const _sup = '<' + '/sup>';          const _button = '<' + '/button>';          if (displayDeals.length === 0) {            if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {              if (this.deals.length > 0) {                 this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                  No deals match your selected filters.                ${_div}`;              } else if (this.getViewMode() === 'savings_squad' && this.currentQuery.length <= 2) {                 // Do not show "no exact matches" if query is empty for savings_squad                 this.grid.innerHTML = '';              } else {                 this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                  No exact matches found for "\x3Cstrong>${this.escapeHTML(this.currentQuery)}${_strong}". Try adjusting your search term.                ${_div}`;              }            } else {              this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                Search product or category names to discover the best deals from across the web.              ${_div}`;            }            return;          }          let dealsHtml = displayDeals.slice(0, this.displayLimit).map((deal, index) => {            try {               const currencySym = this.escapeHTML(deal.currency);               const isoCurrencyCode = normalizeCurrency(currencySym);               const escapedPrice = this.escapeHTML(deal.price);               const escapedMsrp = this.escapeHTML(deal.msrp);               const areaCode = this.getAreaCode();                              const revenueId = generateRevenueId(deal.url, deal.title, deal.merchant, null);               const originalLink = deal.url;               const rewrittenLink = rewriteAffiliateLink(deal.url, areaCode, revenueId);                        const productCategoryName = 'deals';            const dataAttr = `              data-action="${deal.isCheckPrice ? 'view-similar-click' : 'deal-click'}"              data-analytics-id="${this.escapeHTML(deal.externalProductId || deal.id || '')}"              data-product-name="${this.escapeHTML(deal.title)}"              data-merchant-name="${this.escapeHTML(deal.merchant)}"              data-price="${deal.rawPrice || ''}"              data-previous-price="${deal.rawMsrp || ''}"              data-original-link="${this.escapeHTML(originalLink)}"              data-revenue-id="${revenueId}"              data-index="${index}"              data-total="${displayDeals.length}"              data-in-stock="${deal.inStock !== false}"              data-currency="${this.escapeHTML(isoCurrencyCode)}"              data-model-id="${this.escapeHTML(deal.modelId || '')}"              data-product-key="${this.escapeHTML(deal.productKey || '')}"              data-merchant-id="${this.escapeHTML(deal.merchantId || '')}"            `;                        let priceGroupHtml = '';            let isSavingsSquadMode = this.getViewMode() === 'savings_squad';            let ctaText = 'View Deal';            let formattedPrice = '';            let msrpHtml = '';                        if (deal.isCheckPrice) {              ctaText = 'View Deal';              if (isSavingsSquadMode) {                priceGroupHtml = ``;              } else {                priceGroupHtml = `                  \x3Cdiv class="tg-df-card-price-group">                    \x3Cspan class="tg-df-card-price" style="font-size: 15px; font-weight: 500; font-style: italic;">See price at retailer${_span}                  ${_div}                `;              }            } else {              // Format Price              formattedPrice = escapedPrice.includes(currencySym)                 ? escapedPrice                 : `${currencySym}${escapedPrice}`;                              // Format MSRP              msrpHtml = deal.msrp && deal.rawMsrp > deal.rawPrice                ? `\x3Cspan class="tg-df-card-msrp">${escapedMsrp.includes(currencySym) ? escapedMsrp : currencySym + escapedMsrp}${_span}`                : '';                              priceGroupHtml = isSavingsSquadMode ? `` : `                \x3Cdiv class="tg-df-card-price-group">                  \x3Cspan class="tg-df-card-price">${formattedPrice}${_span}                  ${msrpHtml}                ${_div}              `;            }                        const discountBadgeHtml = deal.savingLabel && !deal.isCheckPrice              ? `\x3Cspan class="tg-df-card-discount-badge">${this.escapeHTML(deal.savingLabel)}${_span}`              : '';                          // HACK for CMS            const _button = '<' + '/button>';            const _svg = '<' + '/svg>';            const _path = '<' + '/path>';            const _rect = '<' + '/rect>';            const _circle = '<' + '/circle>';            const _polyline = '<' + '/polyline>';            const _line = '<' + '/line>';                        let badgesHtml = '';            const primeBadge = deal.isPrime ? `              \x3Cspan class="tg-df-tag tg-df-tag-prime">                \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">                  \x3Cpath d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z">${_path}                ${_svg} Prime              ${_span}            ` : '';                        const couponsBadge = deal.merchant && deal.merchant.toLowerCase().includes('amazon') ? '' : `              \x3Cdiv class="tg-df-coupon-wrapper" data-merchant="${this.escapeHTML(deal.merchant)}" style="display:inline-flex; align-items:center;">                \x3Cdiv class="tg-df-coupon-spinner">${_div}                \x3Cbutton type="button" class="tg-df-tag tg-df-tag-coupons" data-action="coupons-click" data-merchant="${this.escapeHTML(deal.merchant)}" style="display:none;">                  \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">                    \x3Cpath d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z">${_path}                    \x3Cline x1="7" y1="7" x2="7.01" y2="7">${_line}                  ${_svg} Coupons                ${_button}              ${_div}            `;                        // Note: We always add coupons badge if there's a chance, but to allow 3-line titles we check wrapper display state            badgesHtml = `              \x3Cdiv class="tg-df-card-badges">                ${primeBadge}                ${couponsBadge}              ${_div}            `;            const _linearGradient = '<' + '/linearGradient>';            const _polygon = '<' + '/polygon>';            const _stop = '<' + '/stop>';            const _defs = '<' + '/defs>';                        let starHtml = '';            if (deal.starRating) {              let rating = deal.starRating;                            if (rating > 0) {                const fullStars = Math.floor(rating);                const halfStar = (rating - fullStars) >= 0.5 ? 1 : 0;                const emptyStars = Math.max(0, 5 - fullStars - halfStar);                const blue = '#1f69ff'; // Tom's guide brand color from VIEW DEAL button                const gray = '#cbd5e1';                                const starSvgFull = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="${blue}" stroke="${blue}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26">${_polygon}${_svg}`;                                const gradId = 'half_grad_' + Math.floor(Math.random()*1000000);                const starSvgHalf = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" stroke="${blue}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cdefs>\x3ClinearGradient id="${gradId}" x1="0" x2="1" y1="0" y2="0">\x3Cstop offset="50%" stop-color="${blue}">${_stop}\x3Cstop offset="50%" stop-color="transparent">${_stop}${_linearGradient}${_defs}                  \x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26" fill="url(#${gradId})">${_polygon}${_svg}`;                                  const starSvgEmpty = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="${gray}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26">${_polygon}${_svg}`;                                let stars = [];                for (let i=0; i<fullStars; i++) stars.push(starSvgFull);                if (halfStar) stars.push(starSvgHalf);                for (let i=0; i<emptyStars; i++) stars.push(starSvgEmpty);                                starHtml = `\x3Cdiv class="tg-df-card-stars" style="display:flex;align-items:center;margin-bottom:8px;font-size:13px;font-weight:600;color:var(--tg-df-text-muted);">                  \x3Cspan style="margin-right:6px;">Tom's Guide:${_span}                  \x3Cdiv style="display:flex;gap:2px;">                    ${stars.join('')}                  ${_div}                ${_div}`;              }            }            let htmlOutput = '';            if (isSavingsSquadMode) {              htmlOutput += `              \x3Cdiv class="hawk-deal-widget-container tg-df-mobile-only" data-collapsible="true">                ${this.editorMode ? `\x3Cinput type="checkbox" class="tg-df-deal-checkbox" data-id="${this.escapeHTML(deal.id)}" ${this.selectedDeals.has(deal.id) ? 'checked' : ''} style="margin-bottom: 10px;">` : ''}                \x3Cdiv class="hawk-deal-widget-wrap">                  \x3Cdiv class="hawk-deal-widget-image-container">                    \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" rel="sponsored noopener" target="_blank" class="hawk-affiliate-link-deal-widget" ${dataAttr}>                      \x3Cimg ${deal.image ? `src="${this.escapeHTML(deal.image)}"` : ''} alt="${this.escapeHTML(deal.title)}" class="hawk-lazy-image-deal-widget" loading="lazy" width="140" height="160" onerror="${deal.fallbackImage ? `if(!this.dataset.fb) { this.dataset.fb='1'; this.src='${this.escapeHTML(deal.fallbackImage)}'; } else { this.style.opacity='0'; }` : `this.style.opacity='0';`}">                    ${_a}                  ${_div}                  \x3Cdiv class="hawk-deal-widget-text-cta-container">                    \x3Cdiv class="hawk-deal-widget-text-body-container">                      \x3Cdiv class="hawk-deal-widget-text-body-main">                        \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                          ${deal.isCheckPrice ? `                            \x3Cspan class="hawk-deal-widget-title-product-title">${this.escapeHTML(deal.title)}${_span}                          ` : `                            \x3Cspan class="hawk-deal-widget-title-product-title">${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_span}                          `}                        ${_a}                        ${!deal.isCheckPrice && deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `                          \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                            \x3Cspan class="hawk-deal-widget-title-was-price">was ${currencySym}${escapedMsrp}${_span}                          ${_a}                        ` : ''}                        \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                          \x3Cspan class="hawk-deal-widget-title-retailer-price">                            ${!deal.isCheckPrice ? `                              \x3Cspan class="hawk-deal-widget-title-price">now ${formattedPrice}${_span}                              \x3Cspan class="hawk-deal-widget-title-retailer"> at ${this.escapeHTML(deal.merchant)}${_span}                            ` : `                              \x3Cspan class="hawk-deal-widget-title-price">See price at ${this.escapeHTML(deal.merchant)}${_span}                            `}                          ${_span}                        ${_a}                        ${deal.description ? `\x3Cdiv class="hawk-deal-widget-text-body-description tg-df-card-desc-container" style="margin-bottom: 12px; position: relative;">                          \x3Cp class="tg-df-card-desc-content" style="font-size: 13px; color: var(--tg-df-text-muted); margin-bottom: 0; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;">${this.escapeHTML(deal.description)}${_p}                          \x3Cbutton type="button" class="tg-df-card-desc-btn" style="display: none; appearance: none; border: none; color: #000000; font-size: 11px; font-weight: 700; text-transform: uppercase; cursor: pointer; font-family: inherit; position: absolute; bottom: 2px; right: 0; background: linear-gradient(to right, transparent, #fff 20%, #fff); padding: 0 0 0 16px;" onclick="                            var c = this.parentNode;                            if (this.dataset.expanded === 'true') {                              var pd = (c.tagName === 'P') ? c : this.previousElementSibling;                              if (c.tagName === 'P') { c.parentNode.appendChild(this); pd = c; }                              pd.style.display = '-webkit-box';                              pd.style.webkitLineClamp = '3';                              this.textContent = 'READ MORE';                              this.style.position = 'absolute';                              this.style.background = 'linear-gradient(to right, transparent, #fff 20%, #fff)';                              this.style.paddingLeft = '16px';                              this.dataset.expanded = 'false';                            } else {                              var pd = this.previousElementSibling;                              pd.style.display = 'inline';                              pd.style.webkitLineClamp = 'unset';                              this.textContent = 'READ LESS';                              this.style.position = 'static';                              this.style.background = 'transparent';                              this.style.paddingLeft = '4px';                              this.dataset.expanded = 'true';                              pd.appendChild(this);                            }                          ">READ MORE${_button}                        \x3C/div>` : ''}                      ${_div}                    ${_div}                    ${deal.authorName ? `                      \x3Cdiv class="tg-df-author-line-mobile" style="padding: 0 0 12px 0; background: transparent;">                         \x3Cdiv style="display: flex; align-items: center; gap: 12px;">                            ${deal.authorImage ? `\x3Cimg src="${this.escapeHTML(deal.authorImage)}" alt="${this.escapeHTML(deal.authorName)}" class="tg-df-author-img" width="40" height="40" style="border-radius: 50%; object-fit: cover; flex-shrink: 0; aspect-ratio: 1 / 1; min-width: 40px; min-height: 40px;">` : ''}                            \x3Cdiv style="display: flex; flex-direction: column;">                               \x3Cdiv style="font-size: 10px; color: var(--tg-df-text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 2px; font-weight: 600;">\x3Cspan style="color: #FF6600;">${this.escapeHTML(deal.merchant)}${_span} deal recommended by:${_div}                               \x3Cdiv style="font-size: 11px; color: var(--tg-df-text); line-height: 1.3;">                                  \x3Cstrong>\x3Ca href="https://www.tomsguide.com/${this.escapeHTML(deal.documentUrl || '').replace(/^\/+/, '')}" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit; border-bottom: 1px dotted var(--tg-df-text-muted);">${this.escapeHTML(deal.authorName)}${_a}${_strong}                                  ${deal.authorRole && !['null', 'nul', 'undefined'].includes(String(deal.authorRole).toLowerCase()) ? ` • ${this.escapeHTML(deal.authorRole)}` : ''}                                  ${deal.modifiedDate ? `\x3Cdiv style="color: var(--tg-df-text-muted); margin-top: 2px;">${getTimeAgo(deal.modifiedDate)}${_div}` : ''}                               ${_div}                            ${_div}                         ${_div}                      ${_div}                    ` : ''}                    \x3Cdiv class="hawk-deal-widget-footer">                      \x3Cdiv class="hawk-deal-widget-button-wrapper">                        \x3Cdiv class="hawk-deal-widget-preferred-partner-wrapper">                          \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-deal-button" rel="sponsored noopener" target="_blank" ${dataAttr}>                            \x3Cspan>View Deal${_span}                          ${_a}                        ${_div}                      ${_div}                    ${_div}                  ${_div}                ${_div}              ${_div}              `;            }            htmlOutput += `              \x3Cdiv class="tg-df-card ${isSavingsSquadMode ? 'tg-df-desktop-only' : ''}">                ${this.editorMode ? `\x3Cinput type="checkbox" class="tg-df-deal-checkbox" data-id="${this.escapeHTML(deal.id)}" ${this.selectedDeals.has(deal.id) ? 'checked' : ''}>` : ''}                \x3Cdiv class="tg-df-card-image-box">                  ${discountBadgeHtml}                  \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" style="display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;">                    \x3Cimg ${deal.image ? `src="${this.escapeHTML(deal.image)}"` : ''} alt="${this.escapeHTML(deal.title)}" class="tg-df-card-image" loading="lazy" onerror="${deal.fallbackImage ? `if(!this.dataset.fb) { this.dataset.fb='1'; this.src='${this.escapeHTML(deal.fallbackImage)}'; } else { this.style.opacity='0'; }` : `this.style.opacity='0';`}">                  ${_a}                  \x3Cdiv class="tg-df-card-merchant-wrapper" style="position: absolute; bottom: 0; right: 0; background: transparent; padding: 8px 12px; z-index: 10;">                     \x3Cspan class="tg-df-card-merchant-pill" style="text-align: right; margin-bottom: 0;" title="${this.escapeHTML(deal.merchant)}">${this.escapeHTML(deal.merchant)}${_span}                  ${_div}                ${_div}                \x3Cdiv class="tg-df-card-body">                  ${starHtml}                  ${badgesHtml}                  \x3Ch3 class="tg-df-card-title tg-df-custom-savings-squad-title" title="${this.escapeHTML(deal.title)}">                    \x3Ca href="${this.escapeHTML(rewrittenLink)}" disable-tracking="true" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit;">                      ${isSavingsSquadMode                         ? (deal.isCheckPrice                             ? (deal.title && deal.title.includes(':')                                 ? `\x3Cstrong>${this.escapeHTML(deal.title.substring(0, deal.title.indexOf(':') + 1))}${_strong}\x3Cspan style="color: #1f69ff; font-weight: normal;">${this.escapeHTML(deal.title.substring(deal.title.indexOf(':') + 1))}${_span}`                                : this.escapeHTML(deal.title)                              )                             : `\x3Cstrong>${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_strong} ${deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `\x3Cspan style="color: #d0021b; text-decoration: line-through; font-weight: normal; margin-right: 4px;">was ${currencySym}${escapedMsrp}${_span} ` : ''}\x3Cspan style="color: #1f69ff; font-weight: normal;">now ${formattedPrice} at ${this.escapeHTML(deal.merchant)}${_span}`                          )                        : this.escapeHTML(deal.title)                      }                    ${_a}                  ${_h3}                  ${deal.description ? `\x3Cdiv class="tg-df-card-desc-container" style="margin-bottom: 12px; position: relative;">                    \x3Cp class="tg-df-card-desc-content" style="font-size: 13px; color: var(--tg-df-text-muted); margin-bottom: 0; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;">${this.escapeHTML(deal.description)}${_p}                    \x3Cbutton type="button" class="tg-df-card-desc-btn" style="display: none; appearance: none; border: none; color: #000000; font-size: 11px; font-weight: 700; text-transform: uppercase; cursor: pointer; font-family: inherit; position: absolute; bottom: 2px; right: 0; background: linear-gradient(to right, transparent, #fff 20%, #fff); padding: 0 0 0 16px;" onclick="                      var c = this.parentNode;                      if (this.dataset.expanded === 'true') {                        var pd = (c.tagName === 'P') ? c : this.previousElementSibling;                        if (c.tagName === 'P') { c.parentNode.appendChild(this); pd = c; }                        pd.style.display = '-webkit-box';                        pd.style.webkitLineClamp = '3';                        this.textContent = 'READ MORE';                        this.style.position = 'absolute';                        this.style.background = 'linear-gradient(to right, transparent, #fff 20%, #fff)';                        this.style.paddingLeft = '16px';                        this.dataset.expanded = 'false';                      } else {                        var pd = this.previousElementSibling;                        pd.style.display = 'inline';                        pd.style.webkitLineClamp = 'unset';                        this.textContent = 'READ LESS';                        this.style.position = 'static';                        this.style.background = 'transparent';                        this.style.paddingLeft = '4px';                        this.dataset.expanded = 'true';                        pd.appendChild(this);                      }                    ">READ MORE${_button}                  \x3C/div>` : ''}                  \x3Cdiv class="tg-df-card-footer">                    ${deal.authorName ? `                    \x3Cdiv class="tg-df-author-line-desktop" style="padding: 0 0 ${isSavingsSquadMode ? 0 : 12}px 0;">                       \x3Cdiv style="display: flex; align-items: center; gap: 10px;">                          ${deal.authorImage ? `\x3Cimg src="${this.escapeHTML(deal.authorImage)}" alt="${this.escapeHTML(deal.authorName)}" class="tg-df-author-img" width="36" height="36" style="border-radius: 50%; object-fit: cover; flex-shrink: 0; aspect-ratio: 1 / 1; min-width: 36px; min-height: 36px;">` : ''}                          \x3Cdiv style="display: flex; flex-direction: column;">                             \x3Cdiv style="font-size: 10px; color: var(--tg-df-text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 2px; font-weight: 600;">Recommended by:${_div}                             \x3Cdiv style="font-size: 11px; color: var(--tg-df-text); line-height: 1.2;">                                \x3Cstrong>\x3Ca href="https://www.tomsguide.com/${this.escapeHTML(deal.documentUrl || '').replace(/^\/+/, '')}" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit; border-bottom: 1px dotted var(--tg-df-text-muted);">${this.escapeHTML(deal.authorName)}${_a}${_strong}                                ${deal.authorRole && !['null', 'nul', 'undefined'].includes(String(deal.authorRole).toLowerCase()) ? ` • ${this.escapeHTML(deal.authorRole)}` : ''}                                ${deal.modifiedDate ? `\x3Cspan style="color: var(--tg-df-text-muted);"> • ${getTimeAgo(deal.modifiedDate)}${_span}` : ''}                             ${_div}                          ${_div}                       ${_div}                    ${_div}                    ` : ''}                    ${priceGroupHtml}                  ${_div}                ${_div}                \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" class="tg-df-card-cta" style="text-decoration: none; border-radius: 0;">${ctaText}${_a}              ${_div}            `;                        return htmlOutput;            } catch (e) {               console.log("Error rendering deal in map for index", index, typeof deal === 'object' ? JSON.stringify(deal) : deal, "MSG:", e.message);               return '';            }          }).join('');                    if (displayDeals.length > this.displayLimit) {            dealsHtml += `              \x3Cdiv style="width: 100%; display: flex; justify-content: center; margin-top: 16px; grid-column: 1 / -1;">                \x3Cbutton type="button" class="tg-df-tag-outline tg-df-load-more" style="padding: 8px 24px; border-radius: 100px; font-weight: 600; font-size: 14px; cursor: pointer;">Load More${_button}              ${_div}            `;          }                    this.grid.innerHTML = dealsHtml;          // Inject JSON-LD          try {            let targetNode = this.hostContainer || document.head;            let jsonLdScript = targetNode.querySelector('#tg-df-json-ld-' + this.widgetId);            if (!jsonLdScript) {                jsonLdScript = document.createElement('script');                jsonLdScript.type = 'application/ld+json';                jsonLdScript.id = 'tg-df-json-ld-' + this.widgetId;                targetNode.appendChild(jsonLdScript);            }            const jsonLdData = {              "@context": "https://schema.org",              "@type": "ItemList",              "itemListElement": displayDeals.slice(0, this.displayLimit).map((deal, index) => {                 let isoCurrency = "USD";                 if (deal.currency === '£') isoCurrency = "GBP";                 else if (deal.currency === '€') isoCurrency = "EUR";                 else if (deal.currency === 'A$') isoCurrency = "AUD";                 else if (deal.currency === 'CA$') isoCurrency = "CAD";                 const areaCode = typeof this.getAreaCode === 'function' ? this.getAreaCode() : 'US';                 const revenueId = typeof generateRevenueId === 'function' ? generateRevenueId(deal.url, deal.title, deal.merchant, null) : '';                 const rewrittenLink = typeof rewriteAffiliateLink === 'function' ? rewriteAffiliateLink(deal.url, areaCode, revenueId) : deal.url;                 return {                   "@type": "ListItem",                   "position": index + 1,                   "item": {                     "@type": "Product",                     "name": deal.title,                     "image": deal.image || "",                     "description": deal.description || "",                     "brand": {                       "@type": "Brand",                       "name": deal.brand || ""                     },                     "offers": {                       "@type": "Offer",                       "priceCurrency": isoCurrency,                       "price": deal.rawPrice || 0,                       "url": rewrittenLink,                       "seller": {                         "@type": "Organization",                         "name": deal.merchant || ""                       }                     }                   }                 };              }).filter(item => item.item.name)            };            jsonLdScript.textContent = JSON.stringify(jsonLdData);          } catch(e) { console.warn("JSON-LD generation failed", e); }          setTimeout(() => {            const contents = this.root.querySelectorAll('.tg-df-card-desc-content');            contents.forEach(p => {              if (p.scrollHeight > p.clientHeight || p.scrollHeight > 60) {                if (p.nextElementSibling) {                  p.nextElementSibling.style.display = 'block';                }              }            });                        // Allow hawklinks.js to discover and rewrite our widget links             // by appending the .article-body class and manually triggering processArticle.            let container = this.root.classList.contains('tg-df-container') ? this.root : this.root.querySelector('.tg-df-container');            if (container && !container.classList.contains('article-body')) {               container.classList.add('article-body');            }            if (this.grid && !this.grid.classList.contains('article-body')) this.grid.classList.add('article-body');            document.dispatchEvent(new CustomEvent('processArticle', { detail: { element: this.root } }));          }, 50);          const loadMoreBtn = this.grid.querySelector('.tg-df-load-more');          if (loadMoreBtn) {            loadMoreBtn.addEventListener('click', () => {              if (typeof trackElementInteraction === 'function') {                trackElementInteraction({ id: 'load-more', name: 'Load more', label: 'Load More Results' });              }              this.displayLimit += this.getRowsLimit();              this.render();            });          }                      this.bindCouponButtons();            this.checkAndUpdateCoupons();          } catch(e) {            console.warn("Widget render error", e);          }        }                async checkAndUpdateCoupons() {          const wrappers = Array.from(this.root.querySelectorAll('.tg-df-coupon-wrapper'));          if (wrappers.length === 0) return;                    const merchants = [...new Set(wrappers.map(w => w.getAttribute('data-merchant')).filter(Boolean))];          if (merchants.length === 0) return;          const couponResultsMap = await this.checkMerchantsCouponsBulk(merchants);                    for (const merchant of merchants) {            const hasCoupons = !!couponResultsMap[merchant];            const merchantWrappers = wrappers.filter(w => w.getAttribute('data-merchant') === merchant);            merchantWrappers.forEach(wrapper => {              const spinner = wrapper.querySelector('.tg-df-coupon-spinner');              const btn = wrapper.querySelector('.tg-df-tag-coupons');                            if (spinner) spinner.style.display = 'none';                            if (hasCoupons && btn) {                btn.style.display = 'inline-flex';              } else if (!hasCoupons) {                wrapper.style.display = 'none';              }            });          }        }        updateFloatingCopyBar() {          if (!this.editorBar || !this.editorSelectedCount) return;          if (this.editorMode && this.selectedDeals.size > 0) {            this.editorBar.style.display = 'flex';            this.editorSelectedCount.innerText = this.selectedDeals.size;          } else {            this.editorBar.style.display = 'none';          }        }        async copySelectedDealsToCMS() {           function htmlToSlate(htmlString) {              if (!htmlString) return [{ type: 'paragraph', children: [{ text: '' }] }];              let doc;              if (typeof window !== 'undefined' && window.DOMParser) {                 doc = new DOMParser().parseFromString(htmlString, 'text/html');              } else {                 doc = document.implementation.createHTMLDocument('');                 doc.body.innerHTML = htmlString;              }                            function parseNode(node, marks = {}) {                  if (node.nodeType === 3) {                      const text = node.textContent;                      if (!text) return null;                      return { text: text, ...marks };                  }                  if (node.nodeType === 1) {                      const tagName = node.tagName.toLowerCase();                      if (tagName === 'br') {                          return { type: 'line-break', children: [{ text: '' }] };                      }                      if (tagName === 'p') {                          let children = Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                          if (children.length === 0) children.push({ text: "" });                          return { type: 'paragraph', children };                      }                      if (tagName === 'strong' || tagName === 'b') {                          const newMarks = { ...marks, bold: true };                          return Array.from(node.childNodes).map(child => parseNode(child, newMarks)).flat().filter(Boolean);                      }                      if (tagName === 'em' || tagName === 'i') {                          const newMarks = { ...marks, italic: true };                          return Array.from(node.childNodes).map(child => parseNode(child, newMarks)).flat().filter(Boolean);                      }                      if (tagName === 'a') {                          const href = node.getAttribute('href') || '';                          let children = Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                          if (children.length === 0) children.push({ text: "" });                          return {                              type: 'link',                              url: href,                              isNoFollow: (node.getAttribute('rel') || '').includes('nofollow'),                              isSponsored: (node.getAttribute('rel') || '').includes('sponsored'),                              isOpenNewTab: node.getAttribute('target') === '_blank',                              isPreventDataRewrite: false,                              children: children                          };                      }                      return Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                  }                  return null;              }                            let blocksArray = [];              let currentParagraphChildren = [];              function flushParagraph() {                  if (currentParagraphChildren.length > 0) {                      blocksArray.push({ type: 'paragraph', children: currentParagraphChildren });                      currentParagraphChildren = [];                  }              }              Array.from(doc.body.childNodes).forEach(node => {                  const parsed = parseNode(node, {});                  const parsedItems = Array.isArray(parsed) ? parsed : (parsed ? [parsed] : []);                  parsedItems.forEach(item => {                      if (item.type === 'paragraph') {                          flushParagraph();                          blocksArray.push(item);                      } else {                          currentParagraphChildren.push(item);                      }                  });              });              flushParagraph();              if (blocksArray.length === 0) {                  blocksArray = [{ type: 'paragraph', children: [{ text: '' }] }];              }              return blocksArray;           }           const blocks = [];                      this.editorCopyBtn.innerHTML = '\x3Cspan class="tg-df-coupon-spinner" style="display:inline-block; margin-right:8px; border-top-color:#fff;">' + '<' + '/span> Copying...';           for (const deal of Array.from(this.selectedDeals.values())) {              const url = deal.url;              const merchant = deal.merchant;              const title = deal.title;              const image = deal.image;              const currentPrice = deal.currency + deal.rawPrice;              const wasPrice = deal.hasWasPrice && deal.rawMsrp > deal.rawPrice ? deal.currency + deal.rawMsrp : '';                            let couponsChildren = [];              try {                  const area = this.getAreaCode();                  const apiUrl = new URL('https://search-api.fie.future.net.uk/widget.php');                  apiUrl.searchParams.append('model_name', 'Everything');                  apiUrl.searchParams.append('language', 'en-GB');                  apiUrl.searchParams.append('area', area);                  apiUrl.searchParams.append('combine_product_types', '1');                  apiUrl.searchParams.append('filter_merchant_name', merchant);                  apiUrl.searchParams.append('all_filters', 'false');                  apiUrl.searchParams.append('exclude_unlabelled', 'false');                  apiUrl.searchParams.append('include_specs', 'false');                  apiUrl.searchParams.append('sort', 'voucher');                  apiUrl.searchParams.append('distinct_merchants', 'natural');                  apiUrl.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');                  apiUrl.searchParams.append('rows', '3');                  apiUrl.searchParams.append('origin', 'widgets-clientside');                                    let res; try { res = await fetch(apiUrl.toString()); } catch (e) { return; }                  if (res.ok) {                      const data = await res.json();                      let offers = [];                      if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {                        offers = data.widget.data.offers;                      } else if (data && data.data && Array.isArray(data.data.offers)) {                        offers = data.data.offers;                      }                                            if (offers.length > 0) {                          couponsChildren.push({ text: "Also check out these coupons: ", bold: true });                          offers.slice(0, 3).forEach((offer, idx) => {                              const actualOffer = offer.offer || offer;                              const offerName = actualOffer.name || actualOffer.title || offer.model_name || offer.title || offer.name || 'Coupon';                              const linkUrl = actualOffer.link || actualOffer.url || actualOffer.offer_link || '#';                              couponsChildren.push({ type: "line-break", children: [{ text: "" }] });                              couponsChildren.push({ text: "🎟️ " });                              couponsChildren.push({                                  type: "link",                                  url: linkUrl,                                  isNoFollow: true,                                  isSponsored: false,                                  isOpenNewTab: true,                                  isPreventDataRewrite: false,                                  children: [{ text: offerName, bold: true }]                              });                          });                      }                  }              } catch (err) {                  console.warn('Failed to fetch coupons for', merchant, err);              }              let descriptionValue = [];              if (deal.text) {                 descriptionValue = htmlToSlate(deal.text);              } else {                 const dealDescriptions = [                   `Don't miss out on this fantastic deal for the ${title}. It is currently available at ${merchant} for a highly competitive price.`,                   `We've spotted an excellent price drop on the ${title}. Grab it now at ${merchant} before it's gone.`,                   `The ${title} is currently seeing a generous discount over at ${merchant}. This is a perfect time to buy if you've been holding out.`,                   `If you're in the market for the ${title}, ${merchant} has just the deal for you.`,                   `Score the ${title} for less at ${merchant} right now. This is a rare chance to save big.`,                   `Upgrade your setup with the ${title}, now available at a stellar price via ${merchant}.`                 ];                 const randomDescription = dealDescriptions[Math.floor(Math.random() * dealDescriptions.length)];                 descriptionValue = [                    { type: "paragraph", children: [{ text: randomDescription }] }                 ];              }                            if (couponsChildren.length > 0) {                 let lastBlock = descriptionValue[descriptionValue.length - 1];                 if (lastBlock && lastBlock.type === 'paragraph') {                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children.push({ text: "Also check out these coupons: ", bold: true });                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children = lastBlock.children.concat(couponsChildren);                 } else {                     descriptionValue.push({                         type: "paragraph",                         children: [                             { type: "line-break", children: [{ text: "" }] },                             { type: "line-break", children: [{ text: "" }] },                             { text: "Also check out these coupons: ", bold: true },                             { type: "line-break", children: [{ text: "" }] },                             ...couponsChildren                         ]                     });                 }              }              function normalizeCurrencyToISO(symbol) {                const map = { '£': 'GBP', '$': 'USD', 'A$': 'AUD', 'CA$': 'CAD', '€': 'EUR' };                return map[symbol] || symbol;              }              const isoCurrency = normalizeCurrencyToISO(deal.currency);              blocks.push({                 id: (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : 'cms-' + Date.now() + Math.random(),                 blockTypeName: "deal",                 excludeFrom: [],                 collapsible: false,                 props: {                    description: {                       value: descriptionValue,                       touched: false,                       validationMessage: ""                    },                    image: {                       value: {                          credit: [{ type: "paragraph", children: [{ text: merchant }] }],                          dateCreated: Date.now(),                          dateModified: Date.now(),                          distribution: [],                          fileSize: 0,                          height: 1000,                          id: deal.id,                          imageRights: "",                          src: image,                          name: title + ".jpg",                          tags: [],                          width: 1000                       },                       touched: false,                       validationMessage: ""                    },                    showDealButton: { value: true, touched: false, validationMessage: "" },                    isPreferredPartner: { value: false, touched: false, validationMessage: "" },                    linkHref: { value: url, touched: false, validationMessage: "" },                    linkLabel: { value: "", touched: false, validationMessage: "" },                    linkIsNoFollow: { value: true, touched: false, validationMessage: "" },                    linkIsSponsored: { value: false, touched: false, validationMessage: "" },                    linkIsOpenNewWindow: { value: true, touched: false, validationMessage: "" },                    customPromoFlags: { value: [], touched: false, validationMessage: "" },                    showStarDeal: { value: false, touched: false, validationMessage: "" },                    savingType: { value: "none", touched: false, validationMessage: "" },                    starDealPromoFlag: { value: "", touched: false, validationMessage: "" },                    showEditorsChoice: { value: false, touched: false, validationMessage: "" },                    editorsChoiceTitle: { value: "", touched: false, validationMessage: "" },                    hawkPriceCurrency: { value: { value: isoCurrency, label: isoCurrency }, touched: false, validationMessage: "" },                    hawkPrice: { value: deal.hasWasPrice ? String(deal.rawMsrp) : String(deal.rawPrice), touched: false, validationMessage: "" },                    hawkSalePrice: { value: String(deal.rawPrice), touched: false, validationMessage: "" },                    lastCheckedPriceDate: { value: "", touched: false, validationMessage: "" },                    hawkModel: { touched: false, validationMessage: "" },                    productId: { value: "", touched: false, validationMessage: "" },                    voucherId: { value: "", touched: false, validationMessage: "" },                    brand: { value: deal.brand || merchant, touched: false, validationMessage: "" },                    productName: { value: title, touched: false, validationMessage: "" },                    label: { value: "", touched: false, validationMessage: "" },                    retailer: { value: merchant, touched: false, validationMessage: "" },                    priceCheckError: false                 },                 failedFetchError: ""              });           }           const payload = {              type: "articleBuilderPages",              data: blocks           };           const jsonStr = JSON.stringify(payload);                      if (navigator.clipboard && navigator.clipboard.writeText) {              navigator.clipboard.writeText(jsonStr).then(() => {                 this.editorCopyBtn.innerHTML = 'Copied!';                 setTimeout(() => {                    this.editorCopyBtn.innerHTML = '\x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2"><' + '/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"><' + '/path><' + '/svg> Copy to CMS';                 }, 2000);              }).catch(err => {                 console.warn('Failed to copy text: ', err);                 alert('Failed to copy deals to clipboard. See console.');              });           } else {              // Fallback              const textArea = document.createElement("textarea");              textArea.value = jsonStr;              document.body.appendChild(textArea);              textArea.focus();              textArea.select();              try {                 document.execCommand('copy');                 this.editorCopyBtn.innerHTML = 'Copied!';                 setTimeout(() => {                    this.editorCopyBtn.innerHTML = '\x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2"><' + '/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"><' + '/path><' + '/svg> Copy to CMS';                 }, 2000);              } catch (err) {                 console.warn('Fallback: Oops, unable to copy', err);                 alert('Fallback: Failed to copy deals to clipboard.');              }              document.body.removeChild(textArea);           }        }      }      // Initialize the Widget      if (document.readyState === 'loading') {        document.addEventListener('DOMContentLoaded', () => new DealsFinderWidget({ rootId: 'signal-deals-finder-root', rootNode: shadowRoot, hostContainer: hostContainer }));      } else {        new DealsFinderWidget({ rootId: 'signal-deals-finder-root', rootNode: shadowRoot, hostContainer: hostContainer });      }    })();  </script></div> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/how-to-save-up-to-usd885-on-the-new-iphone-duo</link>
                                                                            <description>
                            <![CDATA[ Preorders for the iPhone Duo start on October 16. Here's how you can avoid paying full price. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">vNtsHycpwSinJx9FbvaQNM</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/7QMQTBU6yXm2axztKNZtnU-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 23 Sep 2026 11:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                                    <dc:creator><![CDATA[ Olivia Halevy ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/YAg7Fmh9dGKbg3hULBMWiU-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Olivia is a Deals Writer at Tom’s Guide. She loves all things lifestyle, shopping and sourcing the best deals from some of the top brands, retailers and websites around. From fashion and beauty to smart home and tech, she has an eye for finding practical, stylish, and reasonably-priced items that help make life simpler (and a little more aesthetically-pleasing).&amp;nbsp;Olivia has over five years of experience writing lifestyle, commerce, and branded content for &lt;a href=&quot;http://patch.com/&quot;&gt;Patch.com&lt;/a&gt;. She&#039;s covered major shopping holidays like Amazon Prime Day, Black Friday and Cyber Monday. In her free time, she enjoys trying out new exercise classes, binge-watching the latest viral TV shows, cooking, spending time with family and taking long walks with her dog, Gus.&amp;nbsp;&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/7QMQTBU6yXm2axztKNZtnU-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide / Jeff Parsons]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone Duo hands-on pictures]]></media:description>                                                            <media:text><![CDATA[iPhone Duo hands-on pictures]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone Duo hands-on pictures]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/7QMQTBU6yXm2axztKNZtnU-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> preorders don't start until October 16 at 8:00 a.m. ET — but that doesn't mean you can't start hunting for deals and discounts now. Apple's first foldable device was announced during the company's <a href="https://www.tomsguide.com/news/live/apple-event-live-foldable-iphone-iphone-18-pro-max-apple-watch-12-and-all-the-big-news">"Surprise and Shine" event</a> and will be available for purchase on October 23. </p><p>The new 5.4-inch phone and tablet in one device opens up to revel a huge 7.6-inch nano-texture display starts at $1,999, making it Apple's most expensive phone yet. That's a tough pill to swallow in today's economy, but I'm here to help you find the best iPhone Duo preorder deals well in advance of the release date.</p><p>iPhone Duo preorder deals have yet to start, but the <a href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow">Apple Store is already offering $35 to $885 in credit via trade-in</a>. For example, an iPhone 8 Plus will land you a $35 credit, whereas an iPhone 17 Pro Max will get you the maximum $885 off credit. I expect to see many more iPhone Duo preorder deals in the weeks to come as carriers release their own offers. </p><p>Below I've listed the best early deals on Apple's iPhone Duo from top carriers and retailers.</p><h3 class="article-body__section" id="section-what-you-need-to-know"><span>What you need to know</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="q4DNX2SeEFU5sCTTt45wEa" name="iphone duo edit 5" alt="iPhone Duo" src="https://cdn.mos.cms.futurecdn.net/q4DNX2SeEFU5sCTTt45wEa-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Current iPhone 18 Pro Max orders are seeing delays, with deliveries showing October 14 to October 21. Considering the strong interest in the iPhone Duo, we expect much longer delivery times with this model — so placing a pre-order as soon as possible is critical if you want to get it with the least amount of wait.</p><p>So far, Apple and major carriers are set to sell the iPhone Duo. While we expect other MVNOs to sell Apple's first foldable phone, it may be a long while before it happens. At the same time, we suspect that unlocked versions of the Duo might be in short supply due to demand. </p><h3 class="article-body__section" id="section-quick-links"><span>Quick Links</span></h3><ul><li><strong>iPhone Duo: </strong><a href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow"><strong>up to $885 w/ trade-in @ Apple Store</strong></a></li><li><strong>iPhone Duo: </strong><a href="https://www.t-mobile.com/cell-phone/apple-iphone-duo?"><strong>preorder October 16 @ T-Mobile</strong></a></li><li><strong>iPhone Duo: </strong><a href="https://www.verizon.com/smartphones/apple-iphone-duo/" target="_blank" rel="nofollow"><strong>waived activation fee @ Verizon</strong></a></li><li><strong>iPhone Duo: </strong><a href="https://www.att.com/buy/phones/apple-iphone-duo.html" target="_blank" rel="nofollow"><strong>preorder October 16 @ AT&T</strong></a></li></ul><h3 class="article-body__section" id="section-iphone-duo"><span>iPhone Duo</span></h3><div class="product"><a data-dimension112="6cc6be5a-b691-11f1-bc79-596df37e8fe3" data-action="Deal Block" data-label="iPhone Duo: up to $885 w/ trade-in @ Apple Store" data-dimension48="iPhone Duo: up to $885 w/ trade-in @ Apple Store" href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:728px;"><p class="vanilla-image-block" style="padding-top:91.48%;"><img id="xkXTUQ8A4RPbEuJRLjy2WH" name="iPhone Deuo" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/xkXTUQ8A4RPbEuJRLjy2WH-1920-80.jpg" mos="" align="middle" fullscreen="" width="728" height="666" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone Duo: </strong><a href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow" data-dimension112="6cc6be5a-b691-11f1-bc79-596df37e8fe3" data-action="Deal Block" data-label="iPhone Duo: up to $885 w/ trade-in @ Apple Store" data-dimension48="iPhone Duo: up to $885 w/ trade-in @ Apple Store" data-dimension25=""><strong>up to $885 w/ trade-in @ Apple Store</strong></a><br>The Apple Store is offering up to a $885 credit when you trade-in your old smartphone for the iPhone Duo. For example, an iPhone 15 will get you up to a $305 credit, while an iPhone 13 Pro will get you up to a $255 credit. Clearly newer models have more value, evident in how an iPhone 17 Pro Max will get you up to $885 off.<a class="view-deal button" href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow" data-dimension112="6cc6be5a-b691-11f1-bc79-596df37e8fe3" data-action="Deal Block" data-label="iPhone Duo: up to $885 w/ trade-in @ Apple Store" data-dimension48="iPhone Duo: up to $885 w/ trade-in @ Apple Store" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="6cc6bedc-b691-11f1-a180-cf86370157dd" data-action="Deal Block" data-label="iPhone Duo: preorder October 16 @ T-Mobile" data-dimension48="iPhone Duo: preorder October 16 @ T-Mobile" href="https://www.t-mobile.com/cell-phone/apple-iphone-duo?" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:50.00%;"><img id="Y26QJd7Ff7aeQmTHuW8nCP" name="NEW T-Mobile Logo" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Y26QJd7Ff7aeQmTHuW8nCP-1920-80.png" mos="" align="middle" fullscreen="" width="600" height="300" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone Duo: </strong><a href="https://www.t-mobile.com/cell-phone/apple-iphone-duo?" data-dimension112="6cc6bedc-b691-11f1-a180-cf86370157dd" data-action="Deal Block" data-label="iPhone Duo: preorder October 16 @ T-Mobile" data-dimension48="iPhone Duo: preorder October 16 @ T-Mobile" data-dimension25=""><strong>preorder October 16 @ T-Mobile</strong></a><br>T-Mobile doesn't have any discounts on the iPhone Duo yet but you preorders will be available on October 16. Despite that, it offers some of the best rates with its unlimited plans.<a class="view-deal button" href="https://www.t-mobile.com/cell-phone/apple-iphone-duo?" target="_blank" rel="nofollow" data-dimension112="6cc6bedc-b691-11f1-a180-cf86370157dd" data-action="Deal Block" data-label="iPhone Duo: preorder October 16 @ T-Mobile" data-dimension48="iPhone Duo: preorder October 16 @ T-Mobile" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="6cc6bf40-b691-11f1-b7b4-11ddb26f0b74" data-action="Deal Block" data-label="iPhone Duo: waived activation fee @ Verizon" data-dimension48="iPhone Duo: waived activation fee @ Verizon" href="https://www.verizon.com/smartphones/apple-iphone-duo/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:400px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="bhuNLVbkmhJxHuYhoz9cuY" name="verizon-redesign-thumb.jpeg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/bhuNLVbkmhJxHuYhoz9cuY-1920-80.jpg" mos="" align="middle" fullscreen="" width="400" height="400" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone Duo: </strong><a href="https://www.verizon.com/smartphones/apple-iphone-duo/" target="_blank" rel="nofollow" data-dimension112="6cc6bf40-b691-11f1-b7b4-11ddb26f0b74" data-action="Deal Block" data-label="iPhone Duo: waived activation fee @ Verizon" data-dimension48="iPhone Duo: waived activation fee @ Verizon" data-dimension25=""><strong>waived activation fee @ Verizon</strong></a><br>Verizon waiving activation and upgrade fees for customers on its Simplicity Plan who enroll in its Verizon Loyalty program. We expect there to be full trade-in offers and deals when iPhone Duo preorders officially open. <a class="view-deal button" href="https://www.verizon.com/smartphones/apple-iphone-duo/" target="_blank" rel="nofollow" data-dimension112="6cc6bf40-b691-11f1-b7b4-11ddb26f0b74" data-action="Deal Block" data-label="iPhone Duo: waived activation fee @ Verizon" data-dimension48="iPhone Duo: waived activation fee @ Verizon" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="6cc6bfae-b691-11f1-b9ce-ff072f7891a3" data-action="Deal Block" data-label="iPhone Duo: preorder October 16 @ AT&amp;T" data-dimension48="iPhone Duo: preorder October 16 @ AT&amp;T" href="https://www.att.com/buy/phones/apple-iphone-duo.html" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:225px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="o9PdShQsgAk95AN7C5UMNR" name="AT&T Logo.jpeg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/o9PdShQsgAk95AN7C5UMNR-1920-80.jpeg" mos="" align="middle" fullscreen="" width="225" height="225" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone Duo: </strong><a href="https://www.att.com/buy/phones/apple-iphone-duo.html" target="_blank" rel="nofollow" data-dimension112="6cc6bfae-b691-11f1-b9ce-ff072f7891a3" data-action="Deal Block" data-label="iPhone Duo: preorder October 16 @ AT&amp;T" data-dimension48="iPhone Duo: preorder October 16 @ AT&amp;T" data-dimension25=""><strong>preorder October 16 @ AT&T</strong></a><br>AT&T doesn't have any discounts on the iPhone Duo yet but you preorders will be available on October 16. <a class="view-deal button" href="https://www.att.com/buy/phones/apple-iphone-duo.html" target="_blank" rel="nofollow" data-dimension112="6cc6bfae-b691-11f1-b9ce-ff072f7891a3" data-action="Deal Block" data-label="iPhone Duo: preorder October 16 @ AT&amp;T" data-dimension48="iPhone Duo: preorder October 16 @ AT&amp;T" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="8bb67c0a-b697-11f1-94a1-afa23a3a111a" data-action="Deal Block" data-label="iPhone Duo: $55.56/month preorder October 16 @ Best Buy" data-dimension48="iPhone Duo: $55.56/month preorder October 16 @ Best Buy" href="https://www.bestbuy.com/product/apple-iphone-duo-256gb-star-white-at-t/JCQ6HTJYJQ" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1331px;"><p class="vanilla-image-block" style="padding-top:68.52%;"><img id="yjsgCbZzcWDLMuhHtLHa7K" name="Best Buy deal block 2022.jpeg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/yjsgCbZzcWDLMuhHtLHa7K-1920-80.jpeg" mos="" align="middle" fullscreen="" width="1331" height="912" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone Duo: </strong><a href="https://www.bestbuy.com/product/apple-iphone-duo-256gb-star-white-at-t/JCQ6HTJYJQ" target="_blank" rel="nofollow" data-dimension112="8bb67c0a-b697-11f1-94a1-afa23a3a111a" data-action="Deal Block" data-label="iPhone Duo: $55.56/month preorder October 16 @ Best Buy" data-dimension48="iPhone Duo: $55.56/month preorder October 16 @ Best Buy" data-dimension25=""><strong>$55.56/month preorder October 16 @ Best Buy</strong></a><br>Right now, Best Buy is showing preorder deals on the iPhone Duo for as low as $55.56/month when it's activated with a 36-month AT&T Installment plan. You'll be able to get this offer starting on October 16. <a class="view-deal button" href="https://www.bestbuy.com/product/apple-iphone-duo-256gb-star-white-at-t/JCQ6HTJYJQ" target="_blank" rel="nofollow" data-dimension112="8bb67c0a-b697-11f1-94a1-afa23a3a111a" data-action="Deal Block" data-label="iPhone Duo: $55.56/month preorder October 16 @ Best Buy" data-dimension48="iPhone Duo: $55.56/month preorder October 16 @ Best Buy" data-dimension25="">View Deal</a></p></div><h3 class="article-body__section" id="section-shop-more-deals"><span>Shop more deals</span></h3><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?brands=Apple&rows=6&view_mode=savings_squad&widget_title=Top+Deals+Handpicked+by+Our+Editors&widget_subtitle=Discover+the+best+discounts+currently+available%2C+curated+daily+by+the+Tom%27s+Guide+Savings+Squad.&bg_color=transparent" data-vizualizer-embed="true"></div>    <script>    /**     * Tom's Guide Deals Finder - Vanilla JS Encapsulated Engine     */    (function() {      // --- Freyr Analytics Adapter ---      function initAnalytics() {        window.dataLayer = window.dataLayer || [];        window.googletag = window.googletag || {};        window.googletag.cmd = window.googletag.cmd || [];        window.hawk = window.hawk || { analytics: { freyr: [] } };        window.hawk.analytics = window.hawk.analytics || { freyr: [] };        window.hawk.analytics.freyr = window.hawk.analytics.freyr || [];        window.freyr = window.freyr || { cmd: [] };        const scriptSrc = 'https://freyr.futurecdn.net/freyr.js';        const hostname = typeof window !== 'undefined' ? window.location.hostname : '';        const isTestEnv = typeof window.navigator !== 'undefined' && (window.navigator.webdriver || window.navigator.userAgent.includes('Headless'));        const shouldSendRealAnalytics = !isTestEnv && hostname && hostname !== 'localhost' && hostname !== '127.0.0.1' && !hostname.includes('run.app');        if (shouldSendRealAnalytics && !document.querySelector(`script[src="${scriptSrc}"]`)) {          const script = document.createElement('script');          script.src = scriptSrc;          script.async = true;          document.head.appendChild(script);        }      }      function storeEventForDebug(name, data) {        if (!window.hawk || !window.hawk.analytics || !window.hawk.analytics.freyr) return;        window.hawk.analytics.freyr.push({ name, data });        try {          if (typeof window !== 'undefined' && window.localStorage) {            window.localStorage.setItem("hawk", JSON.stringify(window.hawk));          }        } catch (e) {          // Ignore storage issues        }        try {          window.dispatchEvent(new CustomEvent("hawk-analytics-update"));        } catch (e) {}      }      function sendToFreyr(eventName, data) {        if (typeof window === 'undefined') return;        window.freyr = window.freyr || { cmd: [] };        window.freyr.cmd.push(() => {          if (window.freyr && window.freyr.pushAndUpdate) {            window.freyr.pushAndUpdate(eventName, data);          }        });      }      function sendEvent(event, skip = false) {        try {          storeEventForDebug(event.name, event.data);          if (!skip) {            sendToFreyr(event.name, event.data);          }        } catch (e) {          // Ensure tracking errors don't surface to the user        }      }      function getCookie(name) {        try {          const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));          return match ? match[2] : null;        } catch (e) {          return null;        }      }      function getTimeAgo(dateString) {        if (!dateString) return '';        const date = new Date(dateString);        const now = new Date();        const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);        if (diffInSeconds < 60) return 'Just now';        const diffInMinutes = Math.floor(diffInSeconds / 60);        if (diffInMinutes < 60) return `${diffInMinutes} min${diffInMinutes > 1 ? 's' : ''} ago`;        const diffInHours = Math.floor(diffInMinutes / 60);        if (diffInHours < 24) return `${diffInHours} hr${diffInHours > 1 ? 's' : ''} ago`;        const diffInDays = Math.floor(diffInHours / 24);        if (diffInDays < 30) return `${diffInDays} day${diffInDays > 1 ? 's' : ''} ago`;        const diffInMonths = Math.floor(diffInDays / 30);        if (diffInMonths < 12) return `${diffInMonths} mo${diffInMonths > 1 ? 's' : ''} ago`;        const diffInYears = Math.floor(diffInDays / 365);        return `${diffInYears} yr${diffInYears > 1 ? 's' : ''} ago`;      }      function normalizeCurrency(symbol) {        const map = {          '£': 'GBP',          '$': 'USD',          'A$': 'AUD',          'CA$': 'CAD',          '€': 'EUR'        };        return map[symbol] || symbol;      }      function trackElementInteraction(props) {        sendEvent({          name: 'elementInteraction',          data: {            element: {              action: props.action || "click",              id: props.id || undefined,              class: props.class || undefined,              name: props.name || undefined,              text: props.text || undefined,              label: props.label || undefined,              container: props.container || undefined,              url: props.url || undefined,              articleId: props.articleId || undefined            }          }        });      }      function generateRevenueId(url, productName, merchantName, modelId) {        const str = `${window.location.href}|${productName}|${merchantName}|${modelId || ''}|${new Date().toDateString()}|tomsguide`;        let hash = 0;        for (let i = 0; i < str.length; i++) {          const char = str.charCodeAt(i);          hash = ((hash << 5) - hash) + char;          hash = hash & hash;        }        let numericStr = Math.abs(hash).toString();        while (numericStr.length < 19) {          numericStr += Math.floor(Math.random() * 10).toString();        }        return numericStr.substring(0, 19);      }      function rewriteAffiliateLink(url, territory, revenueId) {        if (!url) return url;        const t = (territory || 'gb').toLowerCase();        return url.replace(/hawk-custom-tracking/g, `tomsguide-${t}-${revenueId}`);      }      function trackHawkEvent(params) {        const { clickType, widgetId, productCategoryName, product, productsArray, zeroBasedProductIndexOrNull, totalDealsOrProducts, areaClicked, merchant, revenueId, isoCurrencyCode, queryName, widgetTypeName } = params;        const data = {          event: "hawkEvent",          category: "Affiliates",          affiliate: {            action: {              type: clickType,              id: widgetId,              event: clickType === "appeared" ? "viewed" : "Click from",              timestamp: Date.now()            },            component: {              flag: "Editor",              product: productCategoryName || "deals",              category: `Signal Deal Finder ${widgetTypeName || "Carousel"} widget`,              type: clickType === "appeared" ? "review" : "signal product",              label: queryName || (product ? (product.name || "") : ""),              index: zeroBasedProductIndexOrNull === null || zeroBasedProductIndexOrNull === undefined ? -1 : zeroBasedProductIndexOrNull,              linkCount: totalDealsOrProducts || 0,              blockLayout: "",              areaClicked: areaClicked || ""            }          },          products: productsArray || (product && merchant ? [            {              product: {                primary: {                  id: product.id || product.matchId || null,                  name: product.name,                  type: "deal",                  price: product.price,                  previousPrice: product.previousPrice || null,                  currency: isoCurrencyCode || "USD",                  preorder: false,                  labels: [],                  link: product.link,                  originalLink: product.originalLink || null,                  revenueId: revenueId || null,                  startTime: null,                  endTime: null,                  voucherCode: null,                  voucherAudience: null,                  voucherPercentageSaving: null,                  voucherMoneySaving: null,                  voucherType: null,                  offerExclusive: false,                  offerScope: null,                  globalId: product.globalId || null,                  inStock: product.inStock !== false,                  contractProvider: null,                  contractMinutes: null,                  contractTexts: null,                  contractData: null,                  contractLength: null,                  contractMonthlyPrice: null,                  contractCurrency: isoCurrencyCode || "USD"                }              },              merchant: {                id: merchant.id || null,                name: merchant.name,                url: merchant.url || null,                network: merchant.network || null              },              model: {                id: product.modelId || null,                brand: product.brand || null,                name: product.name,                parent: product.parent || null              }            }          ] : []),          reviews: [],          _clear: true,          "gtm.uniqueEventId": Date.now() % 10000        };        sendEvent({ name: 'hawkEvent', data });      }      function trackDealClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Product Card" });      }      function trackViewSimilarClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Product Card View Similar" });      }      function trackPriceComparisonClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Price Comparison" });      }      function trackReviewClick(params) {        trackHawkEvent({ ...params, clickType: "review", areaClicked: "Signal Product Card Review Link" });      }      function trackShare(params) {        trackHawkEvent({ ...params, clickType: "share", areaClicked: "Signal Product Card Share" });      }      function trackDealsAppeared(widgetId, deals, revenueId, currency, queryName, widgetTypeName) {         if (!deals || deals.length === 0) return;                  const productsArray = deals.slice(0, 50).map((deal) => {            let voucherPct = null;            let rawPrice = parseFloat(deal.rawPrice) || parseFloat(deal.price) || null;            let rawMsrp = parseFloat(deal.rawMsrp) || parseFloat(deal.msrp) || null;            if (rawMsrp > rawPrice && rawPrice > 0) {              voucherPct = Math.round((1 - (rawPrice / rawMsrp)) * 100);            }            let numId = null;            if (deal.externalProductId && !isNaN(parseInt(deal.externalProductId))) {              numId = parseInt(deal.externalProductId);            } else if (deal.id && !isNaN(parseInt(deal.id))) {              numId = parseInt(deal.id);            } else {              numId = deal.matchId || null;            }            return {              product: {                primary: {                  id: numId,                  name: deal.productName || deal.title || "",                  type: "deal",                  price: rawPrice,                  previousPrice: rawMsrp,                  currency: currency || 'USD',                  preorder: false,                  labels: deal.modelBrand || deal.brand ? [                     { type: "brand", value: deal.modelBrand || deal.brand }                  ] : [],                  link: deal.url,                  originalLink: deal.url,                  revenueId: revenueId || null,                  startTime: null,                  endTime: null,                  voucherCode: null,                  voucherAudience: null,                  voucherPercentageSaving: voucherPct,                  voucherMoneySaving: null,                  voucherType: null,                  offerExclusive: false,                  offerScope: null,                  globalId: deal.productKey || null,                  inStock: deal.inStock !== false,                  contractProvider: null,                  contractMinutes: null,                  contractTexts: null,                  contractData: null,                  contractLength: null,                  contractMonthlyPrice: null,                  contractCurrency: currency || 'USD'                }              },              merchant: {                id: deal.merchantId ? parseInt(deal.merchantId) : null,                name: deal.merchant || "Retailer",                url: deal.merchantUrl || null,                network: deal.merchantNetwork || null              },              model: {                id: deal.modelId ? parseInt(deal.modelId) : null,                brand: deal.modelBrand || deal.brand || null,                name: deal.productName || deal.title || "",                parent: deal.modelParent || null              }            };         });                  trackHawkEvent({             clickType: "appeared",             widgetId: widgetId,             productCategoryName: "deals",             zeroBasedProductIndexOrNull: null,             totalDealsOrProducts: deals.length,             productsArray: productsArray,             queryName: queryName,             widgetTypeName: widgetTypeName         });      }      // 1. Setup Shadow DOM Sandbox      const currentScript = document.currentScript;      let hostContainer = null;      let template = null;            if (currentScript) {        let prev = currentScript.previousElementSibling;        while (prev) {          if (prev.tagName === 'TEMPLATE' && prev.classList.contains('tg-df-widget-template')) {            template = prev;          } else if (prev.tagName === 'DIV' && prev.classList.contains('tg-df-widget-host') && !prev.hasAttribute('data-initialized')) {            hostContainer = prev;            break;          }          prev = prev.previousElementSibling;        }      }            // Fallbacks in case script is deferred      if (!hostContainer) {        const hosts = document.querySelectorAll('.tg-df-widget-host:not([data-initialized])');        if (hosts.length > 0) hostContainer = hosts[0];      }            // Safely embedded template for CMS environments      const rawTemplate = `  \x3Cstyle>    /* --- Shadow DOM Base Reset --- */    *, *::before, *::after {      box-sizing: border-box;    }    img, picture, svg, video {      max-width: 100%;      height: auto;      display: block;    }    /*       1. Scoped CSS for Tom's Guide Deals Widget       All classes are prefixed with \`tg-df-\` to prevent CMS style leakage.    */    .tg-df-container {      container-type: inline-size;      container-name: tg-df;      --tg-df-blue: #1F69FF;      --tg-df-blue-hover: #004d8c;      --tg-df-text: #222222;      --tg-df-text-muted: #555555;      --tg-df-bg: #ffffff;      --tg-df-bg-secondary: #f4f4f4;      --tg-df-border: #e2e8f0;      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;      color: var(--tg-df-text);      background-color: transparent;       width: 100%;      max-width: 1200px;      margin: 0 auto;      padding-bottom: 24px;    }    .tg-df-container *, .tg-df-container *::before, .tg-df-container *::after {      margin: 0;      padding: 0;      box-sizing: border-box;    }    .tg-df-container img {      border: none;      margin: 0;      padding: 0;    }    .tg-df-container a {      text-decoration: none;      color: inherit;    }    /*       2. Search & Filter Bar    */    .tg-df-controls {      display: flex;      flex-direction: column;      align-items: center;      gap: 20px;      margin-bottom: 32px;      width: 100%;      position: relative;      z-index: 20;    }    .tg-df-top-bar {      display: flex;      width: 100%;      max-width: 760px;      gap: 12px;      margin: 0 auto;      align-items: center;    }    .tg-df-search-wrapper {      position: relative;      flex: 1;      width: 100%;      box-shadow: 0 8px 24px rgba(0,0,0,0.06);      border-radius: 40px;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      z-index: 100;    }    .tg-df-autocomplete-dropdown {      position: absolute;      top: calc(100% + 4px);      left: 0;      right: 0;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 12px;      box-shadow: 0 8px 32px rgba(0,0,0,0.12);      max-height: 300px;      overflow-y: auto;      z-index: 200;      display: none;    }    .tg-df-autocomplete-dropdown.active {      display: block;    }    .tg-df-autocomplete-item {      padding: 12px 24px;      cursor: pointer;      font-size: 14px;      color: var(--tg-df-text);      transition: background 0.1s ease;    }    .tg-df-autocomplete-item:hover {      background: var(--tg-df-bg-secondary);    }    .tg-df-search-input {      width: 100%;      padding: 16px 64px 16px 24px;      font-size: 16px;      border: 2px solid transparent;      border-radius: 40px;      outline: none;      transition: border-color 0.2s ease, box-shadow 0.2s ease;      color: var(--tg-df-text);      background: transparent;    }    .tg-df-search-input:focus {      border-color: transparent;      box-shadow: 0 0 0 3px rgba(0, 108, 196, 0.15);    }    .tg-df-search-input::placeholder {      color: #999999;    }        .tg-df-search-btn {      position: absolute;      right: 8px;      top: 50%;      transform: translateY(-50%);      width: 40px;      height: 40px;      border-radius: 50%;      background: #222;      border: none;      display: flex;      align-items: center;      justify-content: center;      cursor: pointer;      transition: background 0.2s ease;    }        .tg-df-search-btn:hover {      background: #000;    }    .tg-df-search-icon {      width: 16px;      height: 16px;      fill: #fff;    }    .tg-df-settings-wrapper {      position: relative;    }        .tg-df-settings-btn {      width: 48px;      height: 48px;      border-radius: 50%;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      box-shadow: 0 4px 12px rgba(0,0,0,0.04);      display: flex;      align-items: center;      justify-content: center;      cursor: pointer;      transition: all 0.2s ease;      color: var(--tg-df-text-muted);      flex-shrink: 0;    }    .tg-df-settings-btn:hover {      background: var(--tg-df-bg-secondary);      border-color: #0000ff;      color: var(--tg-df-text);    }    .tg-df-settings-btn svg {      width: 24px;      height: 24px;      fill: currentColor;    }    .tg-df-settings-dropdown {      position: absolute;      top: calc(100% + 8px);      right: 0;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 12px;      box-shadow: 0 8px 32px rgba(0,0,0,0.12);      width: 280px;      padding: 20px;      display: none;      z-index: 100;      flex-direction: column;      gap: 20px;    }    .tg-df-settings-dropdown.active {      display: flex;    }        .tg-df-settings-dropdown-backdrop {      display: none;      position: fixed;      inset: 0;      z-index: 99;    }        .tg-df-settings-dropdown-backdrop.active {      display: block;    }    .tg-df-setting-item {      display: flex;      flex-direction: column;      gap: 10px;    }    .tg-df-setting-label {      font-size: 11px;      font-weight: 700;      color: var(--tg-df-text-muted);      text-transform: uppercase;      letter-spacing: 0.5px;    }        .tg-df-region-select {        padding: 10px 12px;        border-radius: 8px;        border: 1px solid var(--tg-df-border);        font-size: 15px;        outline: none;        background: var(--tg-df-bg-secondary);        color: var(--tg-df-text);        cursor: pointer;        width: 100%;    }    .tg-df-toggle {        position: relative;        display: inline-block;        width: 44px;        height: 24px;        flex-shrink: 0;    }    .tg-df-toggle input {        opacity: 0;        width: 0;        height: 0;    }    .tg-df-slider {        position: absolute;        cursor: pointer;        top: 0; left: 0; right: 0; bottom: 0;        background-color: #ccc;        transition: .2s;        border-radius: 24px;    }    .tg-df-slider:before {        position: absolute;        content: "";        height: 18px;        width: 18px;        left: 3px;        bottom: 3px;        background-color: white;        transition: .2s;        border-radius: 50%;    }    .tg-df-toggle input:checked + .tg-df-slider {        background-color: #1F69FF;    }    .tg-df-toggle input:checked + .tg-df-slider:before {        transform: translateX(20px);    }    .tg-df-dl-row {        flex-direction: row;        align-items: center;        justify-content: space-between;    }    .tg-df-dl-row-text {        font-size: 14px;        font-weight: 600;        color: var(--tg-df-text);    }    .tg-df-dl-row-subtext {        font-size: 12px;        font-weight: 400;        line-height: 1.3;        color: var(--tg-df-text-muted);        margin-top: 4px;        display: block;    }    .tg-df-filters-container {      position: relative;      width: 100%;      max-width: 800px;    }    .tg-df-scroll-btn {      display: none;      position: absolute;      top: 50%;      transform: translateY(-50%);      width: 32px;      height: 32px;      background: white;      border: 1px solid var(--tg-df-border);      border-radius: 50%;      align-items: center;      justify-content: center;      cursor: pointer;      z-index: 10;      box-shadow: 0 2px 8px rgba(0,0,0,0.1);      color: var(--tg-df-text-primary);      padding: 0;    }    .tg-df-scroll-btn svg {      width: 16px;      height: 16px;    }    .tg-df-scroll-btn:hover {      background: #f4f4f4;    }    .tg-df-scroll-btn.left {      left: 0px;    }    .tg-df-scroll-btn.right {      right: 0px;    }    @container tg-df (max-width: 768px) {      .tg-df-scroll-btn {        display: flex;        top: 22px; /* vertically center within the 44px high filter buttons */      }    }    .tg-df-filters {      display: grid;      width: 100%;      grid-template-columns: repeat(4, 1fr);      gap: 12px;      margin: 0 auto;      max-width: 800px;    }                 .tg-df-sort-wrapper {      position: relative;      display: flex;      align-items: center;      width: 100%;    }        .tg-df-sort-icon {      position: absolute;      left: 14px;      width: 14px;      height: 14px;      fill: var(--tg-df-text-muted);      pointer-events: none;    }    .tg-df-sort-select, .tg-df-filter-select {      width: 100%;      padding: 10px 36px 10px 38px;      font-size: 14px;      border: 1px solid var(--tg-df-border);      border-radius: 100px;      outline: none;      appearance: none;      background-color: var(--tg-df-bg-secondary);      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12'%3E%3Cpath fill='%23555555' d='M6 8L1 3h10z'/%3E%3C/svg%3E");      background-repeat: no-repeat;      background-position: right 14px center;      color: var(--tg-df-text);      cursor: pointer;      font-weight: 500;      transition: all 0.2s ease;    }        .tg-df-price-input::-webkit-outer-spin-button,    .tg-df-price-input::-webkit-inner-spin-button {      -webkit-appearance: none;      margin: 0;    }    .tg-df-price-input {      -moz-appearance: textfield;    }    .tg-df-sort-select:hover, .tg-df-filter-select:hover {      background-color: #e2e8f0;    }    .tg-df-multiselect-container {      position: relative;    }    @container tg-df (max-width: 768px) {      .tg-df-filters-container {      position: relative;      width: 100%;      max-width: 800px;    }    .tg-df-scroll-btn {      display: none;      position: absolute;      top: 50%;      transform: translateY(-50%);      width: 32px;      height: 32px;      background: white;      border: 1px solid var(--tg-df-border);      border-radius: 50%;      align-items: center;      justify-content: center;      cursor: pointer;      z-index: 10;      box-shadow: 0 2px 8px rgba(0,0,0,0.1);      color: var(--tg-df-text-primary);      padding: 0;    }    .tg-df-scroll-btn svg {      width: 16px;      height: 16px;    }    .tg-df-scroll-btn:hover {      background: #f4f4f4;    }    .tg-df-scroll-btn.left {      left: 0px;    }    .tg-df-scroll-btn.right {      right: 0px;    }    @container tg-df (max-width: 768px) {      .tg-df-scroll-btn {        display: flex;        top: 22px; /* vertically center within the 44px high filter buttons */      }    }    .tg-df-filters {        width: 100%;        margin: 0;        margin-bottom: -320px;        padding: 0 16px 320px 16px;        display: flex;        flex-wrap: nowrap;        gap: 8px;        overflow-x: auto;        overflow-y: hidden;        pointer-events: none;        scrollbar-width: none;        -webkit-overflow-scrolling: touch;      }      .tg-df-filters::-webkit-scrollbar {        display: none;      }      .tg-df-sort-wrapper {        pointer-events: auto;        flex: 0 0 auto;        width: 175px;        min-width: 175px;      }    }        .tg-df-multiselect-trigger {      display: block;      background: #fff;      user-select: none;      width: 100%;      overflow: hidden;      white-space: nowrap;      text-overflow: ellipsis;    }        .tg-df-multiselect-dropdown {      display: none;      position: absolute;      top: calc(100% + 4px);      left: 0;      width: 100%;      min-width: 220px;      max-height: 300px;      overflow-y: auto;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 8px;      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);      z-index: 100;      padding: 8px 0;    }    .tg-df-multiselect-dropdown.active {      display: block;    }    .tg-df-ms-option {      padding: 8px 16px;      display: flex;      align-items: center;      gap: 8px;      cursor: pointer;      font-size: 14px;    }    .tg-df-ms-option:hover {      background-color: var(--tg-df-bg-secondary);    }        .tg-df-ms-option input {      cursor: pointer;      accent-color: #1f69ff;    }    .tg-df-sort-select:focus, .tg-df-filter-select:focus {      border-color: #0000ff;      box-shadow: 0 0 0 3px rgba(0, 0, 255, 0.2);      background-color: var(--tg-df-bg);    }    /*       3. Deal Grid Layout    */    .tg-df-grid.tg-df-grid-auto {      padding-top: 24px;    }    .tg-df-grid, .tg-df-grid.layout-grid {      display: grid;      grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));      gap: 10px;    }    .tg-df-grid.layout-row {      grid-template-columns: 1fr;      gap: 16px;    }        .tg-df-grid.layout-row .tg-df-card {      flex-direction: row;      align-items: stretch;      height: auto;      box-shadow: none;      border-bottom: 1px solid var(--tg-df-border);    }    .tg-df-grid.layout-row .tg-df-card:hover {      box-shadow: none;    }    .tg-df-grid.layout-row .tg-df-card-image-box {      width: 140px;      min-width: 140px;      aspect-ratio: 3/4;      border-right: none;      padding: 16px 16px 16px 32px;    }    .tg-df-grid.layout-row .tg-df-card-body {      padding: 16px;      justify-content: space-between;    }    .tg-df-grid.layout-row .tg-df-card-title {      font-size: 15px;      margin-bottom: 16px;    }    .tg-df-grid.layout-row .tg-df-card-stars { margin-bottom: 8px; }    .tg-df-grid.layout-row .tg-df-card-footer {      flex-direction: column;      align-items: flex-start;      gap: 0;    }    .tg-df-grid.layout-row .tg-df-card-merchant-pill {      margin-bottom: 4px;    }    .tg-df-grid.layout-row .tg-df-card-price-group {      margin-bottom: 8px;    }    .tg-df-grid.layout-row .tg-df-price-group {      width: auto;    }    .tg-df-grid.layout-row .tg-df-card-cta {      width: 100%;      max-width: 200px;      padding: 10px 24px;      font-size: 13px;      flex-shrink: 0;      text-align: center;      justify-content: center;    }    /*       4. Deal Card Design    */    .tg-df-card {      position: relative;      display: flex;      flex-direction: column;      background-color: #ffffff;      border-radius: 0;      overflow: hidden;      transition: transform 0.2s ease, box-shadow 0.2s ease;      text-decoration: none;      color: inherit;      height: 100%;      box-shadow: 0 0 16px rgba(0, 0, 0, 0.08);      border: 1px solid var(--tg-df-border);    }    .tg-df-card:hover {      box-shadow: 0 0 24px rgba(0, 0, 0, 0.12);    }    .tg-df-card-image-box {      width: 100%;      aspect-ratio: 3/4;      background-color: #f8f8f8;      display: flex;      align-items: center;      justify-content: center;      position: relative;      overflow: hidden;      padding: 32px;      flex: 0 0 auto;    }    .tg-df-card-image {      max-width: 100%;      max-height: 100%;      width: auto;      height: auto;      object-fit: contain;      mix-blend-mode: multiply; /* Helps white background images blend into secondary bg */      transition: transform 0.3s ease;    }    .tg-df-card:hover .tg-df-card-image {      transform: scale(1.05); /* Zoom in on hover */    }    .tg-df-card-discount-badge {      position: absolute;      top: 12px;      left: 12px;      background: #dc2626; /* Red */      color: #ffffff;      padding: 6px 8px;      font-size: 11px;      font-weight: 500;      text-transform: uppercase;      letter-spacing: 0.5px;      border-radius: 0;      z-index: 10;    }        .tg-df-card-merchant-pill {      display: block;      padding: 0;      font-size: 11px;      font-weight: 600;      text-transform: uppercase;      letter-spacing: 0.5px;      border-radius: 0;      color: var(--tg-df-text-muted);      margin-bottom: 8px;      white-space: nowrap;      overflow: hidden;      text-overflow: ellipsis;    }    .tg-df-card-body {      padding: 16px;      display: flex;      flex-direction: column;      flex-grow: 1;      min-width: 0;    }    .tg-df-card-badges {      display: flex;      flex-wrap: wrap;      gap: 6px;      margin-bottom: 8px;    }    .tg-df-tag {      display: inline-flex;      align-items: center;      padding: 4px 6px;      font-size: 11px;      font-weight: 700;      text-transform: uppercase;      border-radius: 4px;      gap: 4px;    }    .tg-df-tag-prime {      background-color: #00A8E1;      color: #fff;    }    .tg-df-tag-coupons {      background-color: #f1f5f9;      color: #334155;      border: 1px solid #cbd5e1;      cursor: pointer;      transition: background-color 0.2s;    }    .tg-df-tag-coupons:hover {      background-color: #e2e8f0;    }        .tg-df-tag-outline {      background-color: #f1f5f9;      color: #334155;      border: 1px solid #cbd5e1;      cursor: pointer;      transition: background-color 0.2s;    }    .tg-df-tag-outline:hover {      background-color: #e2e8f0;    }        @keyframes tg-df-spin {      0% { transform: rotate(0deg); }      100% { transform: rotate(360deg); }    }    .tg-df-coupon-spinner {      border: 2px solid #e2e8f0;      border-top: 2px solid #3b82f6;      border-radius: 50%;      width: 14px;      height: 14px;      animation: tg-df-spin 1s linear infinite;      margin: 4px 8px;      display: inline-block;    }        /* Vouchers Modal */    .tg-df-modal-backdrop {      position: fixed;      top: 0; left: 0; right: 0; bottom: 0;      background: rgba(0,0,0,0.5);      z-index: 10000;      display: flex;      align-items: center;      justify-content: center;      opacity: 0;      pointer-events: none;      transition: opacity 0.3s;    }    .tg-df-modal-backdrop.active {      opacity: 1;      pointer-events: auto;    }    .tg-df-modal {      background: #fff;      border-radius: 12px;      width: 90%;      max-width: 400px;      max-height: 80vh;      display: flex;      flex-direction: column;      box-shadow: 0 10px 40px rgba(0,0,0,0.2);      transform: translateY(20px);      transition: transform 0.3s;    }    .tg-df-modal-backdrop.active .tg-df-modal {      transform: translateY(0);    }    .tg-df-modal-header {      padding: 16px;      border-bottom: 1px solid #e2e8f0;      display: flex;      align-items: center;      justify-content: space-between;    }    .tg-df-modal-title {      font-size: 16px;      font-weight: 600;      margin: 0;    }    .tg-df-modal-close {      background: none;      border: none;      cursor: pointer;      padding: 4px;      color: #64748b;    }    .tg-df-modal-body {      padding: 16px;      overflow-y: auto;    }    .tg-df-voucher-item {      padding: 12px;      border: 1px dashed #cbd5e1;      border-radius: 8px;      margin-bottom: 10px;      background: #f8fafc;      display: flex;      align-items: center;      gap: 12px;      text-decoration: none;      color: inherit;      transition: background-color 0.2s, border-color 0.2s;    }    .tg-df-voucher-item:hover {      background: #f1f5f9;      border-color: #94a3b8;    }    .tg-df-voucher-item:last-child {      margin-bottom: 0;    }    .tg-df-voucher-logo {      width: 48px;      height: 48px;      object-fit: contain;      border-radius: 4px;      background: #fff;      border: 1px solid #e2e8f0;      flex-shrink: 0;    }    .tg-df-voucher-content {      flex: 1;      min-width: 0;    }    .tg-df-voucher-title {      font-size: 14px;      font-weight: 600;      margin: 0 0 4px 0;      line-height: 1.3;      color: #0f172a;    }    .tg-df-voucher-expiry {      font-size: 12px;      color: #64748b;      display: flex;      align-items: center;      gap: 4px;      margin-top: 6px;    }    .tg-df-voucher-code {      display: inline-flex;      align-items: center;      background: #f1f5f9;      border: 1px dashed #cbd5e1;      padding: 6px 10px;      font-family: monospace;      font-weight: 700;      font-size: 14px;      color: #0f172a;      border-radius: 4px;      margin-top: 8px;      cursor: pointer;      transition: all 0.2s ease;    }    .tg-df-voucher-code:hover {      background: #e2e8f0;      border-color: #94a3b8;    }    .tg-df-voucher-code.copied {      background: #ecfdf5;      border-color: #10b981;      color: #10b981;    }    .tg-df-voucher-cta {      display: inline-block;      margin-top: 8px;      font-size: 13px;      font-weight: 600;      color: #2563eb;      text-decoration: none;    }    .tg-df-card-title {      font-size: 15px;      font-weight: 400;      line-height: 1.4;      margin: 0 0 12px 0;      color: var(--tg-df-text);    }    .tg-df-card-footer {      margin-top: auto;      display: flex;      flex-direction: column;      width: 100%;    }    .tg-df-card-price-group {      display: flex;      flex-direction: row;      align-items: center;      gap: 8px;      margin-bottom: 12px;    }    .tg-df-card-price {      font-size: 16px;      font-weight: 700;      color: #dc2626; /* Red price */      line-height: 1;    }        .tg-df-card-msrp {      font-size: 13px;      color: var(--tg-df-text-muted);      text-decoration: line-through;    }    .tg-df-container .tg-df-card-cta {      display: flex;      align-items: center;      justify-content: center;      width: 100%;      box-sizing: border-box;      background-color: #1f69ff;      color: #ffffff;      font-size: 12px;      font-weight: 700;      text-transform: uppercase;      letter-spacing: 0.5px;      padding: 12px 16px;      border-radius: 0;      border: none;      cursor: pointer;      transition: background-color 0.2s ease;    }    .tg-df-card:hover .tg-df-card-cta,    .tg-df-card-cta:hover {      background-color: #1555cc;    }    /*       5. State & Skeleton Styles    */    .tg-df-message {      grid-column: 1 / -1;      text-align: center;      padding: 48px 24px;      color: var(--tg-df-text-muted);      font-size: 16px;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 8px;    }    @keyframes tg-df-shimmer {      0% { background-position: -200% 0; }      100% { background-position: 200% 0; }    }    .tg-df-skeleton {      background: linear-gradient(90deg, var(--tg-df-bg-secondary) 25%, #e2e8f0 50%, var(--tg-df-bg-secondary) 75%);      background-size: 200% 100%;      animation: tg-df-shimmer 1.5s infinite;      border-radius: 4px;    }    .tg-df-skeleton-img {      width: 100%;      height: 100%;      position: absolute;      top: 0; left: 0;    }        .tg-df-skeleton-text {      height: 16px;      margin-bottom: 8px;      width: 100%;    }    .tg-df-skeleton-text.short { width: 40%; }    .tg-df-skeleton-text.title { height: 20px; margin-bottom: 16px; }    /* Editor Floating Bar & Elements */    .tg-df-editor-bar {      position: sticky;      top: 120px;      z-index: 1000;      background: #111827;      color: #fff;      padding: 12px 16px;      border-radius: 8px;      margin-bottom: 16px;      display: flex;      align-items: center;      justify-content: space-between;      box-shadow: 0 4px 12px rgba(0,0,0,0.15);    }    .tg-df-editor-bar-text {      font-weight: 600;      font-size: 14px;    }    .tg-df-editor-copy-btn {      background: #10b981;      color: #fff;      padding: 6px 16px;      border: none;      border-radius: 4px;      font-weight: 600;      cursor: pointer;      display: flex;      align-items: center;      font-size: 13px;    }    .tg-df-editor-copy-btn:hover { background: #059669; }        .tg-df-deal-checkbox {      position: absolute;      top: 12px;      right: 12px;      z-index: 10;      width: 20px;      height: 20px;      cursor: pointer;      pointer-events: auto;    }    /*       6. Mobile List View (Stacks into a cleaner horizontal row/list)    */    @container tg-df (max-width: 599px) {      .tg-df-controls {        padding: 16px 16px 8px;      }            .tg-df-top-bar {        width: 100%;      }            .tg-df-settings-dropdown {        position: fixed;        top: auto;        bottom: 0;        left: 0;        right: 0;        width: 100%;        border-radius: 20px 20px 0 0;        padding: 24px;        box-shadow: 0 -8px 32px rgba(0,0,0,0.15);        z-index: 1000;        border: none;        border-top: 1px solid var(--tg-df-border);      }            .tg-df-settings-dropdown-backdrop.active {        background: rgba(0,0,0,0.4);      }            .tg-df-search-wrapper {        box-shadow: 0 0 16px rgba(0,0,0,0.08);      }                  .tg-df-sort-wrapper.tg-df-price-range-wrapper {        flex: 0 0 auto;        min-width: max-content;        width: auto;      }            .tg-df-sort-select, .tg-df-filter-select {        width: 100%;        text-align: left;        padding: 10px 24px 10px 32px;        background-position: right 8px center;        text-overflow: ellipsis;        white-space: nowrap;        overflow: hidden;      }      .tg-df-sort-icon {        left: 10px;      }      .tg-df-grid:not(.layout-grid):not(.layout-row),      .tg-df-grid.layout-row {        grid-template-columns: 1fr;        gap: 16px;      }            .tg-df-grid.tg-df-grid-auto {        padding-top: 24px;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card,      .tg-df-grid.layout-row .tg-df-card {        flex-direction: row;        align-items: stretch;        height: auto;        box-shadow: none; /* simple line on mobile if preferred, or keep */        border-bottom: 1px solid var(--tg-df-border);      }      .tg-df-grid.tg-df-grid-auto .tg-df-card:hover,      .tg-df-grid.layout-row .tg-df-card:hover {        box-shadow: none;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-image-box,      .tg-df-grid.layout-row .tg-df-card-image-box {        width: 120px;        min-width: 120px;        aspect-ratio: 3/4;        border-right: none;        padding: 12px;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-body,      .tg-df-grid.layout-row .tg-df-card-body {        padding: 12px;        justify-content: space-between;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-title,      .tg-df-grid.layout-row .tg-df-card-title {        font-size: 14px;        margin-bottom: 12px;      }      /* Single column mobile grid override */      .tg-df-grid.layout-grid {        grid-template-columns: 1fr;        gap: 16px;      }      .tg-df-grid.layout-grid .tg-df-card-image-box {        padding: 12px;      }      .tg-df-grid.layout-grid .tg-df-card-body {        padding: 10px;      }      .tg-df-grid.layout-grid .tg-df-card-title {        font-size: 13px;        margin-bottom: 8px;      }      .tg-df-grid.layout-grid .tg-df-card-price {        font-size: 14px;      }            .tg-df-card-footer {        flex-direction: column;        align-items: stretch;        gap: 0;        width: 100%;        min-width: 0;      }      .tg-df-card-merchant-pill {        margin-bottom: 4px;      }      .tg-df-card-price-group {        flex: 1 1 auto;        margin-bottom: 8px;      }      .tg-df-card-price {        font-size: 16px;      }      .tg-df-card-msrp {        display: block;       }      .tg-df-grid.layout-row .tg-df-card-cta,      .tg-df-container .tg-df-card-cta {        width: 100%;        max-width: none;        min-width: 0;        box-sizing: border-box;        padding: 8px 16px;        font-size: 12px;        flex: 0 0 auto;        text-align: center;        white-space: normal;        line-height: 1.2;      }    }    .tg-df-container.is-carousel {      min-height: 760px;      background-color: #E7F0FF;      padding: 0 0 24px 0;      border-radius: 24px;      width: 100vw;      max-width: 1200px;      position: relative;      left: 50%;      transform: translateX(-50%);    }    .tg-df-container.is-carousel.hide-header-details {      min-height: 480px;    }    /*       7. Carousel View Mode    */    .tg-df-container .tg-df-carousel-host {      /* Layout is now handled by container wrapper */    }    .tg-df-container .tg-df-carousel-eyebrow {      color: #1F69FF;      font-weight: 700;      font-size: 14px;      text-transform: uppercase;      letter-spacing: 1px;      padding: 24px 16px 0 16px;      display: none;    }    .tg-df-container .tg-df-carousel-query-title {      color: #011535;      font-size: 28px;      font-weight: 600;      padding: 0 16px 24px 16px;      line-height: 1.2;      display: none;    }    .tg-df-container .tg-df-carousel-blue-box {      background-color: transparent;      border-radius: 0;      padding: 24px 24px 0 24px;      margin: 0;      color: #1F69FF;          position: relative;      overflow: hidden;    }    .tg-df-container .tg-df-carousel-bg-circle-1 {      display: none;    }    .tg-df-container .tg-df-carousel-bg-circle-2 {      display: none;    }    .tg-df-container .tg-df-carousel-bg-circle-3 {      display: none;    }    .tg-df-container .tg-df-carousel-box-content {      position: relative;      z-index: 10;    }    .tg-df-container .tg-df-carousel-box-eyebrow {      background-color: transparent;      color: #1F69FF;      font-weight: 700;      font-size: 14px;      text-transform: uppercase;      letter-spacing: 1px;      display: inline-block;      padding: 0;      border-radius: 0;    }    .tg-df-container .tg-df-carousel-box-title {      font-size: 28px;      font-weight: 600;      line-height: 1.2;      margin-top: 8px;      color: #1e293b;    }    .tg-df-container .tg-df-countdown-wrapper {      position: absolute;      top: 0;      right: 0;      display: flex;      flex-direction: column;      align-items: flex-end;      gap: 12px;      transform: scale(0.67);      transform-origin: top right;    }    .tg-df-container .tg-df-countdown-title {      font-size: 14px;      font-weight: 600;      color: #011535;      margin: 0;    }    .tg-df-container .tg-df-countdown-blocks {      display: flex;      gap: 16px;    }    .tg-df-container .tg-df-countdown-item {      display: flex;      flex-direction: column;      align-items: center;      gap: 4px;    }    .tg-df-container .tg-df-countdown-box {      width: 59px;      height: 59px;      background: #03FE9E;      border-radius: 15px;      display: flex;      align-items: center;      justify-content: center;    }    .tg-df-container .tg-df-countdown-num {      font-family: 'Inter', sans-serif;      font-weight: 700;      font-size: 20px;      line-height: normal;      color: #011535;    }    .tg-df-container .tg-df-countdown-label {      font-family: 'Inter', sans-serif;      font-weight: 500;      font-size: 16px;      line-height: normal;      color: #1e293b;      text-transform: uppercase;    }    .tg-df-container .tg-df-carousel-box-subtitle {      font-size: 16px;      margin-top: 8px;      font-weight: 300;      color: #1e293b;      line-height: 24px;    }    .tg-df-container .tg-df-carousel-roundels-wrapper {      position: relative;      margin-top: 24px;      margin-left: -24px;      margin-right: -24px;    }    .tg-df-container .tg-df-carousel-roundels {      display: flex;      gap: 16px;      overflow-x: auto;            scrollbar-width: none;      padding-top: 12px;      padding-bottom: 24px;      padding-left: 24px;      padding-right: 24px;      margin-left: 0;      margin-right: 0;    }        .tg-df-container .tg-df-carousel-scroll-left,    .tg-df-container .tg-df-carousel-scroll-right {      position: absolute;      top: 50%;      transform: translateY(-50%);      height: 36px;      width: 36px;      display: flex;      align-items: center;      justify-content: center;      border-radius: 50%;      background-color: #ffffff;      border: 1px solid #e2e8f0;      box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);      color: #1F69FF;      cursor: pointer;      transition: all 0.2s;      margin-top: -4px;      z-index: 20;    }    .tg-df-container .tg-df-carousel-scroll-left { left: 8px; }    .tg-df-container .tg-df-carousel-scroll-right { right: 8px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-left { left: 0px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-right { right: 0px; }    .tg-df-carousel-filters-outer { margin-left: -24px; margin-right: -24px; padding-left: 24px; padding-right: 24px; }    .tg-df-grid-wrapper { position: relative; }    @container tg-df (max-width: 599px) { .tg-df-carousel-filters-outer { margin-left: -16px; margin-right: -16px; padding-left: 16px; padding-right: 16px; } }        .tg-df-container .tg-df-carousel-scroll-left:hover,    .tg-df-container .tg-df-carousel-scroll-right:hover {      background-color: rgba(255, 255, 255, 0.6);    }    .tg-df-container .tg-df-carousel-roundels::-webkit-scrollbar {      display: none;    }    .tg-df-container .tg-df-roundel {      display: flex;      flex-direction: column;      align-items: center;      gap: 8px;      cursor: pointer;      min-width: 120px;      flex-shrink: 0;    }    .tg-df-container .tg-df-roundel-img-box {      width: 120px;      height: 120px;      border-radius: 50%;      background: white;      display: flex;      align-items: center;      justify-content: center;      overflow: hidden;      box-shadow: 0px 3px 14px 0px rgba(30, 41, 59, 0.08);      transition: box-shadow 0.2s;    }    .tg-df-container .tg-df-roundel:hover .tg-df-roundel-img-box {      box-shadow: 0 0 0 2px #E7F0FF, 0 0 0 4px #1F69FF;    }    .tg-df-container .tg-df-roundel.active .tg-df-roundel-img-box {      box-shadow: 0 0 0 2px #E7F0FF, 0 0 0 4px #1F69FF;    }    .tg-df-container .tg-df-roundel:hover .tg-df-roundel-img-box img {      transform: scale(1.08);    }    .tg-df-container .tg-df-roundel-img-box img {      width: 100%;      height: 100%;      object-fit: contain;      padding: 10px;      box-sizing: border-box;      transition: transform 0.3s ease;    }    .tg-df-container .tg-df-roundel-label {      font-size: 13px;      font-weight: 400;      color: #1e293b;      text-align: center;    }    .tg-df-container .tg-df-carousel-filters-label {      font-size: 16px;      font-weight: 400;      color: #1e293b;      white-space: nowrap;      margin-right: 4px;    }    .tg-df-container .tg-df-carousel-filters-wrap {      display: flex;      align-items: center;      flex-wrap: nowrap;      gap: 8px;      margin-top: 8px;      overflow-x: auto;      scrollbar-width: none;      -webkit-overflow-scrolling: touch;      padding-bottom: 8px;      margin-left: -24px;      margin-right: -24px;      padding-left: 24px;      padding-right: 24px;    }    .tg-df-container .tg-df-carousel-filters-wrap::-webkit-scrollbar {      display: none;    }        .tg-df-container .tg-df-carousel-filter-btn img,    .tg-df-container .tg-df-carousel-filter-btn picture {      height: 20px;      width: 20px;      object-fit: contain;      object-position: center;      display: inline-flex;      align-items: center;      justify-content: center;      margin-right: 6px;    }    .tg-df-container .tg-df-carousel-filter-btn picture img {      margin-right: 0;      height: 100%;      width: 100%;    }    .tg-df-container .tg-df-carousel-filter-btn img.active-img,    .tg-df-container .tg-df-carousel-filter-btn picture:has(.active-img) {      display: none;    }    .tg-df-container .tg-df-carousel-filter-btn:hover img.inactive-img,    .tg-df-container .tg-df-carousel-filter-btn.active img.inactive-img,    .tg-df-container .tg-df-carousel-filter-btn:hover picture:has(.inactive-img),    .tg-df-container .tg-df-carousel-filter-btn.active picture:has(.inactive-img) {      display: none;    }    .tg-df-container .tg-df-carousel-filter-btn:hover img.active-img,    .tg-df-container .tg-df-carousel-filter-btn.active img.active-img,    .tg-df-container .tg-df-carousel-filter-btn:hover picture:has(.active-img),    .tg-df-container .tg-df-carousel-filter-btn.active picture:has(.active-img) {      display: inline-flex;    }    .tg-df-container .tg-df-carousel-filter-btn {      background: #ffffff;      border: 2px solid #1e293b;      color: #1e293b;      border-radius: 24px;      padding: 6px 16px;      font-size: 14px;      font-weight: 600;      cursor: pointer;      transition: all 0.2s;      flex-shrink: 0;      white-space: nowrap;    }    .tg-df-container .tg-df-carousel-filter-btn svg {      margin-right: 6px;    }    .tg-df-container .tg-df-carousel-filter-btn {      display: inline-flex;      align-items: center;    }    .tg-df-container .tg-df-carousel-filter-btn:hover {      background: #1e293b;      color: white;      border-color: #1e293b;    }    .tg-df-container .tg-df-carousel-filter-btn.active {      background: #1e293b;      color: white;      border-color: #1e293b;    }        .tg-df-grid.carousel-compact {      display: flex;      flex-wrap: nowrap;      overflow-x: auto;      gap: 16px;      padding: 16px 24px;      align-items: stretch;      scrollbar-width: none;    }    .tg-df-grid.carousel-compact::-webkit-scrollbar {      display: none;    }    .tg-df-grid.carousel-compact .tg-df-card {      flex: 0 0 auto;      width: 200px;      min-height: auto;      height: auto;      display: flex;      flex-direction: column;      border-radius: 15px;      border: none;      box-shadow: 0 0 16px rgba(0,0,0,0.08);      overflow: visible;    }    .tg-df-grid.carousel-compact .tg-df-card-image-box {      padding: 12px;      background-color: transparent;      border-radius: 15px 15px 0 0;      height: 130px;    }    .tg-df-grid.carousel-compact .tg-df-card-image {      mix-blend-mode: normal;    }    .tg-df-grid.carousel-compact .tg-df-card-discount-badge {      border-radius: 0;      top: 0px;      left: 0px;      padding: 4px 8px;      font-size: 11px;    }    .tg-df-grid.carousel-compact .tg-df-card-body {      padding: 8px 12px 12px 12px;    }    .tg-df-grid.carousel-compact .tg-df-card-title {      font-size: 14px;      font-weight: 400;      margin-bottom: 8px;      color: #011535;    }    .tg-df-grid.carousel-compact .tg-df-card-body:not(:has(.tg-df-card-stars)):not(:has(.tg-df-tag-prime)):not(:has(.tg-df-coupon-wrapper:not([style*="none"]))) > .tg-df-card-title,    .tg-df-grid.carousel-compact .tg-df-card-body:not(:has(.tg-df-card-stars)):has(> .tg-df-card-title:first-child) > .tg-df-card-title {    }    .tg-df-grid.carousel-compact .tg-df-card-cta {      border-radius: 5px;      padding: 8px 10px;      margin-top: 4px;      background-color: #1F69FF;    }    .tg-df-grid.carousel-compact .tg-df-card-price-group {      margin-bottom: 2px;    }    .tg-df-grid.carousel-compact .tg-df-card-merchant-pill {      margin-bottom: 2px;    }    @container tg-df (max-width: 599px) {      .tg-df-container .tg-df-carousel-blue-box-title {        font-size: 24px;      }      .tg-df-container .tg-df-countdown-title {        display: none;      }      .tg-df-container .tg-df-countdown-wrapper {        position: absolute;        top: 0;        right: 0;        align-items: flex-end;        transform: scale(0.40);        transform-origin: top right;      }      .tg-df-container .tg-df-roundel {        min-width: 88px;      }      .tg-df-container .tg-df-roundel-img-box {        width: 88px;        height: 88px;      }    }    /* REPLICA BLOCK STYLES */    .tg-df-grid.layout-replica-2 { grid-template-columns: repeat(2, 1fr) !important; gap: 20px; }    .tg-df-grid.layout-replica-1 { grid-template-columns: 1fr !important; gap: 20px; }        .tg-df-container .hawk-deal-widget-container { border-bottom: 1px solid #e5e7eb; display: flex; flex-direction: column; margin: 0; padding: 20px 0; box-sizing: border-box; font-family: inherit; }    .tg-df-container .hawk-deal-widget-wrap { display: flex; flex-direction: row; align-items: flex-start; width: 100%; gap: 24px; }    .tg-df-container .hawk-deal-widget-image-container { display: flex; flex-shrink: 0; justify-content: center; width: 160px; height: 160px; align-items: center; background: white; margin-bottom: 0px; }    .tg-df-container .hawk-deal-widget-title-product-title { color: #111827; font-size: 18px; font-weight: 700; line-height: 1.4; display: inline; }    .tg-df-container .hawk-deal-widget-title-price { font-size: 18px; font-weight: 700; line-height: 1.4; white-space: nowrap; color: #2563eb; }    .tg-df-container .hawk-deal-widget-title-price-now { font-weight: 700; }    .tg-df-container .hawk-deal-widget-title-retailer-price:hover { text-decoration: underline; }    .tg-df-container .hawk-deal-widget-title-retailer { font-size: 18px; font-weight: 700; line-height: 1.4; color: #2563eb; }    .tg-df-container .hawk-deal-widget-title-was-price { color: #dc2626; font-size: 16px; font-weight: 500; line-height: 1.4; text-decoration: line-through; white-space: nowrap; margin-left: 8px; margin-right: 8px; }    .tg-df-container .hawk-deal-widget-text-body-container { position: relative; width: 100%; box-sizing: border-box; }    .tg-df-container .hawk-deal-widget-text-body-main { font-size: 16px; width: 100%; margin-bottom: 12px; }    .tg-df-container .hawk-deal-widget-text-body-description { display: block; font-size: 15px; margin-top: 12px; color: #4b5563; line-height: 1.6; }    .tg-df-container .hawk-deal-widget-text-body-description p { margin: 0; line-height: 1.6; }    .tg-df-container .hawk-deal-widget-text-cta-container { display: flex; flex-direction: column; gap: 12px; width: 100%; flex: 1; min-width: 0; box-sizing: border-box; }    .tg-df-container .hawk-deal-widget-footer { display: flex; justify-content: flex-end; width: 100%; margin-top: auto; }    .tg-df-container .hawk-deal-widget-button-wrapper { display: flex; flex-direction: column; align-items: flex-end; justify-content: flex-end; width: 100%; }    .tg-df-container .hawk-deal-widget-preferred-partner-wrapper { display: flex; flex-direction: row; }        @container tg-df (min-width: 600px) {      .tg-df-mobile-only { display: none !important; }    }    @container tg-df (max-width: 599px) {      .tg-df-desktop-only { display: none !important; }      .tg-df-grid.layout-replica-2 { grid-template-columns: 1fr !important; }      .tg-df-grid.savings-squad-cards { grid-template-columns: 1fr !important; display: flex; flex-direction: column; }    }    .tg-df-grid.savings-squad-cards .tg-df-card-title {      -webkit-line-clamp: unset !important;      display: block !important;      overflow: visible !important;    }    @container tg-df (max-width: 500px) {      .tg-df-container .hawk-deal-widget-wrap { display: block; }      .tg-df-container .hawk-deal-widget-image-container { display: block; float: left; margin: 0 16px 8px 0; width: 120px; max-width: 120px; height: auto; align-items: normal; justify-content: normal; }      .tg-df-container .hawk-deal-widget-text-cta-container { display: block; text-align: left; }      .tg-df-container .hawk-deal-widget-footer { display: block; margin-top: 16px; clear: both; width: 100%; }      .tg-df-container .hawk-deal-widget-button-wrapper { display: block; width: 100%; }      .tg-df-container .hawk-deal-widget-button-wrapper .hawk-deal-widget-preferred-partner-wrapper { display: block; width: 100%; }      .tg-df-container .hawk-affiliate-link-deal-button { box-sizing: border-box !important; display: flex !important; max-width: none !important; width: 100% !important; margin: 0 !important; }    }        .tg-df-container .hawk-affiliate-link-deal-button {       align-items: center; background-color: #1f69ff; box-sizing: border-box; color: #ffffff !important; display: flex; font-size: 14px; font-weight: 700; justify-content: center; letter-spacing: 0.5px; line-height: 1; min-width: 160px; padding: 14px 24px; text-align: center; text-decoration: none; text-transform: uppercase; width: 100%; word-break: normal; border-radius: 4px; border: 0; transition: background-color 0.2s;     }    .tg-df-container .hawk-affiliate-link-deal-button:hover { background-color: #0056e0; text-decoration: none; }    .tg-df-container .hawk-lazy-image-deal-widget { display: block; height: auto; margin: auto; max-height: 160px; max-width: 100%; mix-blend-mode: multiply; object-fit: contain; }    .tg-df-container .hawk-deal-widget-text-cta-container a { color: #2563eb; text-decoration: none; display: inline; }    .tg-df-container .hawk-deal-widget-text-cta-container a:hover { text-decoration: underline; }    .tg-df-container .hawk-deal-widget-text-cta-container a:has(.hawk-deal-widget-title-product-title) { color: #111827; }    .tg-df-container .hawk-deal-widget-text-cta-container a:hover .hawk-deal-widget-title-product-title,    .tg-df-container .hawk-deal-widget-text-cta-container a:hover .hawk-deal-widget-title-retailer-price { text-decoration: underline; }    .tg-df-savings-squad-header { margin-bottom: 24px; text-align: center; display: none; }    .tg-df-banner-img-desktop { display: block; width: 100%; height: auto; margin-bottom: 32px; }    .tg-df-banner-img-mobile { display: none; width: 100%; height: auto; margin-bottom: 32px; }    @container tg-df (max-width: 600px) {      .tg-df-banner-img-desktop { display: none; }      .tg-df-banner-img-mobile { display: block; }    }    .tg-df-header-title { font-size: 28px; font-weight: 700; color: var(--tg-df-text); margin: 32px 0 12px 0; line-height: 1.3; }    .tg-df-header-subtitle { font-size: 16px; color: var(--tg-df-text-muted); margin: 0 0 32px 0; line-height: 1.5; }  \x3C/style>  \x3C!-- Widget Container --\x3E  \x3Cdiv class="tg-df-container" id="signal-deals-finder-root">    \x3Cdiv class="tg-df-savings-squad-header" id="tg-df-savings-squad-header">      \x3Cpicture>        \x3Cimg src="https://cdn.mos.cms.futurecdn.net/flexiimages/xkh2og7m3d1778189998.png" alt="Deals Banner" class="tg-df-banner-img-desktop" />        \x3Cimg src="https://cdn.mos.cms.futurecdn.net/flexiimages/gmak6rtdf41778245089.png" alt="Deals Banner Mobile" class="tg-df-banner-img-mobile" />      \x3C/picture>      \x3Cdiv class="tg-df-header-text">        \x3Ch2 class="tg-df-header-title" id="tg-df-header-title">Editor's Choice Deals\x3C/h2>        \x3Cp class="tg-df-header-subtitle" id="tg-df-header-subtitle">Discover the best discounts currently available, curated daily by the Tom's Guide Savings Squad.\x3C/p>      \x3C/div>    \x3C/div>    \x3C!-- Editor Floating Bar --\x3E    \x3Cdiv class="tg-df-editor-bar" id="tg-df-editor-bar" style="display:none;">      \x3Cdiv class="tg-df-editor-bar-text" style="display: flex; align-items: center;">        \x3Cspan id="tg-df-selected-count">0\x3C/span>\x26nbsp;Deals Selected        \x3Cbutton class="tg-df-editor-clear-btn" id="tg-df-editor-clear" type="button" style="margin-left: 12px; font-size: 13px; color: #9ca3af; background: none; border: none; cursor: pointer; text-decoration: underline;">Clear All\x3C/button>      \x3C/div>      \x3Cbutton class="tg-df-editor-copy-btn" id="tg-df-editor-copy" type="button">        \x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2">\x3C/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">\x3C/path>\x3C/svg>        Copy to CMS      \x3C/button>    \x3C/div>    \x3Cdiv class="tg-df-carousel-host" id="tg-df-carousel-host" style="display: none;">      \x3Cdiv class="tg-df-carousel-eyebrow">DEAL FINDER\x3C/div>      \x3Cdiv class="tg-df-carousel-query-title" id="tg-df-carousel-title-label">Best Deals\x3C/div>            \x3Cdiv class="tg-df-carousel-blue-box">        \x3Cdiv class="tg-df-carousel-bg-circle-1" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-bg-circle-2" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-bg-circle-3" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-box-content">          \x3Cdiv class="tg-df-countdown-wrapper" id="tg-df-countdown-wrapper" style="display:none;">            \x3Cdiv class="tg-df-countdown-title" id="tg-df-countdown-title">Prime Day starts in\x3C/div>            \x3Cdiv class="tg-df-countdown-blocks">              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-days">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">DAYS\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-hrs">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">HRS\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-min">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">MIN\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-sec">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">SEC\x3C/div>\x3C/div>            \x3C/div>          \x3C/div>          \x3Cdiv class="tg-df-carousel-box-eyebrow">DEAL FINDER\x3C/div>          \x3Cdiv class="tg-df-carousel-box-title">Find Deals Fast\x3C/div>          \x3Cdiv class="tg-df-carousel-box-subtitle">The latest deals from the biggest retailers, all in one place\x3C/div>                    \x3Cdiv class="tg-df-carousel-roundels-wrapper">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-roundels').scrollBy({left: -200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \x3Cdiv class="tg-df-carousel-roundels">                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Televisions" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/wcMxTsHgqu3roMbAx7RLnT-132-100.png" alt="TVs" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">TVs\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Phones" data-pr="over50">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/G3KGaRGzj24F6PUsw4bWpT-132-100.png" alt="Phones" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Phones\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Computing" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/znNvsLzx8NEgNkD9HSFSnT-132-100.png" alt="Computing" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Computing\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Gaming" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/Pgew8yaRQeZFHqHjTzvBnT-132-100.png" alt="Gaming" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Gaming\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Mattresses" data-pr="over500">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/cW7xsaLyesxkHFVSiC4kmT-132-100.png" alt="Mattresses" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Mattresses\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Audio" data-pr="over30">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/pCvBVHuhaQVjKt3VgCjbqT-132-100.png" alt="Audio" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Audio\x3C/span>            \x3C/div>                  \x3C/div>        \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" onclick="this.parentElement.querySelector('.tg-df-carousel-roundels').scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>        \x3C/div>        \x3C/div>        \x3Cdiv class="tg-df-carousel-filters-outer" style="position: relative;">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').scrollBy({left: -200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \x3Cdiv class="tg-df-carousel-filters-wrap">                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="0">All\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-ot="amazon_lightning">              \x3Cimg src="https://cdn.mos.cms.futurecdn.net/HqAui7w97ft2NPqBtQ5r38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/yWPQ5yyQRhUwVKzGwYbh38-600-100.png" class="active-img" alt="" /> Lightning deals\x3C/button>            \x3Cbutton class="tg-df-carousel-filter-btn" data-ot="amazon_prime">              \x3Cimg src="https://cdn.mos.cms.futurecdn.net/fwoVXvL79turN3Ph535m38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/u75QjVpt3w2EsMimJiRo38-600-100.png" class="active-img" alt="" /> Prime deals\x3C/button>            \x3Cbutton class="tg-df-carousel-filter-btn" data-d="10">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 10% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="15">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 15% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="25">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 25% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-pr="under50">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-badge-dollar-sign">\x3Cpath d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z">\x3C/path>\x3Cpath d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8">\x3C/path>\x3Cpath d="M12 18V6">\x3C/path>\x3C/svg>            Under $50\x3C/button>        \x3C/div>        \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>      \x3C/div>    \x3C/div>    \x3C/div>      \x3C!-- Search & Filter Controls --\x3E      \x3Cdiv class="tg-df-top-bar" id="tg-df-top-bar" style="position: relative; z-index: 100; margin: 0 auto 20px;">        \x3Cdiv class="tg-df-search-wrapper">          \x3Cinput type="text" class="tg-df-search-input" placeholder="Search for deals, products, or brands...">          \x3Cbutton type="button" class="tg-df-search-btn" aria-label="Search">              \x3Csvg class="tg-df-search-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">                \x3Cpath d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>              \x3C/svg>          \x3C/button>          \x3Cdiv class="tg-df-autocomplete-dropdown" id="tg-df-autocomplete">\x3C/div>        \x3C/div>      \x3C/div>    \x3Cdiv class="tg-df-controls" id="tg-df-controls" style="display:flex;">              \x3Cdiv class="tg-df-filters-container" style="position: relative; width: 100%; max-width: 800px; margin: 0 auto;">          \x3Cbutton class="tg-df-scroll-btn left" style="display: none;" onclick="this.parentElement.querySelector('.tg-df-filters').scrollBy({left: -200, behavior: 'smooth'})">            \x3Csvg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\x3Cpath d="M15 18l-6-6 6-6"/>\x3C/svg>          \x3C/button>          \x3Cbutton class="tg-df-scroll-btn right" style="display: none;" onclick="this.parentElement.querySelector('.tg-df-filters').scrollBy({left: 200, behavior: 'smooth'})">            \x3Csvg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\x3Cpath d="M9 18l6-6-6-6"/>\x3C/svg>          \x3C/button>          \x3Cdiv class="tg-df-filters">          \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-category-filter-wrapper" style="display: none;">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-category-filter" aria-label="Category">            \x3Coption value="all">All Categories\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper tg-df-multiselect-container" id="tg-df-brand-filter-wrapper" style="display:none;">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M4.25 5.61C6.27 8.2 10 13 10 13v6c0 .55.45 1 1 1h2c.55 0 1-.45 1-1v-6s3.72-4.8 5.74-7.39A.998.998 0 0 0 18.95 4H5.04c-.83 0-1.3.95-.79 1.61z"/>          \x3C/svg>          \x3Cdiv class="tg-df-filter-select tg-df-multiselect-trigger" id="tg-df-brand-trigger" tabindex="0">            Any Brand          \x3C/div>          \x3Cdiv class="tg-df-multiselect-dropdown" id="tg-df-brand-dropdown">            \x3C!-- Populated via script --\x3E          \x3C/div>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper tg-df-price-range-wrapper" id="tg-df-custom-price-wrapper" style="display: flex; align-items:center; justify-content:center; padding: 10px 20px; gap: 8px; border: 1px solid var(--tg-df-border); border-radius: 100px; background-color: var(--tg-df-bg);">          \x3Cspan style="font-size:14px; font-weight:500; color:var(--tg-df-text-primary);">Price\x3C/span>          \x3Cinput type="number" class="tg-df-price-input" id="tg-df-custom-price-min" placeholder="Min" style="width: 48px; background: transparent; border: none; color: var(--tg-df-text-primary); outline: none; font-size: 14px; text-align: center; padding: 0;">          \x3Cspan style="color:var(--tg-df-text-muted)">-\x3C/span>          \x3Cinput type="number" class="tg-df-price-input" id="tg-df-custom-price-max" placeholder="Max" style="width: 48px; background: transparent; border: none; color: var(--tg-df-text-primary); outline: none; font-size: 14px; text-align: center; padding: 0;">        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-legacy-price-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-price-filter" aria-label="Filter Prices">            \x3Coption value="all">All Prices\x3C/option>            \x3Coption value="under50">Under $50\x3C/option>            \x3Coption value="50_100">$50 - $100\x3C/option>            \x3Coption value="100_200">$100 - $200\x3C/option>            \x3Coption value="200_500">$200 - $500\x3C/option>            \x3Coption value="over500">Over $500\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-discount-filter-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">            \x3Cpath d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-discount-filter" aria-label="Discount Amount">            \x3Coption value="all">Any discount\x3C/option>            \x3Coption value="5">Min 5%\x3C/option>            \x3Coption value="10">Min 10%\x3C/option>            \x3Coption value="15">Min 15%\x3C/option>            \x3Coption value="20">Min 20%\x3C/option>            \x3Coption value="25">Min 25%\x3C/option>            \x3Coption value="30">Min 30%\x3C/option>            \x3Coption value="40">Min 40%\x3C/option>            \x3Coption value="50">Min 50%\x3C/option>            \x3Coption value="60">Min 60%\x3C/option>            \x3Coption value="70">Min 70%\x3C/option>          \x3C/select>          \x3C/div>        \x3C/div>        \x3C/div>      \x3C/div>    \x3C!-- Deals Grid Wrapper --\x3E    \x3Cdiv class="tg-df-grid-wrapper tg-df-carousel-cards-wrapper" id="tg-df-grid-wrapper">      \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').scrollBy({left: -200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>      \x3Cdiv class="tg-df-grid" id="tg-df-grid">        \x3C!-- Content populated by JavaScript --\x3E      \x3C/div>      \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>    \x3C/div>        \x3C!-- Vouchers Modal --\x3E    \x3Cdiv class="tg-df-modal-backdrop" id="tg-df-vouchers-modal">      \x3Cdiv class="tg-df-modal">        \x3Cdiv class="tg-df-modal-header">          \x3Ch3 class="tg-df-modal-title" id="tg-df-vouchers-title">Available Coupons & Deals\x3C/h3>          \x3Cbutton class="tg-df-modal-close" id="tg-df-vouchers-close">            \x3Csvg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">              \x3Cline x1="18" y1="6" x2="6" y2="18">\x3C/line>              \x3Cline x1="6" y1="6" x2="18" y2="18">\x3C/line>            \x3C/svg>          \x3C/button>        \x3C/div>        \x3Cdiv class="tg-df-modal-body" id="tg-df-vouchers-content">          \x3C!-- Vouchers injected here --\x3E        \x3C/div>      \x3C/div>    \x3C/div>  \x3C/div>`;      if (!template) {        template = document.createElement('template');        template.innerHTML = rawTemplate;      }      let shadowRoot = null;      if (hostContainer && template) {        hostContainer.setAttribute('data-initialized', 'true');        shadowRoot = hostContainer.attachShadow({ mode: 'open' });        shadowRoot.appendChild(template.content.cloneNode(true));      }      class DealsFinderWidget {        constructor(config) {          this.rootNode = config.rootNode || document;          this.hostContainer = config.hostContainer || null;          this.rootId = config.rootId || 'signal-deals-finder-root';          this.root = this.rootNode.querySelector('#' + this.rootId);          if (!this.root) return;          this.widgetId = (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : 'widget-' + Date.now() + '-' + Math.random().toString(36).slice(2);          this.grid = this.root.querySelector('#tg-df-grid');          this.tagsContainer = this.root.querySelector('#tg-df-tags-container');          this.categoryFilter = this.root.querySelector('#tg-df-category-filter');          this.categoryFilterWrapper = this.root.querySelector('#tg-df-category-filter-wrapper');          this.searchInput = this.root.querySelector('.tg-df-search-input');          this.autocompleteDropdown = this.root.querySelector('#tg-df-autocomplete');          this.sortSelect = this.root.querySelector('.tg-df-sort-select');          this.searchBtn = this.root.querySelector('.tg-df-search-btn');                    this.settingsToggle = this.root.querySelector('#tg-df-settings-toggle');          this.settingsPanel = this.root.querySelector('#tg-df-settings-panel');          this.settingsBackdrop = this.root.querySelector('#tg-df-settings-backdrop');          this.regionSelect = this.root.querySelector('#tg-df-region-select');          this.retailerSelect = this.root.querySelector('#tg-df-retailer-select');          this.offerTypeSelect = this.root.querySelector('#tg-df-offer-type-select');          this.viewModeSelect = this.root.querySelector('#tg-df-view-mode-select');          this.rowsSelect = this.root.querySelector('#tg-df-rows-select');          this.dealModeToggle = this.root.querySelector('#tg-df-deal-mode');          this.editorModeToggle = this.root.querySelector('#tg-df-editor-mode');          this.priceFilter = this.root.querySelector('#tg-df-price-filter');          this.discountFilter = this.root.querySelector('#tg-df-discount-filter');                    this.editorBar = this.root.querySelector('#tg-df-editor-bar');          this.editorSelectedCount = this.root.querySelector('#tg-df-selected-count');          this.editorCopyBtn = this.root.querySelector('#tg-df-editor-copy');          this.editorClearBtn = this.root.querySelector('#tg-df-editor-clear');                    this.apiUrl = 'https://search-api.fie.future.net.uk/widget.php';          this.deals = [];          this.displayLimit = 12;          this.airedaleArticles = null;          this.airedaleTags = [];          this.airedaleTagCounts = {};          this.activeDealTag = null;          this.selectedBrands = [];          this.currentQuery = '';          this.editorMode = this.hostContainer ? this.hostContainer.hasAttribute('data-editor-mode') : false;          this.viewModeOverride = this.hostContainer ? this.hostContainer.getAttribute('data-view-mode') : null;          this.selectedDeals = new Map();                    this.brandFilterWrapper = this.root.querySelector('#tg-df-brand-filter-wrapper');          this.brandTrigger = this.root.querySelector('#tg-df-brand-trigger');          this.brandDropdown = this.root.querySelector('#tg-df-brand-dropdown');                    this.customPriceWrapper = this.root.querySelector('#tg-df-custom-price-wrapper');          this.customPriceMin = this.root.querySelector('#tg-df-custom-price-min');          this.customPriceMax = this.root.querySelector('#tg-df-custom-price-max');          this.legacyPriceWrapper = this.root.querySelector('#tg-df-legacy-price-wrapper');          this.discountFilterWrapper = this.root.querySelector('#tg-df-discount-filter-wrapper');          this.initResizeObserver();          this.init();        }        getViewMode() {          console.log("DEBUG getViewMode -> override:", this.viewModeOverride, "editorMode:", this.editorMode);          if (this.viewModeOverride && (!this.editorMode || !this.viewModeSelect)) {            return this.viewModeOverride;          }          return (this.viewModeSelect && this.viewModeSelect.value) ? this.viewModeSelect.value : (this.viewModeOverride || 'auto');        }        applyLayoutMode() {          if (!this.grid) return;          const mode = this.getViewMode();          console.log("[DEBUG] applyLayoutMode CALLED! mode=", mode);          this.grid.classList.remove('layout-row', 'layout-grid', 'tg-df-grid-auto', 'carousel-compact', 'layout-replica-1', 'layout-replica-2');                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          const showHeaderDetails = params.get('show_header_details') !== 'false';          const carouselHost = this.root.querySelector('#tg-df-carousel-host');          const controlsDiv = this.root.querySelector('#tg-df-controls');          const topBarDiv = this.root.querySelector('#tg-df-top-bar');          const headerElement = this.root.querySelector('#tg-df-savings-squad-header');          if (headerElement) {             headerElement.style.display = (mode === 'savings_squad' && showHeaderDetails) ? 'block' : 'none';          }          if (mode === 'carousel') {             this.grid.classList.add('carousel-compact');             if (carouselHost) carouselHost.style.display = 'block';             if (controlsDiv) controlsDiv.style.display = 'none';             if (topBarDiv) topBarDiv.style.display = 'none';             if (this.root.classList.contains('tg-df-container')) {               this.root.classList.add('is-carousel');             }          } else {             if (carouselHost) carouselHost.style.display = 'none';             if (controlsDiv) controlsDiv.style.display = 'flex';             if (topBarDiv) topBarDiv.style.display = 'block';             if (this.root.classList.contains('tg-df-container')) {               this.root.classList.remove('is-carousel');             }          }          if (mode === 'grid') {            this.grid.classList.add('layout-grid');          } else if (mode === 'row') {            this.grid.classList.add('layout-row');          } else if (mode === 'savings_squad') {            this.grid.classList.add('tg-df-grid-auto', 'savings-squad-cards');          } else if (mode !== 'carousel') {            this.grid.classList.add('tg-df-grid-auto');          }                    const settingsWrapper = this.root.querySelector('.tg-df-settings-wrapper');          if (settingsWrapper) {            settingsWrapper.style.display = mode === 'auto' ? 'none' : 'block';          }          if (this.customPriceWrapper) {             this.customPriceWrapper.style.display = mode === 'auto' ? 'flex' : 'none';          }          if (this.legacyPriceWrapper) {             this.legacyPriceWrapper.style.display = mode === 'auto' ? 'none' : 'flex';          }          if (this.discountFilterWrapper) {             this.discountFilterWrapper.style.display = mode === 'auto' ? 'none' : 'flex';          }        }        initResizeObserver() {          try {            if (window.parent === window) return;          } catch (e) {            // cross origin frame check threw          }          const emitHeight = () => {            try {              const height = document.documentElement.scrollHeight || document.body.scrollHeight;              const msg = { type: 'embed-size', height: height };              if (window.parent && window.parent !== window) {                window.parent.postMessage(msg, '*');                window.parent.postMessage(JSON.stringify({ ...msg, sentinel: 'amp' }), '*');              }            } catch (e) {}          };                    if (window.ResizeObserver) {            try {              const ro = new ResizeObserver(() => emitHeight());              ro.observe(document.body);              if (this.root) ro.observe(this.root);            } catch(e){ console.warn(e); }          }          window.addEventListener('resize', emitHeight);          setTimeout(emitHeight, 300);        }        initCountdown() {          this.cdWrapper = this.root.querySelector('#tg-df-countdown-wrapper');                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          this.showCountdown = params.get('show_countdown') === 'true';          const showHeaderDetails = params.get('show_header_details') !== 'false';          const eyebrow = this.root.querySelector('.tg-df-carousel-box-eyebrow');          const title = this.root.querySelector('.tg-df-carousel-box-title');          const subtitle = this.root.querySelector('.tg-df-carousel-box-subtitle');          if (!showHeaderDetails) {            let containerElement = this.root.classList.contains('tg-df-container') ? this.root : this.root.querySelector('.tg-df-container');            if (containerElement) containerElement.classList.add('hide-header-details');            if (eyebrow) eyebrow.style.display = 'none';            if (title) title.style.display = 'none';            if (subtitle) subtitle.style.display = 'none';          }          if (!this.cdWrapper) return;          this.cdTitle = this.root.querySelector('#tg-df-countdown-title');          this.cdDays = this.root.querySelector('#tg-df-cd-days');          this.cdHrs = this.root.querySelector('#tg-df-cd-hrs');          this.cdMin = this.root.querySelector('#tg-df-cd-min');          this.cdSec = this.root.querySelector('#tg-df-cd-sec');          this.updateCountdown();          this.cdInterval = setInterval(() => this.updateCountdown(), 1000);        }        updateCountdown() {          if (!this.cdWrapper) return;          if (!this.showCountdown) {            this.cdWrapper.style.display = 'none';            return;          }          const area = this.getAreaCode();          let offset = '-04:00';          if (['DE', 'FR', 'IT', 'ES', 'NL'].includes(area)) {             offset = '+02:00';          } else if (['GB', 'IE', 'UK'].includes(area)) {             offset = '+01:00';          }          const startTime = new Date('2026-06-23T00:00:00' + offset).getTime();          const endTime = new Date('2026-06-26T00:00:00' + offset).getTime();          const now = Date.now();          let targetTime = 0;          if (now < startTime) {             targetTime = startTime;             if (this.cdTitle) this.cdTitle.textContent = 'Prime Day starts in';             this.cdWrapper.style.display = 'flex';          } else if (now < endTime) {             targetTime = endTime;             if (this.cdTitle) this.cdTitle.textContent = 'Prime Day ends in';             this.cdWrapper.style.display = 'flex';          } else {             this.cdWrapper.style.display = 'none';             if (this.cdInterval) clearInterval(this.cdInterval);             return;          }          const diff = Math.max(0, targetTime - now);          const d = Math.floor(diff / (1000 * 60 * 60 * 24));          const h = Math.floor((diff / (1000 * 60 * 60)) % 24);          const m = Math.floor((diff / 1000 / 60) % 60);          const s = Math.floor((diff / 1000) % 60);          if (this.cdDays) this.cdDays.textContent = d;          if (this.cdHrs) this.cdHrs.textContent = h;          if (this.cdMin) this.cdMin.textContent = m;          if (this.cdSec) this.cdSec.textContent = s;        }        init() {          this.initCountdown();          try {            initAnalytics();          } catch (e) {            console.warn('Deals Widget Analytics Error:', e);          }                    this.bindEvents();                    let initialQuery = '';                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          let initialViewMode = params.get('view_mode');          if (!this.viewModeOverride && initialViewMode) {            this.viewModeOverride = initialViewMode;          }          if (!params.has('search') && !params.has('q') && !params.has('query') && initialViewMode !== 'savings_squad') {             initialQuery = 'Gaming laptops';          }          const website = params.get('website') || 'tomsguide';          this.website = website;          if (website === 'techradar') {            const squadHeader = this.root.querySelector('.tg-df-savings-squad-header');            if (squadHeader) {               const pic = squadHeader.querySelector('picture');               if (pic) pic.style.display = 'none';            }            const style = document.createElement('style');            style.innerHTML = `              .tg-df-container .hawk-affiliate-link-deal-button, .tg-df-container .tg-df-card-cta { background-color: #5DAF08 !important; }              .tg-df-container .hawk-affiliate-link-deal-button:hover, .tg-df-container .tg-df-card-cta:hover { background-color: #4a8c06 !important; }            `;            this.root.appendChild(style);          }                    if (this.regionSelect) {            this.regionSelect.value = params.get('region') || 'auto';            this.updatePriceDropdownCurrency();          }                    if (this.retailerSelect && params.has('retailer')) {            this.retailerSelect.value = params.get('retailer');          }                    if (params.has('brands')) {            const b = params.get('brands');            if (b) {              this.selectedBrands = b.split(',');            }          }                    if (this.offerTypeSelect && params.has('offer_type')) {            this.offerTypeSelect.value = params.get('offer_type');          }          if (this.viewModeSelect && params.has('view_mode')) {            this.viewModeSelect.value = params.get('view_mode');          }          if (this.rowsSelect && params.has('rows')) {            this.rowsSelect.value = params.get('rows');          }          if (params.has('price')) {            const priceVal = params.get('price');            if (this.priceFilter) {               // Try assigning it directly to select. If it's not present implicitly ignores               this.priceFilter.value = priceVal;            }            if (priceVal.includes('_')) {               const parts = priceVal.split('_');               if (this.customPriceMin && parts[0]) this.customPriceMin.value = parts[0];               if (this.customPriceMax && parts[1]) this.customPriceMax.value = parts[1];            }          }          if (this.discountFilter && params.has('min_discount_ratio')) {            // Need to convert back from ratio (e.g. 0.8) to select value (e.g. "20")            const ratioStr = params.get('min_discount_ratio');            const ratioFloat = parseFloat(ratioStr);            if (!isNaN(ratioFloat)) {               const percentage = Math.round((1 - ratioFloat) * 100);               this.discountFilter.value = percentage.toString();            }          }          if (this.sortSelect) {            this.sortSelect.value = params.get('sort') || 'date_desc';          }          if (this.dealModeToggle && params.has('deal_mode')) {            this.dealModeToggle.checked = params.get('deal_mode') === 'true' || params.get('deal_mode') === '1';          }          const headerTitleEl = this.root.querySelector('#tg-df-header-title');          const headerSubtitleEl = this.root.querySelector('#tg-df-header-subtitle');          if (params.has('widget_title') && headerTitleEl) {             headerTitleEl.textContent = params.get('widget_title');          }          if (params.has('widget_subtitle') && headerSubtitleEl) {             headerSubtitleEl.textContent = params.get('widget_subtitle');          }                    // Re-apply layout after params have updated control values          this.applyLayoutMode();                    if (params.get('search')) {            initialQuery = params.get('search');          } else if (params.get('q')) {            initialQuery = params.get('q');          } else if (params.get('query')) {            initialQuery = params.get('query');          }                    this.currentQuery = initialQuery;          if (this.searchInput) {            if (this.getViewMode() === 'savings_squad') {              this.searchInput.value = '';            } else {              this.searchInput.value = this.currentQuery;            }          }                    if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {            this.fetchDeals(this.currentQuery);          } else {            this.render();          }        }        updatePriceDropdownCurrency() {          if (!this.priceFilter || !this.regionSelect) return;          const currencySymbols = {            'US': '$',            'GB': '£',            'CA': '$CA',            'AU': '$AU',            'DE': '€',            'FR': '€',            'IT': '€',          };          const area = this.getAreaCode();          const cur = currencySymbols[area || 'US'] || '$';                    const options = this.priceFilter.options;          for (let i = 0; i < options.length; i++) {            const opt = options[i];            if (opt.value === 'all') {              opt.innerText = 'All Prices';            } else if (opt.value === 'under50') {              opt.innerText = `Under ${cur}50`;            } else if (opt.value === '50_100') {              opt.innerText = `${cur}50 - ${cur}100`;            } else if (opt.value === '100_200') {              opt.innerText = `${cur}100 - ${cur}200`;            } else if (opt.value === '200_500') {              opt.innerText = `${cur}200 - ${cur}500`;            } else if (opt.value === 'over500') {              opt.innerText = `Over ${cur}500`;            }          }        }        populateBrandDropdown(values) {          if (!this.brandDropdown || !this.brandFilterWrapper) return;          this.brandFilterWrapper.style.display = 'flex'; // show the wrapper                    let html = '';          const allChecked = this.selectedBrands.length === 0 ? 'checked' : '';          const _div = '<' + '/div>';          const _span = '<' + '/span>';          html += `\x3Cdiv class="tg-df-ms-option">\x3Cinput type="checkbox" value="" ${allChecked} class="tg-df-brand-chk"> Any Brand${_div}`;                    values.forEach(v => {             if (!v.formatted_value || v.formatted_value === 'Any Brand') return;             const isChecked = this.selectedBrands.includes(v.formatted_value) ? 'checked' : '';             html += `\x3Cdiv class="tg-df-ms-option">\x3Cinput type="checkbox" value="${this.escapeHTML(v.formatted_value)}" ${isChecked} class="tg-df-brand-chk"> ${this.escapeHTML(v.formatted_value)} \x3Cspan style="color:var(--tg-df-text-muted);font-size:12px">(${v.count || 0})${_span}${_div}`;          });                    this.brandDropdown.innerHTML = html;                    // Re-bind listeners          const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');          chks.forEach(chk => {            chk.addEventListener('change', (e) => {              const val = e.target.value;              if (val === '') {                this.selectedBrands = [];              } else {                if (e.target.checked) {                   if (!this.selectedBrands.includes(val)) this.selectedBrands.push(val);                } else {                   this.selectedBrands = this.selectedBrands.filter(b => b !== val);                }              }                            if (this.selectedBrands.length === 0) {                 this.brandTrigger.innerText = 'Any Brand';              } else if (this.selectedBrands.length === 1) {                 this.brandTrigger.innerText = this.selectedBrands[0];              } else {                 this.brandTrigger.innerText = `${this.selectedBrands.length} Brands selected`;              }                            // Only call API if changed from UI interactions              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                 this.updateURLParams();                 this.fetchDeals(this.currentQuery);              }            });          });                    // Update button text on load          if (this.selectedBrands.length === 0) {             this.brandTrigger.innerText = 'Any Brand';          } else if (this.selectedBrands.length === 1) {             this.brandTrigger.innerText = this.selectedBrands[0];          } else {             this.brandTrigger.innerText = `${this.selectedBrands.length} Brands selected`;          }        }        updateURLParams() {          const url = new URL(window.location);          if (this.currentQuery && this.currentQuery !== 'Gaming laptops') {            url.searchParams.set('q', this.currentQuery);          } else {            url.searchParams.delete('q');            url.searchParams.delete('search');            url.searchParams.delete('query');          }                    if (this.regionSelect && this.regionSelect.value !== 'auto') {            url.searchParams.set('region', this.regionSelect.value);          } else {            url.searchParams.delete('region');          }                    if (this.retailerSelect && this.retailerSelect.value) {            url.searchParams.set('retailer', this.retailerSelect.value);          } else {            url.searchParams.delete('retailer');          }                    if (this.selectedBrands && this.selectedBrands.length > 0) {            url.searchParams.set('brands', this.selectedBrands.join(','));          } else {            url.searchParams.delete('brands');          }                    if (this.offerTypeSelect && this.offerTypeSelect.value) {            url.searchParams.set('offer_type', this.offerTypeSelect.value);          } else {            url.searchParams.delete('offer_type');          }                    if (this.viewModeSelect && this.viewModeSelect.value !== 'auto') {            url.searchParams.set('view_mode', this.viewModeSelect.value);          } else {            url.searchParams.delete('view_mode');          }                    if (this.rowsSelect && this.rowsSelect.value !== '12') {            url.searchParams.set('rows', this.rowsSelect.value);          } else {            url.searchParams.delete('rows');          }                    const min = this.customPriceMin ? this.customPriceMin.value : '';          const max = this.customPriceMax ? this.customPriceMax.value : '';          if (min || max) {             url.searchParams.set('price', `${min}_${max}`);          } else if (this.priceFilter && this.priceFilter.value !== 'all') {            url.searchParams.set('price', this.priceFilter.value);          } else {            url.searchParams.delete('price');          }                    if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {            const v = parseInt(this.discountFilter.value);            if (!isNaN(v) && v > 0) {               const ratio = (100 - v) / 100;               url.searchParams.set('min_discount_ratio', ratio.toString());            }          } else {            url.searchParams.delete('min_discount_ratio');          }                    if (this.sortSelect && this.sortSelect.value !== 'date_desc') {            url.searchParams.set('sort', this.sortSelect.value);          } else {            url.searchParams.delete('sort');          }                    if (this.dealModeToggle && this.dealModeToggle.checked) {            url.searchParams.set('deal_mode', 'true');          } else {            url.searchParams.delete('deal_mode');          }                    window.history.replaceState({}, '', url);        }        bindEvents() {          const handleFiltersScroll = () => {            const filters = this.root.querySelector('.tg-df-filters');            const leftBtn = this.root.querySelector('.tg-df-scroll-btn.left');            const rightBtn = this.root.querySelector('.tg-df-scroll-btn.right');            if (filters && leftBtn && rightBtn) {              const { scrollLeft, scrollWidth, clientWidth } = filters;              leftBtn.style.display = scrollLeft > 0 ? 'flex' : 'none';              rightBtn.style.display = Math.ceil(scrollLeft + clientWidth) < scrollWidth - 5 ? 'flex' : 'none';            }          };          const filters = this.root.querySelector('.tg-df-filters');          if (filters) {            filters.addEventListener('scroll', handleFiltersScroll);            window.addEventListener('resize', handleFiltersScroll);            setTimeout(handleFiltersScroll, 100);                        // Also call after rendering dropdowns            const origRenderCategories = this.renderCategories;            if (origRenderCategories) {               this.renderCategories = (...args) => {                 origRenderCategories.apply(this, args);                 setTimeout(handleFiltersScroll, 50);               };            }          }                const roundels = this.root.querySelectorAll('.tg-df-carousel-cat');          roundels.forEach(r => {             r.addEventListener('click', () => {                const q = r.getAttribute('data-query');                const pr = r.getAttribute('data-pr');                if (typeof trackHawkEvent !== 'undefined') {                     trackHawkEvent({                         clickType: "CC",                         widgetId: this.widgetId,                         productCategoryName: "deals",                         zeroBasedProductIndexOrNull: null,                         totalDealsOrProducts: null,                         areaClicked: "Category Roundel",                         revenueId: this.revenueId,                         isoCurrencyCode: typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD',                         queryName: q,                         widgetTypeName: this.widgetTypeName                     });                 }                this.currentQuery = q;                const label = this.root.querySelector('#tg-df-carousel-title-label');                if (label) label.textContent = 'Best ' + q;                if (this.priceFilter) this.priceFilter.value = pr || 'all';                if (this.discountFilter) this.discountFilter.value = '5';                if (this.searchInput) this.searchInput.value = q;                                roundels.forEach(ro => ro.classList.remove('active'));                r.classList.add('active');                this.fetchDeals(this.currentQuery);             });          });          const discBtns = this.root.querySelectorAll('.tg-df-carousel-filter-btn');          discBtns.forEach(b => {             b.addEventListener('click', () => {                const d = b.getAttribute('data-d');                const pr = b.getAttribute('data-pr');                const ot = b.getAttribute('data-ot');                let label = b.innerText ? b.innerText.trim() : '';                let filterType = 'unknown';                let filterVal = 'unknown';                if (d !== null) { filterType = 'discount'; filterVal = d; }                else if (pr !== null) { filterType = 'price'; filterVal = pr; }                else if (ot !== null) { filterType = 'offertype'; filterVal = ot; }                if (typeof trackElementInteraction === 'function') trackElementInteraction({ id: `filter-${filterType}-${filterVal}`, name: 'Filter Button', label: label });                                if (d !== null) {                   if (this.discountFilter) this.discountFilter.value = this.discountFilter.value === d ? '0' : d;                } else if (pr !== null) {                   if (this.priceFilter) this.priceFilter.value = this.priceFilter.value === pr ? 'all' : pr;                } else if (ot !== null) {                   if (this.offerTypeSelect) this.offerTypeSelect.value = this.offerTypeSelect.value === ot ? 'all' : ot;                } else {                   if (this.discountFilter) this.discountFilter.value = '0';                   if (this.priceFilter) this.priceFilter.value = 'all';                   if (this.offerTypeSelect) this.offerTypeSelect.value = 'all';                }                if (d === null && pr === null && ot === null && b.getAttribute("data-type") !== "custom") {                   discBtns.forEach(ro => ro.classList.remove('active'));                   b.classList.add('active');                } else if (b.getAttribute("data-type") !== "custom") {                   // Only operate on hardcoded buttons (those without data-type)                   discBtns.forEach(ro => {                      if (!ro.getAttribute('data-d') && !ro.getAttribute('data-pr') && !ro.getAttribute('data-ot') && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active');                   });                                      let makeActive = true;                   if (d !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-d') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   } else if (pr !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-pr') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   } else if (ot !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-ot') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   }                                      if (makeActive) b.classList.add('active');                                      // Check if anything is active, if not activate "All"                   let anyActive = false;                   discBtns.forEach(ro => { if (ro.classList.contains('active') && ro.getAttribute('data-type') !== 'custom') anyActive = true; });                   if (!anyActive) {                       discBtns.forEach(ro => { if (!ro.getAttribute('data-d') && !ro.getAttribute('data-pr') && !ro.getAttribute('data-ot') && ro.getAttribute('data-type') !== 'custom') ro.classList.add('active'); });                   }                }                                this.fetchDeals(this.currentQuery);             });          });          if (this.brandTrigger && this.brandDropdown) {            this.brandTrigger.addEventListener('click', () => {              this.brandDropdown.classList.toggle('active');            });            document.addEventListener('click', (e) => {              if (this.brandFilterWrapper && !e.composedPath().includes(this.brandFilterWrapper)) {                this.brandDropdown.classList.remove('active');              }            });          }          const showAutocomplete = () => {             if (this.getViewMode() !== 'savings_squad' || !this.autocompleteDropdown || !this.airedaleTags) return;                          let terms = this.airedaleTags;             if (this.airedaleBrands) {                terms = terms.concat(this.airedaleBrands.map(b => b.formatted_value));             }             terms = [...new Set(terms)];                          const query = this.searchInput.value.trim();             let matches = [];             if (query.length > 0) {                 matches = terms.filter(t => t.toLowerCase().includes(query.toLowerCase()) && t.toLowerCase() !== query.toLowerCase());             } else {                 matches = terms;             }                          if (matches.length > 0) {                 this.autocompleteDropdown.innerHTML = matches.map(m => `\x3Cdiv class="tg-df-autocomplete-item" data-tag="${this.escapeHTML(m)}">${this.escapeHTML(m)}<` + `/div>`).join('');                 this.autocompleteDropdown.classList.add('active');             } else {                 this.autocompleteDropdown.classList.remove('active');             }          };          let debounceTimer;          if(this.searchInput) {            this.searchInput.addEventListener('focus', showAutocomplete);            this.searchInput.addEventListener('input', (e) => {              clearTimeout(debounceTimer);              const query = e.target.value.trim();              this.currentQuery = query;              showAutocomplete();              debounceTimer = setTimeout(() => {                this.updateURLParams();                if (query.length > 2) {                  this.fetchDeals(query);                } else if (query.length === 0) {                  if (this.getViewMode() === 'savings_squad') {                    this.activeDealTag = null;                    this.currentQuery = '';                    if (this.categoryFilter) this.categoryFilter.value = 'all';                    this.fetchDeals('');                  } else {                    this.deals = [];                    this.render();                  }                }              }, 400);            });            this.searchInput.addEventListener('keypress', (e) => {              if (e.key === 'Enter') {                if (this.autocompleteDropdown) this.autocompleteDropdown.classList.remove('active');                clearTimeout(debounceTimer);                const query = e.target.value.trim();                this.currentQuery = query;                                let isTag = false;                if (this.airedaleTags && this.airedaleTags.includes(query)) isTag = true;                if (this.airedaleBrands && this.airedaleBrands.some(b => b.formatted_value === query)) isTag = true;                this.activeDealTag = isTag ? query : null;                                trackElementInteraction({ id: 'search-submit', name: 'Ask', label: 'Ask (main search)', text: query });                this.updateURLParams();                if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                   if (query.length === 0 && this.getViewMode() === 'savings_squad') {                       if (this.categoryFilter) this.categoryFilter.value = 'all';                   }                   this.fetchDeals(query);                }              }            });          }          if (this.autocompleteDropdown) {             this.autocompleteDropdown.addEventListener('click', (e) => {                const item = e.target.closest('.tg-df-autocomplete-item');                if (item) {                   const tag = item.getAttribute('data-tag');                   this.currentQuery = tag;                   if (this.searchInput) this.searchInput.value = tag;                   this.activeDealTag = tag;                   if (this.categoryFilter && this.airedaleTags.includes(tag)) {                       this.categoryFilter.value = tag;                   }                   this.autocompleteDropdown.classList.remove('active');                   this.updateURLParams();                   this.fetchDeals(tag);                }             });             document.addEventListener('click', (e) => {               if (this.autocompleteDropdown && this.searchInput && !e.composedPath().includes(this.searchInput) && !e.composedPath().includes(this.autocompleteDropdown)) {                 this.autocompleteDropdown.classList.remove('active');               }             });          }          if (this.searchBtn) {            this.searchBtn.addEventListener('click', () => {              if (this.autocompleteDropdown) this.autocompleteDropdown.classList.remove('active');              clearTimeout(debounceTimer);              const query = this.searchInput.value.trim();              trackElementInteraction({ id: 'search-submit', name: 'Ask', label: 'Ask (main search)', text: query });                            let isTag = false;              if (this.airedaleTags && this.airedaleTags.includes(query)) isTag = true;              if (this.airedaleBrands && this.airedaleBrands.some(b => b.formatted_value === query)) isTag = true;              this.activeDealTag = isTag ? query : null;                            this.currentQuery = query;              this.updateURLParams();              if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                 if (query.length === 0 && this.getViewMode() === 'savings_squad') {                     if (this.categoryFilter) this.categoryFilter.value = 'all';                 }                 this.fetchDeals(query);              }            });          }          if(this.sortSelect && this.sortSelect.querySelector('option[value="date_desc"]') === null) {              const option = document.createElement('option');              option.value = "date_desc";              option.text = "Newest First";              this.sortSelect.insertBefore(option, this.sortSelect.firstChild);          }          if(this.sortSelect) this.sortSelect.addEventListener('change', () => {            trackElementInteraction({ id: `sort-option-${this.sortSelect.value}`, name: 'Sort', label: `Sort: ${this.sortSelect.options[this.sortSelect.selectedIndex].text}` });            this.updateURLParams();            if (this.deals.length > 0) {              this.sortData();              this.render();            }          });                    const priceFilter = this.root.querySelector('#tg-df-price-filter');          if (priceFilter) {            this.priceFilter = priceFilter;            this.priceFilter.addEventListener('change', () => {              trackElementInteraction({ id: `filter-price-${this.priceFilter.value}`, name: 'Price', label: this.priceFilter.options[this.priceFilter.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }            });          }          const updateCustomPrice = () => {             this.updateURLParams();             if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);             } else {                this.render();             }          };          if (this.customPriceMin) {             this.customPriceMin.addEventListener('change', updateCustomPrice);             this.customPriceMin.addEventListener('keypress', (e) => {                if (e.key === 'Enter') updateCustomPrice();             });          }          if (this.customPriceMax) {             this.customPriceMax.addEventListener('change', updateCustomPrice);             this.customPriceMax.addEventListener('keypress', (e) => {                if (e.key === 'Enter') updateCustomPrice();             });          }          const discountFilter = this.root.querySelector('#tg-df-discount-filter');          if (discountFilter) {            this.discountFilter = discountFilter;            this.discountFilter.addEventListener('change', () => {              trackElementInteraction({ id: `filter-discount-${this.discountFilter.value}`, name: 'Discount', label: this.discountFilter.options[this.discountFilter.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }            });          }          if (this.categoryFilter) {            this.categoryFilter.addEventListener('change', (e) => {               const val = e.target.value === 'all' ? null : e.target.value;               this.activeDealTag = val;               if (val) {                 this.currentQuery = val;               } else {                 if (this.searchInput && this.currentQuery === document.querySelector('#tg-df-brand-trigger')?.getAttribute('data-active-brand')) {                     // don't clear current query if a brand is selected                 } else if (this.searchInput) {                     this.currentQuery = '';                     this.searchInput.value = '';                 }               }               this.fetchSavingsSquad();            });          }                    if (this.settingsToggle) {            this.settingsToggle.addEventListener('click', () => {              const o = this.settingsPanel.classList.toggle('active');              this.settingsBackdrop.classList.toggle('active');              if (o) trackElementInteraction({ id: 'filter-open', name: 'Filters', label: 'Open filters' });            });          }                    if (this.settingsBackdrop) {            this.settingsBackdrop.addEventListener('click', () => {              this.settingsPanel.classList.remove('active');              this.settingsBackdrop.classList.remove('active');            });          }                    if (this.regionSelect) {            this.regionSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-region-${this.regionSelect.value}`, name: 'Region', label: this.regionSelect.options[this.regionSelect.selectedIndex].text });              this.updateURLParams();              this.updatePriceDropdownCurrency();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.retailerSelect) {            this.retailerSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-merchant-${this.retailerSelect.value}`, name: 'Retailer', label: this.retailerSelect.options[this.retailerSelect.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.offerTypeSelect) {            this.offerTypeSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-offertype-${this.offerTypeSelect.value}`, name: 'Offer Type', label: this.offerTypeSelect.options[this.offerTypeSelect.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.viewModeSelect) {            this._prevViewMode = this.viewModeSelect.value;            this.viewModeSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-viewmode-${this.viewModeSelect.value}`, name: 'View Mode', label: this.viewModeSelect.options[this.viewModeSelect.selectedIndex].text });                            // Reset all active toggles and filters to prevent config carry-over              this.selectedBrands = [];              if (this.brandTrigger) this.brandTrigger.innerText = 'Select Brands';              if (this.brandDropdown) {                const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                chks.forEach(chk => { chk.checked = false; });              }              if (this.priceFilter) this.priceFilter.value = 'all';              if (this.customPriceMin) this.customPriceMin.value = '';              if (this.customPriceMax) this.customPriceMax.value = '';              if (this.sortSelect) this.sortSelect.value = 'date_desc';              if (this.discountFilter) this.discountFilter.value = '0';              if (this.retailerSelect) this.retailerSelect.value = '';              if (this.offerTypeSelect) this.offerTypeSelect.value = '';              if (this.rowsSelect) this.rowsSelect.value = '12';              if (this.categoryFilter) this.categoryFilter.value = 'all';              this.activeDealTag = null;              this.updateURLParams();              this.applyLayoutMode();                            if (this.getViewMode() === 'savings_squad' || this._prevViewMode === 'savings_squad') {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }              this._prevViewMode = this.viewModeSelect.value;            });          }                    if (this.rowsSelect) {            this.rowsSelect.addEventListener('change', () => {              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.dealModeToggle) {            this.dealModeToggle.addEventListener('change', () => {              this.updateURLParams();              this.render();            });          }          if (this.editorModeToggle) {             this.editorModeToggle.addEventListener('change', (e) => {                this.editorMode = e.target.checked;                this.render();                this.updateFloatingCopyBar();             });          }          if (this.editorCopyBtn) {             this.editorCopyBtn.addEventListener('click', () => {                this.copySelectedDealsToCMS();             });          }          if (this.editorClearBtn) {             this.editorClearBtn.addEventListener('click', () => {                this.selectedDeals.clear();                this.render();                this.updateFloatingCopyBar();             });          }          if (this.grid) {            this.grid.addEventListener('change', (e) => {               if (e.target.classList.contains('tg-df-deal-checkbox')) {                  const dealId = e.target.getAttribute('data-id');                  if (e.target.checked) {                     const dealObj = this.deals.find(d => d.id === dealId);                     if (dealObj) this.selectedDeals.set(dealId, dealObj);                  } else {                     this.selectedDeals.delete(dealId);                  }                  this.updateFloatingCopyBar();               }            });            this.grid.addEventListener('click', (e) => {              const dealCard = e.target.closest('[data-action="deal-click"]');              const similarCard = e.target.closest('[data-action="view-similar-click"]');              const cardLink = dealCard || similarCard;              if (cardLink) {                const productName = cardLink.getAttribute('data-product-name');                const merchantName = cardLink.getAttribute('data-merchant-name');                const productId = cardLink.getAttribute('data-analytics-id');                const price = parseFloat(cardLink.getAttribute('data-price')) || null;                const prevPriceStr = cardLink.getAttribute('data-previous-price');                const previousPrice = prevPriceStr ? parseFloat(prevPriceStr) : null;                const originalLink = cardLink.getAttribute('data-original-link');                const rewrittenLink = cardLink.getAttribute('href');                const revenueId = cardLink.getAttribute('data-revenue-id');                const index = parseInt(cardLink.getAttribute('data-index'), 10) || 0;                const inStock = cardLink.getAttribute('data-in-stock') === 'true';                const totalText = cardLink.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: cardLink.getAttribute('data-model-id') || null,                    matchId: cardLink.getAttribute('data-match-id') || null,                    brand: cardLink.getAttribute('data-model-brand') || null,                    parent: cardLink.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: cardLink.getAttribute('data-merchant-id') || null,                    network: cardLink.getAttribute('data-merchant-network') || null,                    url: cardLink.getAttribute('data-merchant-url') || null,                    name: merchantName                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: normalizeCurrency(this.escapeHTML(cardLink.getAttribute('data-currency') || '$'))                };                if (dealCard) {                  trackDealClick(trackingParams);                } else {                  trackViewSimilarClick(trackingParams);                }              }              const couponsBtn = e.target.closest('[data-action="coupons-click"]');              if (couponsBtn) {                trackElementInteraction({                  id: 'product-card-show-coupons',                  name: 'Coupons',                  label: `Product card coupons: ${couponsBtn.getAttribute('data-merchant')}`                });              }            });          }          this.setupScrollListeners();        }        setupScrollListeners() {          const containers = [             this.root.querySelector('.tg-df-carousel-roundels'),             this.root.querySelector('.tg-df-carousel-filters-wrap'),             this.root.querySelector('#tg-df-grid')          ];                    containers.forEach(container => {             if (!container) return;                          const checkScroll = () => {                if (!container.parentElement) return;                const leftBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-left');                const rightBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-right');                                if (leftBtn) {                   if (container.scrollLeft <= 5) leftBtn.style.display = 'none';                   else leftBtn.style.display = 'flex';                }                                if (rightBtn) {                   if (container.scrollWidth <= container.clientWidth) {                       rightBtn.style.display = 'none';                   } else if (container.scrollLeft >= container.scrollWidth - container.clientWidth - 5) {                       rightBtn.style.display = 'none';                   } else {                       rightBtn.style.display = 'flex';                   }                }             };                          container.addEventListener('scroll', checkScroll);             checkScroll();                          window.addEventListener('resize', checkScroll);                          const observer = new MutationObserver(checkScroll);             observer.observe(container, { childList: true, subtree: true, characterData: false });          });        }        get widgetTypeName() {          const mode = this.viewModeSelect ? this.viewModeSelect.value : (this.viewModeOverride || 'auto');          switch(mode) {              case 'carousel': return 'Carousel';              case 'savings_squad': return 'Savings Squad';              case 'grid': return 'Grid';              case 'row': return 'Row';              default: return 'Auto Collection';          }        }        getRowsLimit() {          if (this.rowsSelect && this.rowsSelect.value) return parseInt(this.rowsSelect.value, 10);          let configSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {             configSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {             configSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(configSource);          if (params.has('rows')) return parseInt(params.get('rows'), 10) || 12;          return 12;        }        getAreaCode() {          if (this.regionSelect && this.regionSelect.value) {            if (this.regionSelect.value === 'auto') return null;            return this.regionSelect.value;          }          let area = null;          try {            const locale = window.navigator.language || window.navigator.userLanguage;            if (locale && locale.includes('-')) {              area = locale.split('-')[1].toUpperCase();            } else if (locale && locale.length === 2) {              if (locale.toUpperCase() === 'EN') { area = 'US'; }              else { area = locale.toUpperCase(); }            }          } catch (e) { /* Ignore */ }                    // Map to known valid options or fallback to US          const valid = ['US', 'GB', 'CA', 'AU', 'DE', 'FR', 'IT'];          if (area === 'UK') area = 'GB';          if (valid.includes(area)) {             return area;          }          return 'US';        }        async fetchDeals(query) {          this.showLoading();          this.deals = [];          this.displayLimit = this.getRowsLimit();                    try {            console.log("getViewMode returns:", this.getViewMode());            if (this.getViewMode() === 'savings_squad') {               await this.fetchSavingsSquad();            } else {               if (this.isBroadQuery(query)) {                 await this.fetchAdviserDeals(query);               } else {                 await this.fetchHawkDeals(query);                 if (this.deals.length === 0) {                   await this.fetchAdviserDeals(query);                 }               }            }          } catch (error) {            console.warn("[Tom's Guide Widget] Fetch error:", error);            this.showError();          }        }        async fetchSavingsSquad() {          let topArticles = this.airedaleArticles;          if (!topArticles) {            const siteParam = this.website || 'tomsguide';            const airedaleUrl = `https://airedale.futurecdn.net/feeds/feed_1781000519267.json?site=${siteParam}&articleType=deals&limit=50`;            let res;            try {               res = await fetch(airedaleUrl);            } catch(e) {               try { res = await fetch(`https://airedale.futurecdn.net/feeds/feed_1776420579726.json?site=${siteParam}&articleType=deals&limit=50`); } catch (err) { console.warn("Fallback fetch failed", err); return; }            }            if (!res.ok) throw new Error('Airedale API Error');            const articles = await res.json();            topArticles = Array.isArray(articles) ? articles.slice(0, 50) : ((articles.data && Array.isArray(articles.data)) ? articles.data.slice(0, 50) : []);            this.airedaleArticles = topArticles;                        let tagCounts = {};            topArticles.forEach((a) => {              let articleTags = new Set();              if (a.articlecategory && Array.isArray(a.articlecategory)) {                 a.articlecategory.forEach((t) => articleTags.add(t));              }              articleTags.forEach(t => {                 tagCounts[t] = (tagCounts[t] || 0) + 1;              });            });                        this.airedaleTags = Object.keys(tagCounts).sort((a, b) => tagCounts[b] - tagCounts[a]);            this.airedaleTagCounts = tagCounts;          }                    let targetArticles = topArticles;          if (!this.activeDealTag && this.currentQuery) {             const tagMatch = this.airedaleTags.find(t => t.toLowerCase() === this.currentQuery.toLowerCase());             if (tagMatch) {                this.activeDealTag = tagMatch;             }          }          if (this.activeDealTag) {             const cleanTag = this.activeDealTag.toLowerCase().replace(/&/g, '').replace(/[^a-z0-9]+/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');             const encodedTag = encodeURIComponent(cleanTag);             const siteParam = this.website || 'tomsguide';             const url = `https://airedale.futurecdn.net/feeds/feed_1781000519267.json?site=${siteParam}&articleType=deals&limit=50&articleCategoryHandle=${encodedTag}`;             try {                const res = await fetch(url);                if (res.ok) {                   const articles = await res.json();                   targetArticles = Array.isArray(articles) ? articles.slice(0, 50) : ((articles.data && Array.isArray(articles.data)) ? articles.data.slice(0, 50) : []);                }             } catch(e) {                console.warn("Failed to fetch by activeDealTag", e);             }          }          let extractedDeals = [];          let seenUrls = new Set();                    let overallBrandsCounts = {};                    // First pass: extract ALL brands from topArticles so the dropdown has all options          topArticles.forEach((article) => {             if (!article.articlepage) return;             let pageData = [];             try { pageData = JSON.parse(article.articlepage[0]); } catch(e){ console.warn(e); }             const savingsSquad = pageData.filter((p) => p.type === 'deal' || p.type === 'featured-product');             savingsSquad.forEach((block) => {                const data = block.data || {};                if (data.brand) {                   const cleanBrand = data.brand.replace(/^\d+\.\s*/, '').trim();                   overallBrandsCounts[cleanBrand] = (overallBrandsCounts[cleanBrand] || 0) + 1;                }             });          });          targetArticles.forEach((article) => {             if (!article.articlepage) return;                          let pageData = [];             try {                pageData = JSON.parse(article.articlepage[0]);             } catch(e){ console.warn(e); }                          const savingsSquad = pageData.filter((p) => p.type === 'deal' || p.type === 'featured-product');                          savingsSquad.forEach((block, idx) => {                const data = block.data || {};                const isFeatured = block.type === 'featured-product';                                const link = data.link || {};                const priceObj = data.price || {};                const image = data.image || {};                                if (data.brand) {                   data.brand = data.brand.replace(/^\d+\.\s*/, '').trim();                }                const externalUrl = isFeatured ? data.url : (link.href || null);                let summaryTitle = isFeatured ? (data.name || data.brand) : (data.productName || link.label || article.articlename);                let description = isFeatured ? (data.strapline || '') : (data.text || '');                                if (!isFeatured && !data.productName && data.text) {                   const brSplit = data.text.split(new RegExp('\x3Cbr\\s*\\/?\\x3E', 'i'));                   if (brSplit.length > 1) {                     summaryTitle = brSplit[0].replace(/<[^>]+>/g, '').trim();                     description = brSplit.slice(1).join(' ').replace(/<br\s*\/?>/gi, ' ').replace(/<\/?(p|div)[^>]*>/gi, ' ').replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').trim();                   } else {                     const match = data.text.match(/\x3Cstrong>(.*?)<\/strong>/);                     if (match) {                       summaryTitle = match[1].replace(/<[^>]+>/g, '').trim();                       if (summaryTitle.endsWith(':')) summaryTitle = summaryTitle.slice(0, -1);                     }                   }                }                                let imageUrl = isFeatured ? image.mos : (image.src || null);                if (imageUrl && imageUrl.startsWith('//')) imageUrl = 'https:' + imageUrl;                                description = description.replace(/<br\s*\/?>/gi, ' ').replace(/<\/?(p|div)[^>]*>/gi, ' ').replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').replace(/View Deal$/i, '').trim();                                let merchantName = data.retailer || '';                if (!merchantName && externalUrl) {                   try {                     merchantName = new URL(externalUrl).hostname.replace('www.', '').split('.')[0];                     merchantName = merchantName.charAt(0).toUpperCase() + merchantName.slice(1);                   }catch(e){ console.warn(e); }                }                if (!merchantName) merchantName = 'Retailer';                const q = (this.currentQuery || '').toLowerCase();                const activeTagLogic = (this.activeDealTag || '').toLowerCase();                if (q.length > 2 && q !== activeTagLogic) {                   const searchTarget = `${summaryTitle || ''} ${description || ''}`.toLowerCase();                   if (!searchTarget.includes(q)) return;                }                let rawPrice = 0;                let rawMsrp = 0;                let currencyStr = '$';                if (isFeatured) {                   rawPrice = typeof data.salePrice === 'number' && data.salePrice > 0 ? data.salePrice : (typeof data.price === 'number' ? data.price : 0);                   rawMsrp = typeof data.salePrice === 'number' && typeof data.price === 'number' && data.price > data.salePrice ? data.price : 0;                   currencyStr = data.currency === 'GBP' ? '£' : '$';                } else {                   rawPrice = priceObj.amount ? parseFloat(priceObj.amount) : 0;                   rawMsrp = priceObj.amountWas ? parseFloat(priceObj.amountWas) : 0;                   currencyStr = priceObj.currency === 'GBP' ? '£' : '$';                }                                let savingAmt = 0;                let savingLabel = '';                if (rawPrice > 0 && rawMsrp > rawPrice) {                   savingAmt = parseFloat((rawMsrp - rawPrice).toFixed(2));                   savingLabel = `Save ${currencyStr}${savingAmt}`;                }                                // Apply Brand filter                if (this.selectedBrands && this.selectedBrands.length > 0) {                   const itemBrand = (data.brand || '').toLowerCase();                   const hasMatch = this.selectedBrands.some(sb => sb.toLowerCase() === itemBrand);                   if (!hasMatch) return;                }                // Apply Price filter                let priceFilterVal = null;                const min = this.customPriceMin ? this.customPriceMin.value : '';                const max = this.customPriceMax ? this.customPriceMax.value : '';                if (min || max) {                   priceFilterVal = `${min}_${max}`;                } else if (this.priceFilter && this.priceFilter.value !== 'all') {                   priceFilterVal = this.priceFilter.value;                }                if (priceFilterVal && rawPrice > 0) {                   if (priceFilterVal === 'under50' && rawPrice >= 50) return;                   if (priceFilterVal === 'over50' && rawPrice <= 50) return;                   if (priceFilterVal === 'over30' && rawPrice <= 30) return;                   if (priceFilterVal === 'over500' && rawPrice <= 500) return;                   if (priceFilterVal.includes('_')) {                      const parts = priceFilterVal.split('_');                      const min = parseFloat(parts[0]);                      const max = parseFloat(parts[1]);                      if (!isNaN(min) && rawPrice < min) return;                      if (!isNaN(max) && rawPrice > max) return;                   }                }                // Apply Discount filter                if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {                   const requiredDiscount = parseInt(this.discountFilter.value);                   if (!isNaN(requiredDiscount) && requiredDiscount > 0) {                      if (!rawMsrp || rawMsrp <= rawPrice) return;                      const ratio = Math.round((1 - (rawPrice / rawMsrp)) * 100);                      if (ratio < requiredDiscount) return;                   }                }                                if (externalUrl) {                   if (seenUrls.has(externalUrl)) return;                  seenUrls.add(externalUrl);                }                                extractedDeals.push({                   id: `airedale-${article.id || Math.random()}-${idx}`,                   url: externalUrl,                   image: imageUrl,                   fallbackImage: imageUrl,                   title: summaryTitle,                   brand: data.brand || '',                   productName: data.productName || '',                   merchant: merchantName,                   rawPrice: rawPrice,                   rawMsrp: rawMsrp,                   price: rawPrice > 0 ? rawPrice.toString() : '',                   msrp: rawMsrp > 0 ? rawMsrp.toString() : '',                   currency: currencyStr,                   isCheckPrice: !rawPrice,                   savingLabel: savingLabel,                   savingType: rawMsrp > rawPrice ? 'amount' : 'none',                   isPrime: false,                   starRating: null,                   description: description,                   text: data.text || '',                   authorName: article.articleauthortext ? article.articleauthortext[0] : (article.articleauthor ? article.articleauthor[0] : ''),                   authorRole: article.articleauthorrole ? article.articleauthorrole[0] : '',                   authorImage: article.articleauthormedia ? article.articleauthormedia[0] : '',                   documentUrl: article.documenturl ? article.documenturl[0] : '',                   modifiedDate: article.contentmodifieddate || article.modifieddate || ''                });             });          });                    const airedaleBrandsList = Object.keys(overallBrandsCounts).map(b => ({              formatted_value: b,              count: overallBrandsCounts[b]          })).sort((a,b) => b.count - a.count);                    if (this.getViewMode() === 'savings_squad') {             this.populateBrandDropdown(airedaleBrandsList.slice(0, 15));             if (this.brandFilterWrapper) {                if (airedaleBrandsList.length === 0) {                    this.brandFilterWrapper.style.display = 'none';                } else {                    this.brandFilterWrapper.style.display = 'flex';                }             }          }                    this.deals = extractedDeals;          this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        isBroadQuery(query) {          const q = query.toLowerCase();          const intentModifiers = ['deals', 'best', 'sale', 'under', 'cheap', 'offers', 'discount'];          return intentModifiers.some(term => q.includes(term));        }        async fetchHawkDeals(query) {          const url = new URL(this.apiUrl);          url.searchParams.append('model_name', query);          const areaCode = this.getAreaCode();          if (areaCode) {            url.searchParams.append('area', areaCode);          }                    if (this.retailerSelect && this.retailerSelect.value) {            url.searchParams.append('filter_merchant_name', this.retailerSelect.value);          }                    if (this.selectedBrands && this.selectedBrands.length > 0) {            url.searchParams.append('filter_label[text_brand]', this.selectedBrands.join(','));          }                    let priceVal = null;          const min = this.customPriceMin ? this.customPriceMin.value : '';          const max = this.customPriceMax ? this.customPriceMax.value : '';          if (min || max) {             priceVal = `${min}_${max}`;          } else if (this.priceFilter && this.priceFilter.value !== 'all') {             priceVal = this.priceFilter.value;          }          if (priceVal) {            if (priceVal === 'under50') {              url.searchParams.append('filter_max_price', '50');            } else if (priceVal === 'over50') {              url.searchParams.append('filter_min_price', '50');            } else if (priceVal === 'over30') {              url.searchParams.append('filter_min_price', '30');            } else if (priceVal === 'over500') {              url.searchParams.append('filter_min_price', '500');            } else if (priceVal.includes('_')) {              const parts = priceVal.split('_');              if (parts[0]) url.searchParams.append('filter_min_price', parts[0]);              if (parts[1]) url.searchParams.append('filter_max_price', parts[1]);            }          }                    if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {            const v = parseInt(this.discountFilter.value);            if (!isNaN(v) && v > 0) {              const ratio = (100 - v) / 100;              url.searchParams.append('min_discount_ratio', ratio.toString());            }          }                    if (this.offerTypeSelect && this.offerTypeSelect.value) {            url.searchParams.append('offer', this.offerTypeSelect.value);          }                    url.searchParams.append('filter_product_types', 'deals');                    url.searchParams.append('rows', this.getRowsLimit().toString());          let response;          try {             response = await fetch(url.toString());          } catch(e) {             if (window.location.protocol === 'file:') {                console.warn("[Tom's Guide Widget] fetch from file:// blocked by local CORS policy, falling back to Adviser mock.");                await this.fetchAdviserDeals(query);                return;             }             console.warn("Hawk fetch failed", e);             this.deals = [];             this.render();             return;          }          if (!response.ok) {            throw new Error('Hawk API Response Error');          }          const rawData = await response.json();          // Safely locate data array from potentially wrapped response          let offers = [];          let modelInfoArray = [];                    let brandFilterData = null;          if (rawData && rawData.widget && rawData.widget.data && Array.isArray(rawData.widget.data.filters)) {             brandFilterData = rawData.widget.data.filters.find(f => f.type === 'label_text_brand');          } else if (rawData && rawData.data && Array.isArray(rawData.data.filters)) {             brandFilterData = rawData.data.filters.find(f => f.type === 'label_text_brand');          }          if (brandFilterData && Array.isArray(brandFilterData.values) && brandFilterData.values.length > 0) {             this.populateBrandDropdown(brandFilterData.values);          } else {             if (this.brandFilterWrapper && this.selectedBrands.length === 0) {                this.brandFilterWrapper.style.display = 'none';             }          }                    if (rawData && rawData.widget && rawData.widget.data) {            if (Array.isArray(rawData.widget.data.offers)) offers = rawData.widget.data.offers;            if (rawData.widget.data.model_info && typeof rawData.widget.data.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.widget.data.model_info) ? rawData.widget.data.model_info : Object.values(rawData.widget.data.model_info);            }          } else if (rawData && rawData.data) {            if (Array.isArray(rawData.data.offers)) offers = rawData.data.offers;            if (rawData.data.model_info && typeof rawData.data.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.data.model_info) ? rawData.data.model_info : Object.values(rawData.data.model_info);            }          } else {            if (Array.isArray(rawData)) offers = rawData;            else if (rawData && Array.isArray(rawData.offers)) offers = rawData.offers;            else if (rawData && rawData.offers && Array.isArray(rawData.offers.offer)) offers = rawData.offers.offer;            else if (rawData && rawData.offers) offers = [].concat(rawData.offers);                        if (rawData && rawData.model_info && typeof rawData.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.model_info) ? rawData.model_info : Object.values(rawData.model_info);            }          }          let modelDetails = {};          modelInfoArray.forEach(m => {            const mId = m.model_id || m.id;            if (mId) {              modelDetails[mId] = {                score: m.score != null ? parseFloat(m.score) : null,                brand: m.brand || null,                parent: (m.parents && Array.isArray(m.parents) && m.parents.length > 0) ? m.parents[0].name : null              };            }          });          offers.forEach(item => {            let data = { ...item };            const mId = data.model_id;            if (mId && modelDetails[mId]) {              data.review_score = modelDetails[mId].score;              data.model_brand = modelDetails[mId].brand;              data.model_parent = modelDetails[mId].parent;            } else {              data.review_score = null;            }                        let itemOffers = [];            if (Array.isArray(item.offers)) itemOffers = item.offers;            else if (Array.isArray(item.offer)) itemOffers = item.offer;            else if (item.offers && typeof item.offers === 'object') itemOffers = [item.offers];            else if (item.offer && typeof item.offer === 'object') itemOffers = [item.offer];            if (itemOffers.length > 0) {              itemOffers.forEach(subItem => {                let subData = { ...item, ...subItem };                const subId = subData.model_id;                if (subId && modelDetails[subId]) {                  subData.review_score = modelDetails[subId].score;                  subData.model_brand = modelDetails[subId].brand;                  subData.model_parent = modelDetails[subId].parent;                } else if (data.review_score != null) {                  subData.review_score = data.review_score;                }                if (subData.merchant && typeof subData.merchant === 'object') {                  subData.merchant_name = subData.merchant.name;                }                this.deals.push(this.extractDealData(subData));              });              return;            }                        if (item.merchant && typeof item.merchant === 'object') {              data.merchant_name = item.merchant.name;            }                        this.deals.push(this.extractDealData(data));          });                    this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        async fetchAdviserDeals(query) {          // ======================================================================          // TODO: ADVISER API REPLACEMENT          // The code below simulates the Adviser API response using mock data.          // Once the real endpoint is ready, remove getAdviserMockData() and           // perform an actual fetch() request similar to fetchHawkDeals().          // Example:          // const area = this.getAreaCode();          // let apiUrl = `https://your-adviser-api.com/search?q=${query}&area=${area}`;          // if (this.priceFilter && this.priceFilter.value !== 'all') {          //   const val = this.priceFilter.value;          //   if (val === 'under50') apiUrl += '&filter_max_price=50';          //   else if (val === '50_100') apiUrl += '&filter_max_price=100';          //   else if (val === '100_200') apiUrl += '&filter_max_price=200';          //   else if (val === '200_500') apiUrl += '&filter_max_price=500';          // }          // const res = await fetch(apiUrl);          // const rawData = await res.json();          // ======================================================================          // Simulating network latency          await new Promise(resolve => setTimeout(resolve, 400));                    const rawData = this.getAdviserMockData();          let offers = [];                    if (rawData && rawData.data && rawData.data.Get && Array.isArray(rawData.data.Get.Deal)) {            offers = rawData.data.Get.Deal;          }                    // Basic client-side filtering for the mock if we want it to react to the query          const q = query.toLowerCase();          const selectedRetailer = (this.retailerSelect && this.retailerSelect.value) ? this.retailerSelect.value.toLowerCase() : null;                    offers.forEach(item => {            const dataObj = item;                        // Apply retailer filter            const itemRetailer = (dataObj.dataRetailer || '').toLowerCase();            if (selectedRetailer && itemRetailer !== selectedRetailer && !itemRetailer.includes(selectedRetailer)) {              return;            }                        // Apply mock price filter            let price = dataObj.dataDiscountedPrice || 0;            if (typeof price === 'string') {              price = parseFloat(price.replace(/[^0-9.]/g, ''));            }            let priceVal = null;            const min = this.customPriceMin ? this.customPriceMin.value : '';            const max = this.customPriceMax ? this.customPriceMax.value : '';            if (min || max) {               priceVal = `${min}_${max}`;            } else if (this.priceFilter && this.priceFilter.value !== 'all') {               priceVal = this.priceFilter.value;            }            if (priceVal) {              if (priceVal === 'under50' && price >= 50) return;              if (priceVal === 'over50' && price <= 50) return;              if (priceVal === 'over30' && price <= 30) return;              if (priceVal === 'over500' && price <= 500) return;              if (priceVal.includes('_')) {                 const parts = priceVal.split('_');                 if (parts[0] && price < parseFloat(parts[0])) return;                 if (parts[1] && price > parseFloat(parts[1])) return;              }            }                        // Map Adviser schema to our widget's expected schema            const mappedData = {              url: dataObj.linkHREF || dataObj.dataLink || '#',              image: dataObj.imageURL || (dataObj.image && dataObj.image.src) || '',              title: dataObj.dataProduct || (dataObj.product && dataObj.product.name) || 'Product Deal',              merchant: dataObj.dataRetailer || 'Retailer',              price: dataObj.dataDiscountedPrice || 0,              currency: dataObj.dataCurrency === 'USD' ? '$' : (dataObj.dataCurrency || '$'),              msrp: dataObj.dataOriginalPrice || null            };                        const titleLow = mappedData.title.toLowerCase();            const merchLow = mappedData.merchant.toLowerCase();                        // Smarter mock filtering            let isMatch = false;            if (q === '' || this.isBroadQuery(q)) {              isMatch = true;            } else if (titleLow.includes(q) || merchLow.includes(q)) {              isMatch = true;            } else if ((q.includes('laptop') || q.includes('mac') || q.includes('pc')) && (titleLow.includes('macbook') || titleLow.includes('laptop'))) {              isMatch = true;            } else if ((q.includes('tv') || q.includes('television')) && (titleLow.includes('tv') || titleLow.includes('oled') || titleLow.includes('qled'))) {              isMatch = true;            } else if ((q.includes('phone') || q.includes('smartphone')) && (titleLow.includes('galaxy') || titleLow.includes('phone'))) {              isMatch = true;            } else if ((q.match(/watch|fitness|run|shoe/)) && (titleLow.includes('forerunner') || titleLow.includes('saucony') || titleLow.includes('watch'))) {              isMatch = true;            }                        if (isMatch) {               this.deals.push(this.extractDealData(mappedData));            }          });                    let rowLimit = this.getRowsLimit();          // Intentionally omitting the slice here to allow "Load More" to work if the API returns more                    this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        getAdviserMockData() {          return {            "data": {              "Get": {                "Deal": [                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 300,                    "dataOriginalPrice": 399,                    "dataProduct": "Samsung Galaxy A36",                    "dataRetailer": "Samsung",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/MqDYsukV3JBG54te6dEs7j.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 14,                    "dataOriginalPrice": 24,                    "dataProduct": "Blink Mini",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/3JurmAjHsDa5tPdaHAwEV8.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 59,                    "dataOriginalPrice": 99,                    "dataProduct": "Ring Video Doorbell",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/rAh4uR7AsAsALCCLTXnLNJ.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 10,                    "dataOriginalPrice": 599,                    "dataProduct": "MacBook Neo",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/Lg4Dvg68j9SbB5CPNrTEpH.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 749,                    "dataOriginalPrice": 849,                    "dataProduct": "65\\\" Fire TV Omni 4K QLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/SG34ZWodUkLTxJvMTbjPYR.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 71,                    "dataOriginalPrice": 160,                    "dataProduct": "Saucony Hurricane 24",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/vxf7UD5T2Am7guVzFoFcZ4.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 649,                    "dataOriginalPrice": 749,                    "dataProduct": "Garmin Forerunner 970",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/3GKnEu7CdhtxPMfnPCMCiA.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1049,                    "dataOriginalPrice": 1499,                    "dataProduct": "LG 48\\\" C4 4K OLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/imvwZV9zoMD6fn9Afuge35.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1499,                    "dataOriginalPrice": 2199,                    "dataProduct": "Samsung 49\\\" Odyssey Neo G9 4K Gaming Monitor",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/XWDEJ5dUAE2nhK8k3Jk7k7.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 299,                    "dataOriginalPrice": 699,                    "dataProduct": "EGOHOME Black Memory Foam Mattress (queen)",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/hMUemtAejNETLVYxNrktzm.jpg"                  }                ]              }            }          };        }        decodeHTML(html) {          if (!html) return '';          const txt = document.createElement("textarea");          txt.innerHTML = String(html);          return txt.value;        }        extractDealData(item) {          const priceRawStr = String(item.price || item.current_price || '0');          const msrpRawStr = String(item.was_price || item.msrp || item.original_price || '0');          const rawPrice = parseFloat(priceRawStr.replace(/[^\d.]/g, '')) || 0;          const rawMsrp = parseFloat(msrpRawStr.replace(/[^\d.]/g, '')) || 0;          const isCheckPrice = rawPrice === 0 || priceRawStr === '0.00' || priceRawStr === '0';                    let originalImageUrl = item.image || item.image_url || item.product_image || '';          let imageUrl = originalImageUrl;          if ((!imageUrl || isCheckPrice) && item.model_image_url) {             imageUrl = item.model_image_url;             originalImageUrl = imageUrl;          } else if ((!imageUrl || isCheckPrice) && item.model_image) {             imageUrl = item.model_image;             originalImageUrl = imageUrl;          }                    if (imageUrl) {            imageUrl = imageUrl.replace(/-(\d+)-(\d+)(\.[a-z.]+)$/i, '$3');          }                    let fallbackImage = '';          if (originalImageUrl && originalImageUrl !== imageUrl) {             fallbackImage = originalImageUrl;          } else if (item.model_image && item.model_image !== imageUrl) {             fallbackImage = item.model_image;          } else if (item.model_image_url && item.model_image_url !== imageUrl) {             fallbackImage = item.model_image_url;          }                    const rawCurrency = item.currency || item.currency_symbol || '$';                    let savingLabel = item.percentage_saving_label || '';          if (!savingLabel && rawMsrp > rawPrice && rawPrice > 0) {            const pct = Math.round(((rawMsrp - rawPrice) / rawMsrp) * 100);            if (pct > 0) {              savingLabel = `${pct}% OFF`;            }          }                    const isPrime = item.shipping && item.shipping.prime === true;                    let scoreRaw = (item.review_score !== undefined && item.review_score !== null && item.review_score > 0) ? parseFloat(item.review_score) : null;          let starRating = 0;          if (scoreRaw !== null) {            starRating = Math.round((scoreRaw > 10 ? scoreRaw / 20 : scoreRaw / 2) * 2) / 2;          }                    return {            id: item.offer_id || item.link || item.url || item.offer_link || Math.random().toString(),            url: item.link || item.url || item.offer_link || '#',            image: imageUrl,            fallbackImage: fallbackImage,            title: item.name || item.title || item.model_name || item.product_name || 'Unknown Product',            brand: item.brand || '',            productName: item.model_name || item.product_name || item.name || '',            merchant: item.merchant_name || item.merchant || item.retailer || 'Retailer',            price: item.price !== undefined ? String(item.price) : '0.00',            currency: this.decodeHTML(rawCurrency),            msrp: item.was_price || item.msrp || item.original_price || null,            rawPrice: rawPrice,            rawMsrp: rawMsrp,            hasWasPrice: (item.was_price !== undefined && item.was_price !== null),            isCheckPrice: isCheckPrice,            savingLabel: savingLabel,            isPrime: isPrime,            starRating: starRating > 0 ? starRating : null,            modelId: item.model_id || '',            productKey: item.product_key || '',            merchantId: (item.merchant && typeof item.merchant === 'object') ? item.merchant.id || '' : '',            matchId: item.match_id || '',            merchantNetwork: (item.merchant && typeof item.merchant === 'object') ? item.merchant.an || '' : '',            merchantUrl: (item.merchant && typeof item.merchant === 'object') ? item.merchant.url || '' : '',            modelBrand: item.model_brand || item.brand || '',            modelParent: item.model_parent || ''          };        }        sortData() {          const sortVal = this.sortSelect ? this.sortSelect.value : 'date_desc';          if (sortVal === 'price_asc') {            this.deals.sort((a, b) => a.rawPrice - b.rawPrice);          } else if (sortVal === 'price_desc') {            this.deals.sort((a, b) => b.rawPrice - a.rawPrice);          } else if (sortVal === 'discount_desc') {            this.deals.sort((a, b) => {              const aDiscount = a.rawMsrp > a.rawPrice ? (a.rawMsrp - a.rawPrice) : 0;              const bDiscount = b.rawMsrp > b.rawPrice ? (b.rawMsrp - b.rawPrice) : 0;              return bDiscount - aDiscount;            });          } else if (sortVal === 'date_desc') {             this.deals.sort((a, b) => {                let dateA = 0;                let dateB = 0;                if (a && a.modifiedDate) {                   const valA = Array.isArray(a.modifiedDate) ? a.modifiedDate[0] : a.modifiedDate;                   dateA = new Date(valA).getTime();                   if (isNaN(dateA)) dateA = 0;                }                if (b && b.modifiedDate) {                   const valB = Array.isArray(b.modifiedDate) ? b.modifiedDate[0] : b.modifiedDate;                   dateB = new Date(valB).getTime();                   if (isNaN(dateB)) dateB = 0;                }                return dateB - dateA;             });          }        }        getFilteredDeals() {          let filteredDeals = [...this.deals];                    if (this.dealModeToggle && this.dealModeToggle.checked) {            filteredDeals = filteredDeals.filter(d => d.hasWasPrice || (d.msrp && d.rawMsrp > d.rawPrice));          }                    return filteredDeals;        }        showLoading() {          const _div = '<' + '/div>';          const skeletonCardHtml = `            \x3Cdiv class="tg-df-card">              \x3Cdiv class="tg-df-card-image-box">                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-img">${_div}              ${_div}              \x3Cdiv class="tg-df-card-body">                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short">${_div}                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text title">${_div}                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text title">${_div}                \x3Cdiv class="tg-df-card-footer mt-auto">                  \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="height:24px;">${_div}                ${_div}              ${_div}              \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text" style="height:44px; margin:0; border-radius:0;">${_div}            ${_div}`;          this.grid.innerHTML = Array(4).fill(skeletonCardHtml).join('');        }        showError() {          const _div = '<' + '/div>';          this.grid.innerHTML = `\x3Cdiv class="tg-df-message">            An error occurred while finding deals. Please check your connection and try again.          ${_div}`;        }        escapeHTML(str) {          if (!str) return '';          return String(str).replace(/[&<>'"]/g, tag => ({              '&': '&', '<': '<', '>': '>', "'": ''', '"': '"'          }[tag] || tag));        }                bindCouponButtons() {          const btns = this.root.querySelectorAll('.tg-df-tag-coupons');          btns.forEach(btn => {            btn.addEventListener('click', (e) => {              e.preventDefault();              e.stopPropagation();              const merchant = btn.getAttribute('data-merchant');              this.openVouchersModal(merchant);            });          });                    const closeBtn = this.root.querySelector('#tg-df-vouchers-close');          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          if (closeBtn) {            closeBtn.onclick = () => this.closeVouchersModal();          }          if (backdrop) {            backdrop.onclick = (e) => {              if (e.target === backdrop) this.closeVouchersModal();            };          }        }                closeVouchersModal() {          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          if (backdrop) backdrop.classList.remove('active');        }                async checkMerchantsCouponsBulk(merchants) {          if (!merchants || merchants.length === 0) return {};          const controller = new AbortController();          const timeoutId = setTimeout(() => controller.abort(), 4000);          try {            const area = this.getAreaCode();            const url = new URL('https://search-api.fie.future.net.uk/widget.php');            url.searchParams.append('model_name', 'Everything');            url.searchParams.append('language', 'en-GB');            if (area) url.searchParams.append('area', area);            url.searchParams.append('combine_product_types', '1');            url.searchParams.append('filter_merchant_name', merchants.join(','));            url.searchParams.append('all_filters', 'false');            url.searchParams.append('exclude_unlabelled', 'false');            url.searchParams.append('include_specs', 'false');            url.searchParams.append('sort', 'voucher');            url.searchParams.append('distinct_merchants', 'natural');            url.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');            url.searchParams.append('rows', '120');            url.searchParams.append('origin', 'widgets-clientside');                        let res; try { res = await fetch(url.toString(), { signal: controller.signal }); } catch (e) { return {}; }            clearTimeout(timeoutId);            if (!res.ok) return {};            const data = await res.json();                        let offers = [];            if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {              offers = data.widget.data.offers;            } else if (data && data.data && Array.isArray(data.data.offers)) {              offers = data.data.offers;            } else if (Array.isArray(data)) {              offers = data;            } else if (data && Array.isArray(data.offers)) {              offers = data.offers;            } else if (data && data.offers && Array.isArray(data.offers.offer)) {              offers = data.offers.offer;            } else if (data && Array.isArray(data.data)) {              offers = data.data;            }                        const foundMerchants = new Set();            offers.forEach(o => {              let mName = o.merchant_name || o.merchant || o.retailer;              if (mName && typeof mName === 'object') mName = mName.name;              if (mName) foundMerchants.add(String(mName).toLowerCase());            });            const resultMap = {};            merchants.forEach(m => {              if (m) resultMap[m] = foundMerchants.has(String(m).toLowerCase());            });            return resultMap;          } catch (e) {            return {};          }        }                async openVouchersModal(merchantName) {          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          const title = this.root.querySelector('#tg-df-vouchers-title');          const content = this.root.querySelector('#tg-df-vouchers-content');                    if (!backdrop || !content) return;                    // HACK: Hide closing tags          const _div = '<' + '/div>';          const _span = '<' + '/span>';          const _a = '<' + '/a>';          const _h4 = '<' + '/h4>';          const _svg = '<' + '/svg>';          const _circle = '<' + '/circle>';          const _polyline = '<' + '/polyline>';          const _rect = '<' + '/rect>';          const _path = '<' + '/path>';                    title.innerText = `${merchantName} Coupons & Deals`;          content.innerHTML = `\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text">${_div}                               \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text">${_div}`;          backdrop.classList.add('active');                    try {            const area = this.getAreaCode();            const url = new URL('https://search-api.fie.future.net.uk/widget.php');            url.searchParams.append('model_name', 'Everything');            url.searchParams.append('language', 'en-GB');            if (area) url.searchParams.append('area', area);            url.searchParams.append('combine_product_types', '1');            url.searchParams.append('filter_merchant_name', merchantName);            url.searchParams.append('all_filters', 'false');            url.searchParams.append('exclude_unlabelled', 'false');            url.searchParams.append('include_specs', 'false');            url.searchParams.append('sort', 'voucher');            url.searchParams.append('distinct_merchants', 'natural');            url.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');            url.searchParams.append('rows', '50');            url.searchParams.append('origin', 'widgets-clientside');                        const res = await fetch(url.toString());            if (!res.ok) throw new Error('API Error');            const data = await res.json();                        let offers = [];            if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {              offers = data.widget.data.offers;            } else if (data && data.data && Array.isArray(data.data.offers)) {              offers = data.data.offers;            } else if (Array.isArray(data)) {              offers = data;            } else if (data && Array.isArray(data.offers)) {              offers = data.offers;            } else if (data && data.offers && Array.isArray(data.offers.offer)) {              offers = data.offers.offer;            } else if (data && Array.isArray(data.data)) {              offers = data.data;            }                        if (offers.length === 0) {              content.innerHTML = `\x3Cdiv class="tg-df-message">No vouchers currently available for ${this.escapeHTML(merchantName)}.${_div}`;              return;            }                        content.innerHTML = offers.map((v, idx) => {              let offerObj = v;              if (v.offers && v.offers.offer) {                offerObj = Array.isArray(v.offers.offer) ? v.offers.offer[0] : v.offers.offer;              } else if (v.offer) {                offerObj = Array.isArray(v.offer) ? v.offer[0] : v.offer;              }              let logoUrl = v.logo_url || offerObj.logo_url || '';              if (!logoUrl && v.merchant) {                if (Array.isArray(v.merchant) && v.merchant.length > 0) logoUrl = v.merchant[0].logo_url || '';                else logoUrl = v.merchant.logo_url || '';              }                            const offerName = offerObj.name || offerObj.title || v.name || v.title || 'Special Offer';              const endTime = offerObj.end_time || v.end_time || '';              const linkUrl = offerObj.link || offerObj.url || v.link || v.url || '#';                            let foundVoucherCode = '';              const findVoucherCode = (obj) => {                if (!obj || typeof obj !== 'object') return;                if (obj.type === 'voucher_code' && obj.display_value) {                  foundVoucherCode = obj.display_value;                  return;                }                if (Array.isArray(obj)) {                  for (const item of obj) {                    findVoucherCode(item);                    if (foundVoucherCode) return;                  }                } else {                  for (const k in obj) {                    if (Object.prototype.hasOwnProperty.call(obj, k)) {                      findVoucherCode(obj[k]);                      if (foundVoucherCode) return;                    }                  }                }              };              findVoucherCode(offerObj);              if (!foundVoucherCode) findVoucherCode(v);                            const voucherCode = foundVoucherCode || offerObj.voucher_code || v.voucher_code || '';              const codeHtml = voucherCode ? `\x3Cspan class="tg-df-voucher-code" data-action="copy-code" data-code="${this.escapeHTML(voucherCode)}" title="Copy to clipboard">                \x3Cspan class="tg-df-voucher-code-text">${this.escapeHTML(voucherCode)}${_span}                \x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-left:6px;flex-shrink:0;" class="tg-df-voucher-copy-icon">                  \x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2">${_rect}                  \x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">${_path}                ${_svg}              ${_span}` : '';                            const logoHtml = logoUrl                 ? `\x3Cimg src="${this.escapeHTML(logoUrl)}" alt="${this.escapeHTML(offerName)}" class="tg-df-voucher-logo" />`                 : `\x3Cdiv class="tg-df-voucher-logo" style="background:#e2e8f0;">${_div}`;                            let expiryHtml = '';              if (endTime) {                let dStr = endTime;                if (!isNaN(dStr) && String(dStr).length === 10) dStr = Number(dStr) * 1000;                const d = new Date(dStr);                if (!isNaN(d.getTime())) {                  const options = { year: 'numeric', month: 'short', day: 'numeric' };                  expiryHtml = `                    \x3Cdiv class="tg-df-voucher-expiry">                      \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">                        \x3Ccircle cx="12" cy="12" r="10">${_circle}                        \x3Cpolyline points="12 6 12 12 16 14">${_polyline}                      ${_svg}                      Expires ${d.toLocaleDateString(undefined, options)}                    ${_div}`;                }              }              const revenueIdVal = generateRevenueId(linkUrl, offerName, merchantName, null);              const rewrittenLinkUrl = rewriteAffiliateLink(linkUrl, area, revenueIdVal);              return `                \x3Ca href="${this.escapeHTML(rewrittenLinkUrl)}" target="_blank" rel="noopener nofollow" class="tg-df-voucher-item"                  data-action="voucher-click"                  data-product-name="${this.escapeHTML(offerName)}"                  data-merchant-name="${this.escapeHTML(merchantName)}"                  data-analytics-id="${this.escapeHTML(offerObj.offer_id || offerObj.id || v.id || '')}"                  data-price=""                  data-previous-price=""                  data-original-link="${this.escapeHTML(linkUrl)}"                  data-revenue-id="${revenueIdVal}"                  data-index="${idx}"                  data-total="${offers.length}"                  data-in-stock="true"                  data-currency="USD"                  data-model-id="${this.escapeHTML(offerObj.model_id || v.model_id || offerObj.id || v.id || '')}"                  data-merchant-id="${this.escapeHTML(offerObj.merchant_id || offerObj.merchant?.id || '')}"                >                  ${logoHtml}                  \x3Cdiv class="tg-df-voucher-content">                    \x3Ch4 class="tg-df-voucher-title">${this.escapeHTML(offerName)}${_h4}                    ${codeHtml}                    ${expiryHtml}                  ${_div}                ${_a}              `;            }).join('');                        // Attach copy functionality            const copyBtns = content.querySelectorAll('[data-action="copy-code"]');            copyBtns.forEach(btn => {              btn.addEventListener('click', async (e) => {                e.preventDefault();                e.stopPropagation();                                const code = btn.getAttribute('data-code');                if (!code) return;                                try {                  const copyToClipboard = async (text) => {                     if (window.navigator.clipboard && window.isSecureContext) {                        try { await window.navigator.clipboard.writeText(text); return; } catch (e) {}                     }                     const textArea = document.createElement("textarea");                     textArea.value = text;                     textArea.style.position = "fixed";                     document.body.appendChild(textArea);                     textArea.focus();                     textArea.select();                     document.execCommand('copy');                     textArea.remove();                  };                  await copyToClipboard(code);                                    // Visual feedback                  btn.classList.add('copied');                  const textSpan = btn.querySelector('.tg-df-voucher-code-text');                  const iconSvg = btn.querySelector('.tg-df-voucher-copy-icon');                                    const origText = textSpan.innerText;                  const origIcon = iconSvg.innerHTML;                                    textSpan.innerText = 'Copied!';                  iconSvg.innerHTML = `\x3Cpolyline points="20 6 9 17 4 12">${_polyline}`;                                    setTimeout(() => {                    if (btn) {                      btn.classList.remove('copied');                      if (textSpan) textSpan.innerText = origText;                      if (iconSvg) iconSvg.innerHTML = origIcon;                    }                  }, 2000);                                    trackElementInteraction({                    id: 'voucher-code-copy',                    name: 'Copy Voucher Code',                    label: `Copied ${code} for ${merchantName}`                  });                } catch (err) {                  console.warn('Failed to copy text: ', err);                }              });            });            // Attach voucher click tracking            const voucherBtns = content.querySelectorAll('[data-action="voucher-click"]');            voucherBtns.forEach(btn => {              btn.addEventListener('click', (e) => {                if (e.target.closest('[data-action="copy-code"]')) return;                                const productName = btn.getAttribute('data-product-name');                const merchantNameAttr = btn.getAttribute('data-merchant-name');                const productId = btn.getAttribute('data-analytics-id');                const price = parseFloat(btn.getAttribute('data-price')) || null;                const prevPriceStr = btn.getAttribute('data-previous-price');                const previousPrice = prevPriceStr ? parseFloat(prevPriceStr) : null;                const originalLink = btn.getAttribute('data-original-link');                const rewrittenLink = btn.getAttribute('href');                const revenueId = btn.getAttribute('data-revenue-id');                const index = parseInt(btn.getAttribute('data-index'), 10) || 0;                const inStock = btn.getAttribute('data-in-stock') === 'true';                const totalText = btn.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: btn.getAttribute('data-model-id') || null,                    matchId: btn.getAttribute('data-match-id') || null,                    brand: btn.getAttribute('data-model-brand') || null,                    parent: btn.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: btn.getAttribute('data-merchant-id') || null,                    network: btn.getAttribute('data-merchant-network') || null,                    url: btn.getAttribute('data-merchant-url') || null,                    name: merchantNameAttr                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: btn.getAttribute('data-currency') || 'USD'                };                if (typeof trackDealClick === 'function') {                  trackDealClick(trackingParams);                }              });            });                                  } catch (e) {            console.warn(e);            content.innerHTML = `\x3Cdiv class="tg-df-message">Failed to load vouchers.${_div}`;          }        }        render() {          try {            if (this.getViewMode() === 'savings_squad' && this.airedaleTags.length > 0) {              if (this.categoryFilterWrapper) {                 this.categoryFilterWrapper.style.display = 'flex';              }              if (this.categoryFilter) {                 const _option = '<' + '/option>';                 let optionsHtml = `\x3Coption value="all">All Categories${_option}`;                 this.airedaleTags.forEach(tag => {                    const isSelected = this.activeDealTag === tag ? 'selected' : '';                    optionsHtml += `\x3Coption value="${this.escapeHTML(tag)}" ${isSelected}>${this.escapeHTML(tag)}${_option}`;                 });                 this.categoryFilter.innerHTML = optionsHtml;                 this.categoryFilter.value = this.activeDealTag || 'all';              }            } else {               if (this.categoryFilterWrapper) {                  this.categoryFilterWrapper.style.display = 'none';               }            }            const displayDeals = this.getFilteredDeals();          // HACK: Hide closing tags from the CMS HTML sanitizer so it doesn't strip them during in-page injection          const _div = '<' + '/div>';          const _span = '<' + '/span>';          const _a = '<' + '/a>';          const _h3 = '<' + '/h3>';          const _p = '<' + '/p>';          const _strong = '<' + '/strong>';          const _sup = '<' + '/sup>';          const _button = '<' + '/button>';          if (displayDeals.length === 0) {            if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {              if (this.deals.length > 0) {                 this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                  No deals match your selected filters.                ${_div}`;              } else if (this.getViewMode() === 'savings_squad' && this.currentQuery.length <= 2) {                 // Do not show "no exact matches" if query is empty for savings_squad                 this.grid.innerHTML = '';              } else {                 this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                  No exact matches found for "\x3Cstrong>${this.escapeHTML(this.currentQuery)}${_strong}". Try adjusting your search term.                ${_div}`;              }            } else {              this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                Search product or category names to discover the best deals from across the web.              ${_div}`;            }            return;          }          let dealsHtml = displayDeals.slice(0, this.displayLimit).map((deal, index) => {            try {               const currencySym = this.escapeHTML(deal.currency);               const isoCurrencyCode = normalizeCurrency(currencySym);               const escapedPrice = this.escapeHTML(deal.price);               const escapedMsrp = this.escapeHTML(deal.msrp);               const areaCode = this.getAreaCode();                              const revenueId = generateRevenueId(deal.url, deal.title, deal.merchant, null);               const originalLink = deal.url;               const rewrittenLink = rewriteAffiliateLink(deal.url, areaCode, revenueId);                        const productCategoryName = 'deals';            const dataAttr = `              data-action="${deal.isCheckPrice ? 'view-similar-click' : 'deal-click'}"              data-analytics-id="${this.escapeHTML(deal.externalProductId || deal.id || '')}"              data-product-name="${this.escapeHTML(deal.title)}"              data-merchant-name="${this.escapeHTML(deal.merchant)}"              data-price="${deal.rawPrice || ''}"              data-previous-price="${deal.rawMsrp || ''}"              data-original-link="${this.escapeHTML(originalLink)}"              data-revenue-id="${revenueId}"              data-index="${index}"              data-total="${displayDeals.length}"              data-in-stock="${deal.inStock !== false}"              data-currency="${this.escapeHTML(isoCurrencyCode)}"              data-model-id="${this.escapeHTML(deal.modelId || '')}"              data-product-key="${this.escapeHTML(deal.productKey || '')}"              data-merchant-id="${this.escapeHTML(deal.merchantId || '')}"            `;                        let priceGroupHtml = '';            let isSavingsSquadMode = this.getViewMode() === 'savings_squad';            let ctaText = 'View Deal';            let formattedPrice = '';            let msrpHtml = '';                        if (deal.isCheckPrice) {              ctaText = 'View Deal';              if (isSavingsSquadMode) {                priceGroupHtml = ``;              } else {                priceGroupHtml = `                  \x3Cdiv class="tg-df-card-price-group">                    \x3Cspan class="tg-df-card-price" style="font-size: 15px; font-weight: 500; font-style: italic;">See price at retailer${_span}                  ${_div}                `;              }            } else {              // Format Price              formattedPrice = escapedPrice.includes(currencySym)                 ? escapedPrice                 : `${currencySym}${escapedPrice}`;                              // Format MSRP              msrpHtml = deal.msrp && deal.rawMsrp > deal.rawPrice                ? `\x3Cspan class="tg-df-card-msrp">${escapedMsrp.includes(currencySym) ? escapedMsrp : currencySym + escapedMsrp}${_span}`                : '';                              priceGroupHtml = isSavingsSquadMode ? `` : `                \x3Cdiv class="tg-df-card-price-group">                  \x3Cspan class="tg-df-card-price">${formattedPrice}${_span}                  ${msrpHtml}                ${_div}              `;            }                        const discountBadgeHtml = deal.savingLabel && !deal.isCheckPrice              ? `\x3Cspan class="tg-df-card-discount-badge">${this.escapeHTML(deal.savingLabel)}${_span}`              : '';                          // HACK for CMS            const _button = '<' + '/button>';            const _svg = '<' + '/svg>';            const _path = '<' + '/path>';            const _rect = '<' + '/rect>';            const _circle = '<' + '/circle>';            const _polyline = '<' + '/polyline>';            const _line = '<' + '/line>';                        let badgesHtml = '';            const primeBadge = deal.isPrime ? `              \x3Cspan class="tg-df-tag tg-df-tag-prime">                \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">                  \x3Cpath d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z">${_path}                ${_svg} Prime              ${_span}            ` : '';                        const couponsBadge = deal.merchant && deal.merchant.toLowerCase().includes('amazon') ? '' : `              \x3Cdiv class="tg-df-coupon-wrapper" data-merchant="${this.escapeHTML(deal.merchant)}" style="display:inline-flex; align-items:center;">                \x3Cdiv class="tg-df-coupon-spinner">${_div}                \x3Cbutton type="button" class="tg-df-tag tg-df-tag-coupons" data-action="coupons-click" data-merchant="${this.escapeHTML(deal.merchant)}" style="display:none;">                  \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">                    \x3Cpath d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z">${_path}                    \x3Cline x1="7" y1="7" x2="7.01" y2="7">${_line}                  ${_svg} Coupons                ${_button}              ${_div}            `;                        // Note: We always add coupons badge if there's a chance, but to allow 3-line titles we check wrapper display state            badgesHtml = `              \x3Cdiv class="tg-df-card-badges">                ${primeBadge}                ${couponsBadge}              ${_div}            `;            const _linearGradient = '<' + '/linearGradient>';            const _polygon = '<' + '/polygon>';            const _stop = '<' + '/stop>';            const _defs = '<' + '/defs>';                        let starHtml = '';            if (deal.starRating) {              let rating = deal.starRating;                            if (rating > 0) {                const fullStars = Math.floor(rating);                const halfStar = (rating - fullStars) >= 0.5 ? 1 : 0;                const emptyStars = Math.max(0, 5 - fullStars - halfStar);                const blue = '#1f69ff'; // Tom's guide brand color from VIEW DEAL button                const gray = '#cbd5e1';                                const starSvgFull = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="${blue}" stroke="${blue}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26">${_polygon}${_svg}`;                                const gradId = 'half_grad_' + Math.floor(Math.random()*1000000);                const starSvgHalf = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" stroke="${blue}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cdefs>\x3ClinearGradient id="${gradId}" x1="0" x2="1" y1="0" y2="0">\x3Cstop offset="50%" stop-color="${blue}">${_stop}\x3Cstop offset="50%" stop-color="transparent">${_stop}${_linearGradient}${_defs}                  \x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26" fill="url(#${gradId})">${_polygon}${_svg}`;                                  const starSvgEmpty = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="${gray}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26">${_polygon}${_svg}`;                                let stars = [];                for (let i=0; i<fullStars; i++) stars.push(starSvgFull);                if (halfStar) stars.push(starSvgHalf);                for (let i=0; i<emptyStars; i++) stars.push(starSvgEmpty);                                starHtml = `\x3Cdiv class="tg-df-card-stars" style="display:flex;align-items:center;margin-bottom:8px;font-size:13px;font-weight:600;color:var(--tg-df-text-muted);">                  \x3Cspan style="margin-right:6px;">Tom's Guide:${_span}                  \x3Cdiv style="display:flex;gap:2px;">                    ${stars.join('')}                  ${_div}                ${_div}`;              }            }            let htmlOutput = '';            if (isSavingsSquadMode) {              htmlOutput += `              \x3Cdiv class="hawk-deal-widget-container tg-df-mobile-only" data-collapsible="true">                ${this.editorMode ? `\x3Cinput type="checkbox" class="tg-df-deal-checkbox" data-id="${this.escapeHTML(deal.id)}" ${this.selectedDeals.has(deal.id) ? 'checked' : ''} style="margin-bottom: 10px;">` : ''}                \x3Cdiv class="hawk-deal-widget-wrap">                  \x3Cdiv class="hawk-deal-widget-image-container">                    \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" rel="sponsored noopener" target="_blank" class="hawk-affiliate-link-deal-widget" ${dataAttr}>                      \x3Cimg ${deal.image ? `src="${this.escapeHTML(deal.image)}"` : ''} alt="${this.escapeHTML(deal.title)}" class="hawk-lazy-image-deal-widget" loading="lazy" width="140" height="160" onerror="${deal.fallbackImage ? `if(!this.dataset.fb) { this.dataset.fb='1'; this.src='${this.escapeHTML(deal.fallbackImage)}'; } else { this.style.opacity='0'; }` : `this.style.opacity='0';`}">                    ${_a}                  ${_div}                  \x3Cdiv class="hawk-deal-widget-text-cta-container">                    \x3Cdiv class="hawk-deal-widget-text-body-container">                      \x3Cdiv class="hawk-deal-widget-text-body-main">                        \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                          ${deal.isCheckPrice ? `                            \x3Cspan class="hawk-deal-widget-title-product-title">${this.escapeHTML(deal.title)}${_span}                          ` : `                            \x3Cspan class="hawk-deal-widget-title-product-title">${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_span}                          `}                        ${_a}                        ${!deal.isCheckPrice && deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `                          \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                            \x3Cspan class="hawk-deal-widget-title-was-price">was ${currencySym}${escapedMsrp}${_span}                          ${_a}                        ` : ''}                        \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                          \x3Cspan class="hawk-deal-widget-title-retailer-price">                            ${!deal.isCheckPrice ? `                              \x3Cspan class="hawk-deal-widget-title-price">now ${formattedPrice}${_span}                              \x3Cspan class="hawk-deal-widget-title-retailer"> at ${this.escapeHTML(deal.merchant)}${_span}                            ` : `                              \x3Cspan class="hawk-deal-widget-title-price">See price at ${this.escapeHTML(deal.merchant)}${_span}                            `}                          ${_span}                        ${_a}                        ${deal.description ? `\x3Cdiv class="hawk-deal-widget-text-body-description tg-df-card-desc-container" style="margin-bottom: 12px; position: relative;">                          \x3Cp class="tg-df-card-desc-content" style="font-size: 13px; color: var(--tg-df-text-muted); margin-bottom: 0; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;">${this.escapeHTML(deal.description)}${_p}                          \x3Cbutton type="button" class="tg-df-card-desc-btn" style="display: none; appearance: none; border: none; color: #000000; font-size: 11px; font-weight: 700; text-transform: uppercase; cursor: pointer; font-family: inherit; position: absolute; bottom: 2px; right: 0; background: linear-gradient(to right, transparent, #fff 20%, #fff); padding: 0 0 0 16px;" onclick="                            var c = this.parentNode;                            if (this.dataset.expanded === 'true') {                              var pd = (c.tagName === 'P') ? c : this.previousElementSibling;                              if (c.tagName === 'P') { c.parentNode.appendChild(this); pd = c; }                              pd.style.display = '-webkit-box';                              pd.style.webkitLineClamp = '3';                              this.textContent = 'READ MORE';                              this.style.position = 'absolute';                              this.style.background = 'linear-gradient(to right, transparent, #fff 20%, #fff)';                              this.style.paddingLeft = '16px';                              this.dataset.expanded = 'false';                            } else {                              var pd = this.previousElementSibling;                              pd.style.display = 'inline';                              pd.style.webkitLineClamp = 'unset';                              this.textContent = 'READ LESS';                              this.style.position = 'static';                              this.style.background = 'transparent';                              this.style.paddingLeft = '4px';                              this.dataset.expanded = 'true';                              pd.appendChild(this);                            }                          ">READ MORE${_button}                        \x3C/div>` : ''}                      ${_div}                    ${_div}                    ${deal.authorName ? `                      \x3Cdiv class="tg-df-author-line-mobile" style="padding: 0 0 12px 0; background: transparent;">                         \x3Cdiv style="display: flex; align-items: center; gap: 12px;">                            ${deal.authorImage ? `\x3Cimg src="${this.escapeHTML(deal.authorImage)}" alt="${this.escapeHTML(deal.authorName)}" class="tg-df-author-img" width="40" height="40" style="border-radius: 50%; object-fit: cover; flex-shrink: 0; aspect-ratio: 1 / 1; min-width: 40px; min-height: 40px;">` : ''}                            \x3Cdiv style="display: flex; flex-direction: column;">                               \x3Cdiv style="font-size: 10px; color: var(--tg-df-text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 2px; font-weight: 600;">\x3Cspan style="color: #FF6600;">${this.escapeHTML(deal.merchant)}${_span} deal recommended by:${_div}                               \x3Cdiv style="font-size: 11px; color: var(--tg-df-text); line-height: 1.3;">                                  \x3Cstrong>\x3Ca href="https://www.tomsguide.com/${this.escapeHTML(deal.documentUrl || '').replace(/^\/+/, '')}" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit; border-bottom: 1px dotted var(--tg-df-text-muted);">${this.escapeHTML(deal.authorName)}${_a}${_strong}                                  ${deal.authorRole && !['null', 'nul', 'undefined'].includes(String(deal.authorRole).toLowerCase()) ? ` • ${this.escapeHTML(deal.authorRole)}` : ''}                                  ${deal.modifiedDate ? `\x3Cdiv style="color: var(--tg-df-text-muted); margin-top: 2px;">${getTimeAgo(deal.modifiedDate)}${_div}` : ''}                               ${_div}                            ${_div}                         ${_div}                      ${_div}                    ` : ''}                    \x3Cdiv class="hawk-deal-widget-footer">                      \x3Cdiv class="hawk-deal-widget-button-wrapper">                        \x3Cdiv class="hawk-deal-widget-preferred-partner-wrapper">                          \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-deal-button" rel="sponsored noopener" target="_blank" ${dataAttr}>                            \x3Cspan>View Deal${_span}                          ${_a}                        ${_div}                      ${_div}                    ${_div}                  ${_div}                ${_div}              ${_div}              `;            }            htmlOutput += `              \x3Cdiv class="tg-df-card ${isSavingsSquadMode ? 'tg-df-desktop-only' : ''}">                ${this.editorMode ? `\x3Cinput type="checkbox" class="tg-df-deal-checkbox" data-id="${this.escapeHTML(deal.id)}" ${this.selectedDeals.has(deal.id) ? 'checked' : ''}>` : ''}                \x3Cdiv class="tg-df-card-image-box">                  ${discountBadgeHtml}                  \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" style="display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;">                    \x3Cimg ${deal.image ? `src="${this.escapeHTML(deal.image)}"` : ''} alt="${this.escapeHTML(deal.title)}" class="tg-df-card-image" loading="lazy" onerror="${deal.fallbackImage ? `if(!this.dataset.fb) { this.dataset.fb='1'; this.src='${this.escapeHTML(deal.fallbackImage)}'; } else { this.style.opacity='0'; }` : `this.style.opacity='0';`}">                  ${_a}                  \x3Cdiv class="tg-df-card-merchant-wrapper" style="position: absolute; bottom: 0; right: 0; background: transparent; padding: 8px 12px; z-index: 10;">                     \x3Cspan class="tg-df-card-merchant-pill" style="text-align: right; margin-bottom: 0;" title="${this.escapeHTML(deal.merchant)}">${this.escapeHTML(deal.merchant)}${_span}                  ${_div}                ${_div}                \x3Cdiv class="tg-df-card-body">                  ${starHtml}                  ${badgesHtml}                  \x3Ch3 class="tg-df-card-title tg-df-custom-savings-squad-title" title="${this.escapeHTML(deal.title)}">                    \x3Ca href="${this.escapeHTML(rewrittenLink)}" disable-tracking="true" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit;">                      ${isSavingsSquadMode                         ? (deal.isCheckPrice                             ? (deal.title && deal.title.includes(':')                                 ? `\x3Cstrong>${this.escapeHTML(deal.title.substring(0, deal.title.indexOf(':') + 1))}${_strong}\x3Cspan style="color: #1f69ff; font-weight: normal;">${this.escapeHTML(deal.title.substring(deal.title.indexOf(':') + 1))}${_span}`                                : this.escapeHTML(deal.title)                              )                             : `\x3Cstrong>${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_strong} ${deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `\x3Cspan style="color: #d0021b; text-decoration: line-through; font-weight: normal; margin-right: 4px;">was ${currencySym}${escapedMsrp}${_span} ` : ''}\x3Cspan style="color: #1f69ff; font-weight: normal;">now ${formattedPrice} at ${this.escapeHTML(deal.merchant)}${_span}`                          )                        : this.escapeHTML(deal.title)                      }                    ${_a}                  ${_h3}                  ${deal.description ? `\x3Cdiv class="tg-df-card-desc-container" style="margin-bottom: 12px; position: relative;">                    \x3Cp class="tg-df-card-desc-content" style="font-size: 13px; color: var(--tg-df-text-muted); margin-bottom: 0; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;">${this.escapeHTML(deal.description)}${_p}                    \x3Cbutton type="button" class="tg-df-card-desc-btn" style="display: none; appearance: none; border: none; color: #000000; font-size: 11px; font-weight: 700; text-transform: uppercase; cursor: pointer; font-family: inherit; position: absolute; bottom: 2px; right: 0; background: linear-gradient(to right, transparent, #fff 20%, #fff); padding: 0 0 0 16px;" onclick="                      var c = this.parentNode;                      if (this.dataset.expanded === 'true') {                        var pd = (c.tagName === 'P') ? c : this.previousElementSibling;                        if (c.tagName === 'P') { c.parentNode.appendChild(this); pd = c; }                        pd.style.display = '-webkit-box';                        pd.style.webkitLineClamp = '3';                        this.textContent = 'READ MORE';                        this.style.position = 'absolute';                        this.style.background = 'linear-gradient(to right, transparent, #fff 20%, #fff)';                        this.style.paddingLeft = '16px';                        this.dataset.expanded = 'false';                      } else {                        var pd = this.previousElementSibling;                        pd.style.display = 'inline';                        pd.style.webkitLineClamp = 'unset';                        this.textContent = 'READ LESS';                        this.style.position = 'static';                        this.style.background = 'transparent';                        this.style.paddingLeft = '4px';                        this.dataset.expanded = 'true';                        pd.appendChild(this);                      }                    ">READ MORE${_button}                  \x3C/div>` : ''}                  \x3Cdiv class="tg-df-card-footer">                    ${deal.authorName ? `                    \x3Cdiv class="tg-df-author-line-desktop" style="padding: 0 0 ${isSavingsSquadMode ? 0 : 12}px 0;">                       \x3Cdiv style="display: flex; align-items: center; gap: 10px;">                          ${deal.authorImage ? `\x3Cimg src="${this.escapeHTML(deal.authorImage)}" alt="${this.escapeHTML(deal.authorName)}" class="tg-df-author-img" width="36" height="36" style="border-radius: 50%; object-fit: cover; flex-shrink: 0; aspect-ratio: 1 / 1; min-width: 36px; min-height: 36px;">` : ''}                          \x3Cdiv style="display: flex; flex-direction: column;">                             \x3Cdiv style="font-size: 10px; color: var(--tg-df-text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 2px; font-weight: 600;">Recommended by:${_div}                             \x3Cdiv style="font-size: 11px; color: var(--tg-df-text); line-height: 1.2;">                                \x3Cstrong>\x3Ca href="https://www.tomsguide.com/${this.escapeHTML(deal.documentUrl || '').replace(/^\/+/, '')}" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit; border-bottom: 1px dotted var(--tg-df-text-muted);">${this.escapeHTML(deal.authorName)}${_a}${_strong}                                ${deal.authorRole && !['null', 'nul', 'undefined'].includes(String(deal.authorRole).toLowerCase()) ? ` • ${this.escapeHTML(deal.authorRole)}` : ''}                                ${deal.modifiedDate ? `\x3Cspan style="color: var(--tg-df-text-muted);"> • ${getTimeAgo(deal.modifiedDate)}${_span}` : ''}                             ${_div}                          ${_div}                       ${_div}                    ${_div}                    ` : ''}                    ${priceGroupHtml}                  ${_div}                ${_div}                \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" class="tg-df-card-cta" style="text-decoration: none; border-radius: 0;">${ctaText}${_a}              ${_div}            `;                        return htmlOutput;            } catch (e) {               console.log("Error rendering deal in map for index", index, typeof deal === 'object' ? JSON.stringify(deal) : deal, "MSG:", e.message);               return '';            }          }).join('');                    if (displayDeals.length > this.displayLimit) {            dealsHtml += `              \x3Cdiv style="width: 100%; display: flex; justify-content: center; margin-top: 16px; grid-column: 1 / -1;">                \x3Cbutton type="button" class="tg-df-tag-outline tg-df-load-more" style="padding: 8px 24px; border-radius: 100px; font-weight: 600; font-size: 14px; cursor: pointer;">Load More${_button}              ${_div}            `;          }                    this.grid.innerHTML = dealsHtml;          // Inject JSON-LD          try {            let targetNode = this.hostContainer || document.head;            let jsonLdScript = targetNode.querySelector('#tg-df-json-ld-' + this.widgetId);            if (!jsonLdScript) {                jsonLdScript = document.createElement('script');                jsonLdScript.type = 'application/ld+json';                jsonLdScript.id = 'tg-df-json-ld-' + this.widgetId;                targetNode.appendChild(jsonLdScript);            }            const jsonLdData = {              "@context": "https://schema.org",              "@type": "ItemList",              "itemListElement": displayDeals.slice(0, this.displayLimit).map((deal, index) => {                 let isoCurrency = "USD";                 if (deal.currency === '£') isoCurrency = "GBP";                 else if (deal.currency === '€') isoCurrency = "EUR";                 else if (deal.currency === 'A$') isoCurrency = "AUD";                 else if (deal.currency === 'CA$') isoCurrency = "CAD";                 const areaCode = typeof this.getAreaCode === 'function' ? this.getAreaCode() : 'US';                 const revenueId = typeof generateRevenueId === 'function' ? generateRevenueId(deal.url, deal.title, deal.merchant, null) : '';                 const rewrittenLink = typeof rewriteAffiliateLink === 'function' ? rewriteAffiliateLink(deal.url, areaCode, revenueId) : deal.url;                 return {                   "@type": "ListItem",                   "position": index + 1,                   "item": {                     "@type": "Product",                     "name": deal.title,                     "image": deal.image || "",                     "description": deal.description || "",                     "brand": {                       "@type": "Brand",                       "name": deal.brand || ""                     },                     "offers": {                       "@type": "Offer",                       "priceCurrency": isoCurrency,                       "price": deal.rawPrice || 0,                       "url": rewrittenLink,                       "seller": {                         "@type": "Organization",                         "name": deal.merchant || ""                       }                     }                   }                 };              }).filter(item => item.item.name)            };            jsonLdScript.textContent = JSON.stringify(jsonLdData);          } catch(e) { console.warn("JSON-LD generation failed", e); }          setTimeout(() => {            const contents = this.root.querySelectorAll('.tg-df-card-desc-content');            contents.forEach(p => {              if (p.scrollHeight > p.clientHeight || p.scrollHeight > 60) {                if (p.nextElementSibling) {                  p.nextElementSibling.style.display = 'block';                }              }            });                        // Allow hawklinks.js to discover and rewrite our widget links             // by appending the .article-body class and manually triggering processArticle.            let container = this.root.classList.contains('tg-df-container') ? this.root : this.root.querySelector('.tg-df-container');            if (container && !container.classList.contains('article-body')) {               container.classList.add('article-body');            }            if (this.grid && !this.grid.classList.contains('article-body')) this.grid.classList.add('article-body');            document.dispatchEvent(new CustomEvent('processArticle', { detail: { element: this.root } }));          }, 50);          const loadMoreBtn = this.grid.querySelector('.tg-df-load-more');          if (loadMoreBtn) {            loadMoreBtn.addEventListener('click', () => {              if (typeof trackElementInteraction === 'function') {                trackElementInteraction({ id: 'load-more', name: 'Load more', label: 'Load More Results' });              }              this.displayLimit += this.getRowsLimit();              this.render();            });          }                      this.bindCouponButtons();            this.checkAndUpdateCoupons();          } catch(e) {            console.warn("Widget render error", e);          }        }                async checkAndUpdateCoupons() {          const wrappers = Array.from(this.root.querySelectorAll('.tg-df-coupon-wrapper'));          if (wrappers.length === 0) return;                    const merchants = [...new Set(wrappers.map(w => w.getAttribute('data-merchant')).filter(Boolean))];          if (merchants.length === 0) return;          const couponResultsMap = await this.checkMerchantsCouponsBulk(merchants);                    for (const merchant of merchants) {            const hasCoupons = !!couponResultsMap[merchant];            const merchantWrappers = wrappers.filter(w => w.getAttribute('data-merchant') === merchant);            merchantWrappers.forEach(wrapper => {              const spinner = wrapper.querySelector('.tg-df-coupon-spinner');              const btn = wrapper.querySelector('.tg-df-tag-coupons');                            if (spinner) spinner.style.display = 'none';                            if (hasCoupons && btn) {                btn.style.display = 'inline-flex';              } else if (!hasCoupons) {                wrapper.style.display = 'none';              }            });          }        }        updateFloatingCopyBar() {          if (!this.editorBar || !this.editorSelectedCount) return;          if (this.editorMode && this.selectedDeals.size > 0) {            this.editorBar.style.display = 'flex';            this.editorSelectedCount.innerText = this.selectedDeals.size;          } else {            this.editorBar.style.display = 'none';          }        }        async copySelectedDealsToCMS() {           function htmlToSlate(htmlString) {              if (!htmlString) return [{ type: 'paragraph', children: [{ text: '' }] }];              let doc;              if (typeof window !== 'undefined' && window.DOMParser) {                 doc = new DOMParser().parseFromString(htmlString, 'text/html');              } else {                 doc = document.implementation.createHTMLDocument('');                 doc.body.innerHTML = htmlString;              }                            function parseNode(node, marks = {}) {                  if (node.nodeType === 3) {                      const text = node.textContent;                      if (!text) return null;                      return { text: text, ...marks };                  }                  if (node.nodeType === 1) {                      const tagName = node.tagName.toLowerCase();                      if (tagName === 'br') {                          return { type: 'line-break', children: [{ text: '' }] };                      }                      if (tagName === 'p') {                          let children = Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                          if (children.length === 0) children.push({ text: "" });                          return { type: 'paragraph', children };                      }                      if (tagName === 'strong' || tagName === 'b') {                          const newMarks = { ...marks, bold: true };                          return Array.from(node.childNodes).map(child => parseNode(child, newMarks)).flat().filter(Boolean);                      }                      if (tagName === 'em' || tagName === 'i') {                          const newMarks = { ...marks, italic: true };                          return Array.from(node.childNodes).map(child => parseNode(child, newMarks)).flat().filter(Boolean);                      }                      if (tagName === 'a') {                          const href = node.getAttribute('href') || '';                          let children = Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                          if (children.length === 0) children.push({ text: "" });                          return {                              type: 'link',                              url: href,                              isNoFollow: (node.getAttribute('rel') || '').includes('nofollow'),                              isSponsored: (node.getAttribute('rel') || '').includes('sponsored'),                              isOpenNewTab: node.getAttribute('target') === '_blank',                              isPreventDataRewrite: false,                              children: children                          };                      }                      return Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                  }                  return null;              }                            let blocksArray = [];              let currentParagraphChildren = [];              function flushParagraph() {                  if (currentParagraphChildren.length > 0) {                      blocksArray.push({ type: 'paragraph', children: currentParagraphChildren });                      currentParagraphChildren = [];                  }              }              Array.from(doc.body.childNodes).forEach(node => {                  const parsed = parseNode(node, {});                  const parsedItems = Array.isArray(parsed) ? parsed : (parsed ? [parsed] : []);                  parsedItems.forEach(item => {                      if (item.type === 'paragraph') {                          flushParagraph();                          blocksArray.push(item);                      } else {                          currentParagraphChildren.push(item);                      }                  });              });              flushParagraph();              if (blocksArray.length === 0) {                  blocksArray = [{ type: 'paragraph', children: [{ text: '' }] }];              }              return blocksArray;           }           const blocks = [];                      this.editorCopyBtn.innerHTML = '\x3Cspan class="tg-df-coupon-spinner" style="display:inline-block; margin-right:8px; border-top-color:#fff;">' + '<' + '/span> Copying...';           for (const deal of Array.from(this.selectedDeals.values())) {              const url = deal.url;              const merchant = deal.merchant;              const title = deal.title;              const image = deal.image;              const currentPrice = deal.currency + deal.rawPrice;              const wasPrice = deal.hasWasPrice && deal.rawMsrp > deal.rawPrice ? deal.currency + deal.rawMsrp : '';                            let couponsChildren = [];              try {                  const area = this.getAreaCode();                  const apiUrl = new URL('https://search-api.fie.future.net.uk/widget.php');                  apiUrl.searchParams.append('model_name', 'Everything');                  apiUrl.searchParams.append('language', 'en-GB');                  apiUrl.searchParams.append('area', area);                  apiUrl.searchParams.append('combine_product_types', '1');                  apiUrl.searchParams.append('filter_merchant_name', merchant);                  apiUrl.searchParams.append('all_filters', 'false');                  apiUrl.searchParams.append('exclude_unlabelled', 'false');                  apiUrl.searchParams.append('include_specs', 'false');                  apiUrl.searchParams.append('sort', 'voucher');                  apiUrl.searchParams.append('distinct_merchants', 'natural');                  apiUrl.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');                  apiUrl.searchParams.append('rows', '3');                  apiUrl.searchParams.append('origin', 'widgets-clientside');                                    let res; try { res = await fetch(apiUrl.toString()); } catch (e) { return; }                  if (res.ok) {                      const data = await res.json();                      let offers = [];                      if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {                        offers = data.widget.data.offers;                      } else if (data && data.data && Array.isArray(data.data.offers)) {                        offers = data.data.offers;                      }                                            if (offers.length > 0) {                          couponsChildren.push({ text: "Also check out these coupons: ", bold: true });                          offers.slice(0, 3).forEach((offer, idx) => {                              const actualOffer = offer.offer || offer;                              const offerName = actualOffer.name || actualOffer.title || offer.model_name || offer.title || offer.name || 'Coupon';                              const linkUrl = actualOffer.link || actualOffer.url || actualOffer.offer_link || '#';                              couponsChildren.push({ type: "line-break", children: [{ text: "" }] });                              couponsChildren.push({ text: "🎟️ " });                              couponsChildren.push({                                  type: "link",                                  url: linkUrl,                                  isNoFollow: true,                                  isSponsored: false,                                  isOpenNewTab: true,                                  isPreventDataRewrite: false,                                  children: [{ text: offerName, bold: true }]                              });                          });                      }                  }              } catch (err) {                  console.warn('Failed to fetch coupons for', merchant, err);              }              let descriptionValue = [];              if (deal.text) {                 descriptionValue = htmlToSlate(deal.text);              } else {                 const dealDescriptions = [                   `Don't miss out on this fantastic deal for the ${title}. It is currently available at ${merchant} for a highly competitive price.`,                   `We've spotted an excellent price drop on the ${title}. Grab it now at ${merchant} before it's gone.`,                   `The ${title} is currently seeing a generous discount over at ${merchant}. This is a perfect time to buy if you've been holding out.`,                   `If you're in the market for the ${title}, ${merchant} has just the deal for you.`,                   `Score the ${title} for less at ${merchant} right now. This is a rare chance to save big.`,                   `Upgrade your setup with the ${title}, now available at a stellar price via ${merchant}.`                 ];                 const randomDescription = dealDescriptions[Math.floor(Math.random() * dealDescriptions.length)];                 descriptionValue = [                    { type: "paragraph", children: [{ text: randomDescription }] }                 ];              }                            if (couponsChildren.length > 0) {                 let lastBlock = descriptionValue[descriptionValue.length - 1];                 if (lastBlock && lastBlock.type === 'paragraph') {                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children.push({ text: "Also check out these coupons: ", bold: true });                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children = lastBlock.children.concat(couponsChildren);                 } else {                     descriptionValue.push({                         type: "paragraph",                         children: [                             { type: "line-break", children: [{ text: "" }] },                             { type: "line-break", children: [{ text: "" }] },                             { text: "Also check out these coupons: ", bold: true },                             { type: "line-break", children: [{ text: "" }] },                             ...couponsChildren                         ]                     });                 }              }              function normalizeCurrencyToISO(symbol) {                const map = { '£': 'GBP', '$': 'USD', 'A$': 'AUD', 'CA$': 'CAD', '€': 'EUR' };                return map[symbol] || symbol;              }              const isoCurrency = normalizeCurrencyToISO(deal.currency);              blocks.push({                 id: (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : 'cms-' + Date.now() + Math.random(),                 blockTypeName: "deal",                 excludeFrom: [],                 collapsible: false,                 props: {                    description: {                       value: descriptionValue,                       touched: false,                       validationMessage: ""                    },                    image: {                       value: {                          credit: [{ type: "paragraph", children: [{ text: merchant }] }],                          dateCreated: Date.now(),                          dateModified: Date.now(),                          distribution: [],                          fileSize: 0,                          height: 1000,                          id: deal.id,                          imageRights: "",                          src: image,                          name: title + ".jpg",                          tags: [],                          width: 1000                       },                       touched: false,                       validationMessage: ""                    },                    showDealButton: { value: true, touched: false, validationMessage: "" },                    isPreferredPartner: { value: false, touched: false, validationMessage: "" },                    linkHref: { value: url, touched: false, validationMessage: "" },                    linkLabel: { value: "", touched: false, validationMessage: "" },                    linkIsNoFollow: { value: true, touched: false, validationMessage: "" },                    linkIsSponsored: { value: false, touched: false, validationMessage: "" },                    linkIsOpenNewWindow: { value: true, touched: false, validationMessage: "" },                    customPromoFlags: { value: [], touched: false, validationMessage: "" },                    showStarDeal: { value: false, touched: false, validationMessage: "" },                    savingType: { value: "none", touched: false, validationMessage: "" },                    starDealPromoFlag: { value: "", touched: false, validationMessage: "" },                    showEditorsChoice: { value: false, touched: false, validationMessage: "" },                    editorsChoiceTitle: { value: "", touched: false, validationMessage: "" },                    hawkPriceCurrency: { value: { value: isoCurrency, label: isoCurrency }, touched: false, validationMessage: "" },                    hawkPrice: { value: deal.hasWasPrice ? String(deal.rawMsrp) : String(deal.rawPrice), touched: false, validationMessage: "" },                    hawkSalePrice: { value: String(deal.rawPrice), touched: false, validationMessage: "" },                    lastCheckedPriceDate: { value: "", touched: false, validationMessage: "" },                    hawkModel: { touched: false, validationMessage: "" },                    productId: { value: "", touched: false, validationMessage: "" },                    voucherId: { value: "", touched: false, validationMessage: "" },                    brand: { value: deal.brand || merchant, touched: false, validationMessage: "" },                    productName: { value: title, touched: false, validationMessage: "" },                    label: { value: "", touched: false, validationMessage: "" },                    retailer: { value: merchant, touched: false, validationMessage: "" },                    priceCheckError: false                 },                 failedFetchError: ""              });           }           const payload = {              type: "articleBuilderPages",              data: blocks           };           const jsonStr = JSON.stringify(payload);                      if (navigator.clipboard && navigator.clipboard.writeText) {              navigator.clipboard.writeText(jsonStr).then(() => {                 this.editorCopyBtn.innerHTML = 'Copied!';                 setTimeout(() => {                    this.editorCopyBtn.innerHTML = '\x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2"><' + '/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"><' + '/path><' + '/svg> Copy to CMS';                 }, 2000);              }).catch(err => {                 console.warn('Failed to copy text: ', err);                 alert('Failed to copy deals to clipboard. See console.');              });           } else {              // Fallback              const textArea = document.createElement("textarea");              textArea.value = jsonStr;              document.body.appendChild(textArea);              textArea.focus();              textArea.select();              try {                 document.execCommand('copy');                 this.editorCopyBtn.innerHTML = 'Copied!';                 setTimeout(() => {                    this.editorCopyBtn.innerHTML = '\x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2"><' + '/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"><' + '/path><' + '/svg> Copy to CMS';                 }, 2000);              } catch (err) {                 console.warn('Fallback: Oops, unable to copy', err);                 alert('Fallback: Failed to copy deals to clipboard.');              }              document.body.removeChild(textArea);           }        }      }      // Initialize the Widget      if (document.readyState === 'loading') {        document.addEventListener('DOMContentLoaded', () => new DealsFinderWidget({ rootId: 'signal-deals-finder-root', rootNode: shadowRoot, hostContainer: hostContainer }));      } else {        new DealsFinderWidget({ rootId: 'signal-deals-finder-root', rootNode: shadowRoot, hostContainer: hostContainer });      }    })();  </script></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I put the iPhone 18 Pro Max vs. iPhone 17 Pro Max through a 7-round face-off — here’s the winner ]]></title>
                                                                                                <dc:content><![CDATA[ <p>If there’s one phone I saw out in the wild more than any other this past year, it was easily the Cosmic Orange <a href="https://www.tomsguide.com/phones/iphones/iphone-17-pro-max-review">iPhone 17 Pro Max</a>. As tempting as it is to credit that eye-catching finish alone, Apple backed up the fresh coat of paint with substantial hardware improvements and top-tier performance that drove people to buy it .</p><p>Now that the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max</a> is officially here, Apple has to convince those same owners that it’s time to move on. While my general rule of thumb is to <a href="https://www.tomsguide.com/phones/ive-been-reviewing-phones-for-almost-18-years-heres-my-advice-on-when-to-upgrade-your-phone">upgrade every three years</a>, the pull of the latest flagship is hard to resist.</p><p>That sets the stage for my iPhone 18 Pro Max vs. iPhone 17 Pro Max face-off: can Apple prove its newest generational leap is actually worth the investment? Armed with the cutting-edge <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen">A20 Pro chip</a> and an ambitious variable-aperture camera, the 18 Pro Max enters the ring with serious firepower. Here’s how it holds up against the reigning heavyweight.</p><div class="youtube-video" data-nosnippet ><div class="video-aspect-box"><iframe data-lazy-priority="low" data-lazy-src="https://www.youtube-nocookie.com/embed/sqaV5mFJav8" allowfullscreen></iframe></div></div><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-17-pro-max-specifications"><span>iPhone 18 Pro Max vs. iPhone 17 Pro Max: Specifications</span></h2><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>iPhone 18 Pro Max</strong></p></th><th  ><p><strong>iPhone 17 Pro Max</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p>From $1,299</p></td><td  ><p>From $1,199*</p></td></tr><tr><td class="firstcol " ><p><strong>Main Display</strong></p></td><td  ><p>6.9-inch Super Retina XDR display (2,868 x 1,320)</p></td><td  ><p>6.9-inch Super Retina XDR display (2,868 x 1,320)</p></td></tr><tr><td class="firstcol " ><p><strong>Refresh Rate</strong></p></td><td  ><p>1-120Hz ProMotion</p></td><td  ><p>1-120Hz ProMotion</p></td></tr><tr><td class="firstcol " ><p><strong>Processor</strong></p></td><td  ><p>A20 Pro</p></td><td  ><p>A19 Pro</p></td></tr><tr><td class="firstcol " ><p><strong>Storage</strong></p></td><td  ><p>256GB, 512GB, 1TB, 2TB</p></td><td  ><p>256GB, 512GB, 1TB, 2TB</p></td></tr><tr><td class="firstcol " ><p><strong>RAM</strong></p></td><td  ><p>12GB</p></td><td  ><p>12GB</p></td></tr><tr><td class="firstcol " ><p><strong>Front Camera</strong></p></td><td  ><p>18MP Center Stage camera (f/1.9)</p></td><td  ><p>18MP Center Stage camera (f/1.9)</p></td></tr><tr><td class="firstcol " ><p><strong>Rear Cameras</strong></p></td><td  ><p>48MP main with variable aperture (f/1.48, f/1.8, f/2.8, f/4), 48MP ultrawide (f/2.2), 48MP telephoto w/4x optical zoom (f/2.8)</p></td><td  ><p>48MP main (f/1.78), 48MP ultrawide (f/2.2), 48MP telephoto w/4x optical zoom (f/2.8)</p></td></tr><tr><td class="firstcol " ><p><strong>Battery Capacity</strong></p></td><td  ><p>5,391 mAh </p></td><td  ><p>5,088 mAh</p></td></tr><tr><td class="firstcol " ><p><strong>Charging</strong></p></td><td  ><p>60W wired, 25W wireless</p></td><td  ><p>40W wired, 25W wireless</p></td></tr><tr><td class="firstcol " ><p><strong>Size</strong></p></td><td  ><p>6.43 x 3.07 x 0.34 inches (163.4 x 78.0 x 8.75 mm)</p></td><td  ><p>6.43 x 3.07 x 0.35 inches (163.4 x 78 x 8.8 mm)</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>8.78 ounces (249 grams)</p></td><td  ><p>8.22 ounces (233 grams)</p></td></tr><tr><td class="firstcol " ><p><strong>IP Rating</strong></p></td><td  ><p>IP68</p></td><td  ><p>IP68</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Black, Silver, Glacier, Burgundy</p></td><td  ><p>Silver, Cosmic Orange, Deep Blue</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-17-pro-max-price-and-release"><span>iPhone 18 Pro Max vs. iPhone 17 Pro Max: Price and release</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="UrtN4rcYxsudaToz4wdk7A" name="iPhone 18 Pro Max vs. iPhone 17 Pro Max" alt="iPhone 18 Pro Max vs. iPhone 17 Pro Max." src="https://cdn.mos.cms.futurecdn.net/UrtN4rcYxsudaToz4wdk7A-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>When it comes to your wallet, the older flagship came with an initial starting price of $1,199 when it was released last year. With the latest flagship now on shelf,  Apple's asking $100 more for the the iPhone 18 Pro Max — pushing its starting price up to $1,299.</p><p>While the iPhone 18 Pro Max certainly brings cutting-edge upgrades to the table, an extra hundred dollars is a tough pill to swallow when last year's top-tier phone offers 90% of the same experience. For raw value and affordability out of the gate, the older model takes the crown, especially with the extra discounts you're likely to find right now as carriers and retailers try to clear out remaining stock.</p><p><strong>Winner:</strong> iPhone 17 Pro Max</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-17-pro-max-design"><span>iPhone 18 Pro Max vs. iPhone 17 Pro Max: Design</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="p6N8kMeftmXvZEAopXNk5A" name="iPhone 18 Pro Max vs. iPhone 17 Pro Max" alt="iPhone 18 Pro Max vs. iPhone 17 Pro Max." src="https://cdn.mos.cms.futurecdn.net/p6N8kMeftmXvZEAopXNk5A-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Besides their colorways, it’s nearly impossible to tell them apart at a cursory glance. That’s because Apple sticks to the same design, featuring an identical titanium frame, contoured edges, and the familiar stretched-out camera arrangement across the back. While Apple has gone after a unified color scheme with the iPhone 18 Pro Max, I still like the two-tone look of the previous design.</p><p>When I pick them up, however, I notice a subtle difference. By no means is the iPhone 17 Pro Max lightweight, but the iPhone 18 Pro Max feels noticeably denser in the hand because it tips the scales at a heftier 8.78 ounces — compared to the 8.22-ounce iPhone 17 Pro Max. It’s not a massive differential on paper, but it’s still immediately felt.</p><p>Besides that, I think it’s worth pointing out how Apple has trimmed the size of the Dynamic Island with the iPhone 18 Pro Max. It was never a distraction for me with the iPhone 17 Pro Max, but I nonetheless appreciate it being scaled down to make the display look more seamless.</p><p>Sure, it weighs more, but the slimmed-down Dynamic Island compensates for the 18 Pro Max’s overall design.</p><p><strong>Winner:</strong> tie</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-17-pro-max-display"><span>iPhone 18 Pro Max vs. iPhone 17 Pro Max: Display</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="jCxedQBPXdNUpp6XukTk8A" name="iPhone 18 Pro Max vs. iPhone 17 Pro Max" alt="iPhone 18 Pro Max vs. iPhone 17 Pro Max." src="https://cdn.mos.cms.futurecdn.net/jCxedQBPXdNUpp6XukTk8A-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Both phones feature a 6.9-inch Super Retina XDR display, complete with 120Hz ProMotion that makes nearly everything on the screen look buttery smooth. Our lab testing reveals that the iPhone 18 Pro Max reaches a much more substantial peak brightness of 2,326 nits, making it a breeze to see whatever I’m doing when the sun is beating down on me. </p><p>While the iPhone 17 Pro Max’s peak of 1,899 nits is no slouch, the difference side by side is obvious — with the 18 Pro Max exhibiting superior visibility when I need it most.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>iPhone 18 Pro Max</strong></p></th><th  ><p><strong>iPhone 17 Pro Max</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Peak Brightness (nits)</strong></p></td><td  ><p>2,326 nits</p></td><td  ><p>1,899 nits</p></td></tr><tr><td class="firstcol " ><p><strong>Delta-E</strong></p></td><td  ><p>0.26</p></td><td  ><p>0.26</p></td></tr><tr><td class="firstcol " ><p><strong>sRGB</strong></p></td><td  ><p>115.4%</p></td><td  ><p>109.6%</p></td></tr><tr><td class="firstcol " ><p><strong>DCI-P3</strong></p></td><td  ><p>81.8%</p></td><td  ><p>77.6%</p></td></tr></tbody></table></div><p>Apple also touts an updated anti-reflective coating on the iPhone 18 Pro Max, but in my experience, it’s an enhancement I hardly notice. Harsh overhead lights and reflections still pose a challenge.</p><p><strong>Winner:</strong> iPhone 18 Pro Max</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-17-pro-max-cameras"><span>iPhone 18 Pro Max vs. iPhone 17 Pro Max: Cameras</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="KCak3K8bbaCWkWKyyULcy9" name="iPhone 18 Pro Max vs. iPhone 17 Pro Max" alt="iPhone 18 Pro Max vs. iPhone 17 Pro Max." src="https://cdn.mos.cms.futurecdn.net/KCak3K8bbaCWkWKyyULcy9-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Apple has long set the gold standard for reliable point-and-shoot smartphone photography in virtually any condition. At a glance, both flagships seem to share the same 48MP triple-camera array, but the iPhone 18 Pro Max introduces two transformative upgrades: a mechanical variable aperture and native Pro Controls.</p><p>This variable aperture represents one of the most substantial hardware evolutions the iPhone line has seen in years, cycling through four distinct physical stops: f/1.48, f/1.8, f/2.8, and f/4. As an avid photographer, I know just how significant optical control is on mobile hardware — it grants the 18 Pro Max an immediate edge in capturing natural depth of field and managing light.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/SGfp5XiUJsGDo2kUU43cob-1920-80.jpg" alt="iPhone 18 Pro Max aperture f/4.0" /><figcaption>iPhone 18 Pro Max - Aperture f/4.0<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/QVLjmGvb9JGFx8FxZ8ByVb-1920-80.jpg" alt="iPhone 18 Pro Max aperture f/1.8" /><figcaption>iPhone 18 Pro Max - Aperture f/1.8<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>Better yet, Apple backed up the optical hardware overhaul with native Pro Controls. Enthusiasts have spent years pleading for true manual tools baked directly into iOS's default camera app, and Apple finally answered the call. The 18 Pro Max puts granular adjustment of shutter speed, ISO, white balance, manual focus, and aperture right at your fingertips.</p><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="xYUhv3BRpwmvxD8MCUR8uB" name="iPhone 18 Pro Max camera" alt="iPhone 18 Pro Max camera." src="https://cdn.mos.cms.futurecdn.net/xYUhv3BRpwmvxD8MCUR8uB-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>The iPhone 17 Pro Max remains an effortless, dependable shooter that produces gorgeous results with zero fuss. But the synergy of a true mechanical aperture and extensive manual shooting tools turns the iPhone 18 Pro Max into a legitimate photographer’s tool, delivering creative versatility its predecessor simply can't touch.</p><iframe allow="" height="338" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=c637884e-b695-11f1-ba1b-0e6f42328d7d"></iframe><p>Starting with their main cameras, it’s a dead heat between the two — and I genuinely can’t see a meaningful difference under daytime settings like this. Both flagships capture exceptional detail in the signage, pumpkins, and clouds in sky, with only a trained eye spotting that the iPhone 18 Pro Max lifts the deepest shadows beneath the awning just a hair more.</p><iframe allow="" height="338" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=397427f4-b696-11f1-ba1b-0e6f42328d7d"></iframe><p>These ultrawide camera shots again show how similarly both phones handle daytime scenes. From the rich blue water and rolling cloud formations to finer details like the sand patterns and docked rowboats, dynamic range and sharpness look nearly identical side by side.</p><iframe allow="" height="338" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=f679871e-b695-11f1-ba1b-0e6f42328d7d"></iframe><p>I’ve shown earlier how the physical variable aperture of the iPhone 18 Pro Max produces a more authentic background blur in standard shooting, but that hardware perk matters very little in Portrait Mode since both handsets lean entirely on computational photography. They perform almost identically, isolating my colleague Mark cleanly along the shoulders, with matching skin tones, exposure levels, and edge-detection accuracy.</p><iframe allow="" height="338" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=0ee709e8-b696-11f1-ba1b-0e6f42328d7d"></iframe><p>Switching over to their front-facing Center Stage cameras, the selfies reveal another remarkably close face-off. However, the iPhone 18 Pro Max pulls ahead with slightly cleaner dynamic range, warmer skin tones, and clearer facial detail.</p><iframe allow="" height="338" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=78cfc69c-b696-11f1-ba1b-0e6f42328d7d"></iframe><p>At 4x zoom, both flagships capture the rowboats with nearly identical clarity — it’s really hard to tell them apart.</p><iframe allow="" height="338" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=b5a1e05a-b696-11f1-ba1b-0e6f42328d7d"></iframe><p>Pushing them to 40x zoom, however, reveals the iPhone 18 Pro Max's superior processing. It keeps the phone number's stenciled lettering crisp and legible with noticeably less artifacting. The iPhone 17 Pro Max still manages to keep the text readable, but fine details begin to soften.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/CFsD5vQxyFQHPAaDgUF4YX-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">Future</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/63KcWxvwCtpr3n7FyNMMrS-1920-80.jpg" alt="Apple iPhone 17 Pro Max camera sample." /><figcaption>iPhone 17 Pro Max.<small role="credit">Future</small></figcaption></figure></figure><p>Low-light performance leans in favor of the iPhone 18 Pro Max, largely because its wider f/1.48 aperture takes in more light without needing to artificially brighten the entire room. The iPhone 17 Pro Max pushes exposure a bit too far, resulting in blown-out candle highlights along the mantel and a washed-out wall that loses the moody ambiance of the scene.</p><p>That wider aperture also allows the iPhone 18 Pro Max to capture the scene at ISO 1600, resulting in noticeably less noise and grain than the iPhone 17 Pro Max at ISO 2000.</p><p><strong>Winner:</strong> iPhone 18 Pro Max</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-17-pro-max-performance"><span>iPhone 18 Pro Max vs. iPhone 17 Pro Max: 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:2321px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="36uFQPaegizL2WM4jr82pH" name="iPhone 18 Pro and Pro Max-18" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/36uFQPaegizL2WM4jr82pH-1920-80.jpg" mos="" align="middle" fullscreen="" width="2321" height="1306" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>While last year’s A19 Pro was already a beast on its own, Apple widens the gap significantly with the new 2nm-class A20 Pro silicon powering the iPhone 18 Pro Max. Synthetic benchmark tests reveal this in a substantial way, with the iPhone 18 Pro Max churning out Geekbench scores that blow away its predecessor.</p><p>Its 4,741 single-core and 12,789 multi-core scores beat the 17 Pro Max by a wide margin (3,871 and 9,968). Essentially, this translates to roughly a 22% performance increase in single-core and an even better 28% jump in multi-core. The newer Geekbench 7 test tells a similar story.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Geekbench 6 (single/multi-core)</strong></p></th><th  ><p><strong>Geekbench 7</strong></p></th><th  ><p><strong>3DMark Solar Bay Unlimited</strong></p></th><th  ><p><strong>Geekbench AI 1.7</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>iPhone 18 Pro Max</strong></p></td><td  ><p>4,741 / 12,789</p></td><td  ><p>4,025 / 11,525</p></td><td  ><p>67.9 fps/17,850</p></td><td  ><p>71974</p></td></tr><tr><td class="firstcol " ><p><strong>iPhone 17 Pro Max</strong></p></td><td  ><p>3,871 / 9,968</p></td><td  ><p>3,285 / 8,999</p></td><td  ><p>46.6 fps / 12,260</p></td><td  ><p>48549 </p></td></tr></tbody></table></div><p>Graphics processing also sees marked improvements for the iPhone 18 Pro Max, showing an even greater divide that could be attributed to its larger, redesigned vapor chamber. In 3DMark’s Solar Bay Unlimited test, the 18 Pro Max hits an impressive 67.9 fps average (17,850 score) — which represents a massive 45% leap over the iPhone 17 Pro Max’s 46.6 fps average (12,260 score).</p><p>Those benchmark numbers look great on paper, but synthetic results don’t always tell the whole story. Personally, I’ve enjoyed playing my go-to games on my iPhone 17 Pro Max — but the iPhone 18 Pro Max simply makes them look and run way better with more fluid animations and tighter, more responsive gameplay.</p><p><strong>Winner:</strong> iPhone 18 Pro Max</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-17-pro-max-battery-life-and-charging"><span>iPhone 18 Pro Max vs. iPhone 17 Pro Max: Battery Life and charging</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="S8VCNwUf4CeCFFtLAWtVmK" name="iPhone 18 Pro and Pro Max-8" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/S8VCNwUf4CeCFFtLAWtVmK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The iPhone 17 Pro Max was already an absolute endurance beast, setting an exceptionally high bar. Yet, the iPhone 18 Pro Max manages to stretch that lead even further — although I was expecting a bit more.</p><p>In the Tom’s Guide battery drain test — which involves continuous web surfing over 5G with the display calibrated to 150 nits — the iPhone 18 Pro Max turns in an average time of 18 hours and 27 minutes. That stretches out to 18 hours and 41 minutes on its longest run. This average eclipses the iPhone 17 Pro Max’s time of 17 hours and 54 minutes. In real-world terms, both are reliable two-day phones, but the 18 Pro Max gives you that extra cushion of reassurance.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>iPhone 18 Pro Max </strong></p></th><th  ><p><strong>iPhone 17 Pro Max </strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Battery Size</strong></p></td><td  ><p>5,391 mAh </p></td><td  ><p>5,088 mAh</p></td></tr><tr><td class="firstcol " ><p><strong>Battery Life (hours:minutes)</strong></p></td><td  ><p>18:27</p></td><td  ><p>17:54</p></td></tr><tr><td class="firstcol " ><p><strong>Charging level in 15 minutes</strong></p></td><td  ><p>44%</p></td><td  ><p>35%</p></td></tr><tr><td class="firstcol " ><p><strong>Charging level in 30 minutes</strong></p></td><td  ><p>77%</p></td><td  ><p>64%</p></td></tr></tbody></table></div><p>Where the newer flagship truly pulls away, however, is charging speed. Apple finally upgraded the iPhone 18 Pro Max with 60W charging support for the first time. The payoff is immediate: the iPhone 18 Pro Max rockets to 44% in 15 minutes and 77% in 30 minutes, easily besting the iPhone 17 Pro Max’s slower 35% and 64% fill-ups at the same intervals.</p><p><strong>Winner:</strong> iPhone 18 Pro Max</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-17-pro-max-software-and-ai"><span>iPhone 18 Pro Max vs. iPhone 17 Pro Max: Software and AI</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="UHFLgbZkizWAuzbea6ATRH" name="iPhone 18 Pro and Pro Max" alt="Siri AI on an iPhone 18 Pro" src="https://cdn.mos.cms.futurecdn.net/UHFLgbZkizWAuzbea6ATRH-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Both flagships run the latest iOS 27 software, so the experience is virtually identical with a couple of exceptions. Visually, you get the same level of customization with the interface — complete with <a href="https://www.tomsguide.com/phones/iphones/ios-27-has-a-hidden-liquid-glass-slider-here-is-how-to-find-and-use-it">control over Liquid Glass’ look</a>, icon arrangement, and lock screen personalization. At the same time, both phones offer identical Apple Intelligence tools like <a href="https://www.tomsguide.com/phones/i-tried-ios-27-clean-up-vs-galaxy-ai-photo-assist-in-a-7-round-test-and-i-was-surprised-with-how-close-it-was">Clean Up</a>, notification summaries, Writing Tools, <a href="https://www.tomsguide.com/phones/iphones/i-just-installed-the-ios-27-beta-and-reframe-is-unlike-any-other-ai-feature-ive-come-across">Reframe</a>, and more.</p><p>One of the biggest driving forces that comes with these titans is the arrival of <a href="https://www.tomsguide.com/phones/iphones/i-spent-a-week-with-siri-ai-here-are-my-honest-pros-and-cons">Siri AI</a>, which works identically on both models. This turbocharged version of Apple’s virtual assistant is more proactive and aware, offering contextual responses based on whatever you’re doing — like suggesting a calendar event if someone mentions an upcoming appointment in Messages. I’ve also tested out <a href="https://www.tomsguide.com/phones/iphones/i-just-tried-siri-ai-in-the-ios-27-carplay-beta-and-this-assistant-is-way-more-helpful-than-before">Siri AI with the new CarPlay in iOS 27</a>, and I can say that it’s way more reliable at handling multi-step tasks.</p><p>However, the iPhone 18 Pro Max pulls away with a couple of standout exclusive features. I’ve already pointed out the slimmer Dynamic Island, which takes advantage of the redesigned cutout to monitor three simultaneous Live Activities at once — compared to the two-activity limit on the iPhone 17 Pro Max. Secondly, the 18 Pro Max exclusively packs native Pro Controls into the camera app, something Apple simply doesn’t include with the updated iOS 27 experience on the 17 Pro Max.</p><p><strong>Winner:</strong> iPhone 18 Pro Max</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-17-pro-max-verdict"><span>iPhone 18 Pro Max vs. iPhone 17 Pro Max: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="FDJ2VgTWRJ4st6bGiL5nh9" name="iPhone 18 Pro Max vs. iPhone 17 Pro Max" alt="iPhone 18 Pro Max vs. iPhone 17 Pro Max." src="https://cdn.mos.cms.futurecdn.net/FDJ2VgTWRJ4st6bGiL5nh9-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Apple didn’t just deliver a routine refresh with the iPhone 18 Pro Max — it pushed the envelope where it matters most. Pairing the physical variable aperture with native Pro Controls transforms the camera into a creative setup that could happily replace my point-and-shoot camera. Backed by the blistering performance of the A20 Pro silicon, a much brighter display, faster 60W charging, and class-leading battery endurance, the iPhone 18 Pro Max handily wins this matchup.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>iPhone 18 Pro Max</strong></p></th><th  ><p><strong>iPhone 17 Pro Max</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ></td><td  ><p>X</p></td></tr><tr><td class="firstcol " ><p><strong>Design</strong></p></td><td  ><p>X</p></td><td  ><p>X</p></td></tr><tr><td class="firstcol " ><p><strong>Display</strong></p></td><td  ><p>X</p></td><td  ></td></tr><tr><td class="firstcol " ><p><strong>Cameras</strong></p></td><td  ><p>X</p></td><td  ></td></tr><tr><td class="firstcol " ><p><strong>Performance</strong></p></td><td  ><p>X</p></td><td  ></td></tr><tr><td class="firstcol " ><p><strong>Battery Life</strong></p></td><td  ><p>X</p></td><td  ></td></tr><tr><td class="firstcol " ><p><strong>Software</strong></p></td><td  ><p>X</p></td><td  ></td></tr><tr><td class="firstcol " ><p><strong>Total</strong></p></td><td  ><p>6</p></td><td  ><p>2</p></td></tr></tbody></table></div><p>That said, if you already own an iPhone 17 Pro Max, you will find it hard to justify spending even more money — especially with Apple slapping a $100 price hike on the 18 Pro Max. Last year’s flagship still delivers phenomenal battery life, blazing-fast speed, and nearly the exact same iOS 27 and Siri AI software experience.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ODmljX"></div>                            </div>                            <script src="https://kwizly.com/embed/ODmljX.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom’s Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-iphone-18-pro-your-10-biggest-questions-answered"><strong>I've been testing the iPhone 18 Pro Max and iPhone 18 Pro — your 10 biggest questions answered</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-teardown-reveals-the-ins-and-outs-of-the-latest-iphone-models-including-one-annoying-repair-issue"><strong>iPhone 18 Pro teardown reveals the ins and outs of the latest iPhone models — including one annoying repair issue</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/apples-usd250-million-class-action-settlement-website-is-now-open-heres-how-eligible-iphone-owners-can-file-a-claim-and-how-much-theyll-get"><strong>Apple's $250 million class action settlement website is now open — here's how eligible iPhone owners can file a claim and how much they'll get</strong></a><strong></strong></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/i-put-the-iphone-18-pro-max-vs-iphone-17-pro-max-through-a-7-round-face-off-heres-the-winner</link>
                                                                            <description>
                            <![CDATA[ After testing out its flagships, there's a clear winner in the iPhone 18 Pro Max vs. iPhone 17 Pro Max debate as to which one is the better phone. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">3PrGpeCLVmva7JX6oCBm9h</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/FDJ2VgTWRJ4st6bGiL5nh9-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 23 Sep 2026 05:00:00 +0000</pubDate>                                                                                                                                <updated>Mon, 28 Sep 2026 13:31:26 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ john.velasco@futurenet.com (John Velasco) ]]></author>                    <dc:creator><![CDATA[ John Velasco ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/TSj224oX8d5ERXaDs8pDGd-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/FDJ2VgTWRJ4st6bGiL5nh9-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 18 Pro Max vs. iPhone 17 Pro Max.]]></media:description>                                                            <media:text><![CDATA[iPhone 18 Pro Max vs. iPhone 17 Pro Max.]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 18 Pro Max vs. iPhone 17 Pro Max.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/FDJ2VgTWRJ4st6bGiL5nh9-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>If there’s one phone I saw out in the wild more than any other this past year, it was easily the Cosmic Orange <a href="https://www.tomsguide.com/phones/iphones/iphone-17-pro-max-review">iPhone 17 Pro Max</a>. As tempting as it is to credit that eye-catching finish alone, Apple backed up the fresh coat of paint with substantial hardware improvements and top-tier performance that drove people to buy it .</p><p>Now that the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max</a> is officially here, Apple has to convince those same owners that it’s time to move on. While my general rule of thumb is to <a href="https://www.tomsguide.com/phones/ive-been-reviewing-phones-for-almost-18-years-heres-my-advice-on-when-to-upgrade-your-phone">upgrade every three years</a>, the pull of the latest flagship is hard to resist.</p><p>That sets the stage for my iPhone 18 Pro Max vs. iPhone 17 Pro Max face-off: can Apple prove its newest generational leap is actually worth the investment? Armed with the cutting-edge <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen">A20 Pro chip</a> and an ambitious variable-aperture camera, the 18 Pro Max enters the ring with serious firepower. Here’s how it holds up against the reigning heavyweight.</p><div class="youtube-video" data-nosnippet ><div class="video-aspect-box"><iframe data-lazy-priority="low" data-lazy-src="https://www.youtube-nocookie.com/embed/sqaV5mFJav8" allowfullscreen></iframe></div></div><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-17-pro-max-specifications"><span>iPhone 18 Pro Max vs. iPhone 17 Pro Max: Specifications</span></h2><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>iPhone 18 Pro Max</strong></p></th><th  ><p><strong>iPhone 17 Pro Max</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p>From $1,299</p></td><td  ><p>From $1,199*</p></td></tr><tr><td class="firstcol " ><p><strong>Main Display</strong></p></td><td  ><p>6.9-inch Super Retina XDR display (2,868 x 1,320)</p></td><td  ><p>6.9-inch Super Retina XDR display (2,868 x 1,320)</p></td></tr><tr><td class="firstcol " ><p><strong>Refresh Rate</strong></p></td><td  ><p>1-120Hz ProMotion</p></td><td  ><p>1-120Hz ProMotion</p></td></tr><tr><td class="firstcol " ><p><strong>Processor</strong></p></td><td  ><p>A20 Pro</p></td><td  ><p>A19 Pro</p></td></tr><tr><td class="firstcol " ><p><strong>Storage</strong></p></td><td  ><p>256GB, 512GB, 1TB, 2TB</p></td><td  ><p>256GB, 512GB, 1TB, 2TB</p></td></tr><tr><td class="firstcol " ><p><strong>RAM</strong></p></td><td  ><p>12GB</p></td><td  ><p>12GB</p></td></tr><tr><td class="firstcol " ><p><strong>Front Camera</strong></p></td><td  ><p>18MP Center Stage camera (f/1.9)</p></td><td  ><p>18MP Center Stage camera (f/1.9)</p></td></tr><tr><td class="firstcol " ><p><strong>Rear Cameras</strong></p></td><td  ><p>48MP main with variable aperture (f/1.48, f/1.8, f/2.8, f/4), 48MP ultrawide (f/2.2), 48MP telephoto w/4x optical zoom (f/2.8)</p></td><td  ><p>48MP main (f/1.78), 48MP ultrawide (f/2.2), 48MP telephoto w/4x optical zoom (f/2.8)</p></td></tr><tr><td class="firstcol " ><p><strong>Battery Capacity</strong></p></td><td  ><p>5,391 mAh </p></td><td  ><p>5,088 mAh</p></td></tr><tr><td class="firstcol " ><p><strong>Charging</strong></p></td><td  ><p>60W wired, 25W wireless</p></td><td  ><p>40W wired, 25W wireless</p></td></tr><tr><td class="firstcol " ><p><strong>Size</strong></p></td><td  ><p>6.43 x 3.07 x 0.34 inches (163.4 x 78.0 x 8.75 mm)</p></td><td  ><p>6.43 x 3.07 x 0.35 inches (163.4 x 78 x 8.8 mm)</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>8.78 ounces (249 grams)</p></td><td  ><p>8.22 ounces (233 grams)</p></td></tr><tr><td class="firstcol " ><p><strong>IP Rating</strong></p></td><td  ><p>IP68</p></td><td  ><p>IP68</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Black, Silver, Glacier, Burgundy</p></td><td  ><p>Silver, Cosmic Orange, Deep Blue</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-17-pro-max-price-and-release"><span>iPhone 18 Pro Max vs. iPhone 17 Pro Max: Price and release</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="UrtN4rcYxsudaToz4wdk7A" name="iPhone 18 Pro Max vs. iPhone 17 Pro Max" alt="iPhone 18 Pro Max vs. iPhone 17 Pro Max." src="https://cdn.mos.cms.futurecdn.net/UrtN4rcYxsudaToz4wdk7A-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>When it comes to your wallet, the older flagship came with an initial starting price of $1,199 when it was released last year. With the latest flagship now on shelf,  Apple's asking $100 more for the the iPhone 18 Pro Max — pushing its starting price up to $1,299.</p><p>While the iPhone 18 Pro Max certainly brings cutting-edge upgrades to the table, an extra hundred dollars is a tough pill to swallow when last year's top-tier phone offers 90% of the same experience. For raw value and affordability out of the gate, the older model takes the crown, especially with the extra discounts you're likely to find right now as carriers and retailers try to clear out remaining stock.</p><p><strong>Winner:</strong> iPhone 17 Pro Max</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-17-pro-max-design"><span>iPhone 18 Pro Max vs. iPhone 17 Pro Max: Design</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="p6N8kMeftmXvZEAopXNk5A" name="iPhone 18 Pro Max vs. iPhone 17 Pro Max" alt="iPhone 18 Pro Max vs. iPhone 17 Pro Max." src="https://cdn.mos.cms.futurecdn.net/p6N8kMeftmXvZEAopXNk5A-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Besides their colorways, it’s nearly impossible to tell them apart at a cursory glance. That’s because Apple sticks to the same design, featuring an identical titanium frame, contoured edges, and the familiar stretched-out camera arrangement across the back. While Apple has gone after a unified color scheme with the iPhone 18 Pro Max, I still like the two-tone look of the previous design.</p><p>When I pick them up, however, I notice a subtle difference. By no means is the iPhone 17 Pro Max lightweight, but the iPhone 18 Pro Max feels noticeably denser in the hand because it tips the scales at a heftier 8.78 ounces — compared to the 8.22-ounce iPhone 17 Pro Max. It’s not a massive differential on paper, but it’s still immediately felt.</p><p>Besides that, I think it’s worth pointing out how Apple has trimmed the size of the Dynamic Island with the iPhone 18 Pro Max. It was never a distraction for me with the iPhone 17 Pro Max, but I nonetheless appreciate it being scaled down to make the display look more seamless.</p><p>Sure, it weighs more, but the slimmed-down Dynamic Island compensates for the 18 Pro Max’s overall design.</p><p><strong>Winner:</strong> tie</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-17-pro-max-display"><span>iPhone 18 Pro Max vs. iPhone 17 Pro Max: Display</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="jCxedQBPXdNUpp6XukTk8A" name="iPhone 18 Pro Max vs. iPhone 17 Pro Max" alt="iPhone 18 Pro Max vs. iPhone 17 Pro Max." src="https://cdn.mos.cms.futurecdn.net/jCxedQBPXdNUpp6XukTk8A-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Both phones feature a 6.9-inch Super Retina XDR display, complete with 120Hz ProMotion that makes nearly everything on the screen look buttery smooth. Our lab testing reveals that the iPhone 18 Pro Max reaches a much more substantial peak brightness of 2,326 nits, making it a breeze to see whatever I’m doing when the sun is beating down on me. </p><p>While the iPhone 17 Pro Max’s peak of 1,899 nits is no slouch, the difference side by side is obvious — with the 18 Pro Max exhibiting superior visibility when I need it most.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>iPhone 18 Pro Max</strong></p></th><th  ><p><strong>iPhone 17 Pro Max</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Peak Brightness (nits)</strong></p></td><td  ><p>2,326 nits</p></td><td  ><p>1,899 nits</p></td></tr><tr><td class="firstcol " ><p><strong>Delta-E</strong></p></td><td  ><p>0.26</p></td><td  ><p>0.26</p></td></tr><tr><td class="firstcol " ><p><strong>sRGB</strong></p></td><td  ><p>115.4%</p></td><td  ><p>109.6%</p></td></tr><tr><td class="firstcol " ><p><strong>DCI-P3</strong></p></td><td  ><p>81.8%</p></td><td  ><p>77.6%</p></td></tr></tbody></table></div><p>Apple also touts an updated anti-reflective coating on the iPhone 18 Pro Max, but in my experience, it’s an enhancement I hardly notice. Harsh overhead lights and reflections still pose a challenge.</p><p><strong>Winner:</strong> iPhone 18 Pro Max</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-17-pro-max-cameras"><span>iPhone 18 Pro Max vs. iPhone 17 Pro Max: Cameras</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="KCak3K8bbaCWkWKyyULcy9" name="iPhone 18 Pro Max vs. iPhone 17 Pro Max" alt="iPhone 18 Pro Max vs. iPhone 17 Pro Max." src="https://cdn.mos.cms.futurecdn.net/KCak3K8bbaCWkWKyyULcy9-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Apple has long set the gold standard for reliable point-and-shoot smartphone photography in virtually any condition. At a glance, both flagships seem to share the same 48MP triple-camera array, but the iPhone 18 Pro Max introduces two transformative upgrades: a mechanical variable aperture and native Pro Controls.</p><p>This variable aperture represents one of the most substantial hardware evolutions the iPhone line has seen in years, cycling through four distinct physical stops: f/1.48, f/1.8, f/2.8, and f/4. As an avid photographer, I know just how significant optical control is on mobile hardware — it grants the 18 Pro Max an immediate edge in capturing natural depth of field and managing light.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/SGfp5XiUJsGDo2kUU43cob-1920-80.jpg" alt="iPhone 18 Pro Max aperture f/4.0" /><figcaption>iPhone 18 Pro Max - Aperture f/4.0<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/QVLjmGvb9JGFx8FxZ8ByVb-1920-80.jpg" alt="iPhone 18 Pro Max aperture f/1.8" /><figcaption>iPhone 18 Pro Max - Aperture f/1.8<small role="credit">Tom's Guide</small></figcaption></figure></figure><p>Better yet, Apple backed up the optical hardware overhaul with native Pro Controls. Enthusiasts have spent years pleading for true manual tools baked directly into iOS's default camera app, and Apple finally answered the call. The 18 Pro Max puts granular adjustment of shutter speed, ISO, white balance, manual focus, and aperture right at your fingertips.</p><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="xYUhv3BRpwmvxD8MCUR8uB" name="iPhone 18 Pro Max camera" alt="iPhone 18 Pro Max camera." src="https://cdn.mos.cms.futurecdn.net/xYUhv3BRpwmvxD8MCUR8uB-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>The iPhone 17 Pro Max remains an effortless, dependable shooter that produces gorgeous results with zero fuss. But the synergy of a true mechanical aperture and extensive manual shooting tools turns the iPhone 18 Pro Max into a legitimate photographer’s tool, delivering creative versatility its predecessor simply can't touch.</p><iframe allow="" height="338" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=c637884e-b695-11f1-ba1b-0e6f42328d7d"></iframe><p>Starting with their main cameras, it’s a dead heat between the two — and I genuinely can’t see a meaningful difference under daytime settings like this. Both flagships capture exceptional detail in the signage, pumpkins, and clouds in sky, with only a trained eye spotting that the iPhone 18 Pro Max lifts the deepest shadows beneath the awning just a hair more.</p><iframe allow="" height="338" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=397427f4-b696-11f1-ba1b-0e6f42328d7d"></iframe><p>These ultrawide camera shots again show how similarly both phones handle daytime scenes. From the rich blue water and rolling cloud formations to finer details like the sand patterns and docked rowboats, dynamic range and sharpness look nearly identical side by side.</p><iframe allow="" height="338" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=f679871e-b695-11f1-ba1b-0e6f42328d7d"></iframe><p>I’ve shown earlier how the physical variable aperture of the iPhone 18 Pro Max produces a more authentic background blur in standard shooting, but that hardware perk matters very little in Portrait Mode since both handsets lean entirely on computational photography. They perform almost identically, isolating my colleague Mark cleanly along the shoulders, with matching skin tones, exposure levels, and edge-detection accuracy.</p><iframe allow="" height="338" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=0ee709e8-b696-11f1-ba1b-0e6f42328d7d"></iframe><p>Switching over to their front-facing Center Stage cameras, the selfies reveal another remarkably close face-off. However, the iPhone 18 Pro Max pulls ahead with slightly cleaner dynamic range, warmer skin tones, and clearer facial detail.</p><iframe allow="" height="338" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=78cfc69c-b696-11f1-ba1b-0e6f42328d7d"></iframe><p>At 4x zoom, both flagships capture the rowboats with nearly identical clarity — it’s really hard to tell them apart.</p><iframe allow="" height="338" width="100%" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://cdn.knightlab.com/libs/juxtapose/latest/embed/index.html?uid=b5a1e05a-b696-11f1-ba1b-0e6f42328d7d"></iframe><p>Pushing them to 40x zoom, however, reveals the iPhone 18 Pro Max's superior processing. It keeps the phone number's stenciled lettering crisp and legible with noticeably less artifacting. The iPhone 17 Pro Max still manages to keep the text readable, but fine details begin to soften.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/CFsD5vQxyFQHPAaDgUF4YX-1920-80.jpg" alt="Apple iPhone 18 Pro Max camera sample." /><figcaption>iPhone 18 Pro Max.<small role="credit">Future</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/63KcWxvwCtpr3n7FyNMMrS-1920-80.jpg" alt="Apple iPhone 17 Pro Max camera sample." /><figcaption>iPhone 17 Pro Max.<small role="credit">Future</small></figcaption></figure></figure><p>Low-light performance leans in favor of the iPhone 18 Pro Max, largely because its wider f/1.48 aperture takes in more light without needing to artificially brighten the entire room. The iPhone 17 Pro Max pushes exposure a bit too far, resulting in blown-out candle highlights along the mantel and a washed-out wall that loses the moody ambiance of the scene.</p><p>That wider aperture also allows the iPhone 18 Pro Max to capture the scene at ISO 1600, resulting in noticeably less noise and grain than the iPhone 17 Pro Max at ISO 2000.</p><p><strong>Winner:</strong> iPhone 18 Pro Max</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-17-pro-max-performance"><span>iPhone 18 Pro Max vs. iPhone 17 Pro Max: 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:2321px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="36uFQPaegizL2WM4jr82pH" name="iPhone 18 Pro and Pro Max-18" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/36uFQPaegizL2WM4jr82pH-1920-80.jpg" mos="" align="middle" fullscreen="" width="2321" height="1306" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>While last year’s A19 Pro was already a beast on its own, Apple widens the gap significantly with the new 2nm-class A20 Pro silicon powering the iPhone 18 Pro Max. Synthetic benchmark tests reveal this in a substantial way, with the iPhone 18 Pro Max churning out Geekbench scores that blow away its predecessor.</p><p>Its 4,741 single-core and 12,789 multi-core scores beat the 17 Pro Max by a wide margin (3,871 and 9,968). Essentially, this translates to roughly a 22% performance increase in single-core and an even better 28% jump in multi-core. The newer Geekbench 7 test tells a similar story.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Geekbench 6 (single/multi-core)</strong></p></th><th  ><p><strong>Geekbench 7</strong></p></th><th  ><p><strong>3DMark Solar Bay Unlimited</strong></p></th><th  ><p><strong>Geekbench AI 1.7</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>iPhone 18 Pro Max</strong></p></td><td  ><p>4,741 / 12,789</p></td><td  ><p>4,025 / 11,525</p></td><td  ><p>67.9 fps/17,850</p></td><td  ><p>71974</p></td></tr><tr><td class="firstcol " ><p><strong>iPhone 17 Pro Max</strong></p></td><td  ><p>3,871 / 9,968</p></td><td  ><p>3,285 / 8,999</p></td><td  ><p>46.6 fps / 12,260</p></td><td  ><p>48549 </p></td></tr></tbody></table></div><p>Graphics processing also sees marked improvements for the iPhone 18 Pro Max, showing an even greater divide that could be attributed to its larger, redesigned vapor chamber. In 3DMark’s Solar Bay Unlimited test, the 18 Pro Max hits an impressive 67.9 fps average (17,850 score) — which represents a massive 45% leap over the iPhone 17 Pro Max’s 46.6 fps average (12,260 score).</p><p>Those benchmark numbers look great on paper, but synthetic results don’t always tell the whole story. Personally, I’ve enjoyed playing my go-to games on my iPhone 17 Pro Max — but the iPhone 18 Pro Max simply makes them look and run way better with more fluid animations and tighter, more responsive gameplay.</p><p><strong>Winner:</strong> iPhone 18 Pro Max</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-17-pro-max-battery-life-and-charging"><span>iPhone 18 Pro Max vs. iPhone 17 Pro Max: Battery Life and charging</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="S8VCNwUf4CeCFFtLAWtVmK" name="iPhone 18 Pro and Pro Max-8" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/S8VCNwUf4CeCFFtLAWtVmK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The iPhone 17 Pro Max was already an absolute endurance beast, setting an exceptionally high bar. Yet, the iPhone 18 Pro Max manages to stretch that lead even further — although I was expecting a bit more.</p><p>In the Tom’s Guide battery drain test — which involves continuous web surfing over 5G with the display calibrated to 150 nits — the iPhone 18 Pro Max turns in an average time of 18 hours and 27 minutes. That stretches out to 18 hours and 41 minutes on its longest run. This average eclipses the iPhone 17 Pro Max’s time of 17 hours and 54 minutes. In real-world terms, both are reliable two-day phones, but the 18 Pro Max gives you that extra cushion of reassurance.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>iPhone 18 Pro Max </strong></p></th><th  ><p><strong>iPhone 17 Pro Max </strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Battery Size</strong></p></td><td  ><p>5,391 mAh </p></td><td  ><p>5,088 mAh</p></td></tr><tr><td class="firstcol " ><p><strong>Battery Life (hours:minutes)</strong></p></td><td  ><p>18:27</p></td><td  ><p>17:54</p></td></tr><tr><td class="firstcol " ><p><strong>Charging level in 15 minutes</strong></p></td><td  ><p>44%</p></td><td  ><p>35%</p></td></tr><tr><td class="firstcol " ><p><strong>Charging level in 30 minutes</strong></p></td><td  ><p>77%</p></td><td  ><p>64%</p></td></tr></tbody></table></div><p>Where the newer flagship truly pulls away, however, is charging speed. Apple finally upgraded the iPhone 18 Pro Max with 60W charging support for the first time. The payoff is immediate: the iPhone 18 Pro Max rockets to 44% in 15 minutes and 77% in 30 minutes, easily besting the iPhone 17 Pro Max’s slower 35% and 64% fill-ups at the same intervals.</p><p><strong>Winner:</strong> iPhone 18 Pro Max</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-17-pro-max-software-and-ai"><span>iPhone 18 Pro Max vs. iPhone 17 Pro Max: Software and AI</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="UHFLgbZkizWAuzbea6ATRH" name="iPhone 18 Pro and Pro Max" alt="Siri AI on an iPhone 18 Pro" src="https://cdn.mos.cms.futurecdn.net/UHFLgbZkizWAuzbea6ATRH-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Both flagships run the latest iOS 27 software, so the experience is virtually identical with a couple of exceptions. Visually, you get the same level of customization with the interface — complete with <a href="https://www.tomsguide.com/phones/iphones/ios-27-has-a-hidden-liquid-glass-slider-here-is-how-to-find-and-use-it">control over Liquid Glass’ look</a>, icon arrangement, and lock screen personalization. At the same time, both phones offer identical Apple Intelligence tools like <a href="https://www.tomsguide.com/phones/i-tried-ios-27-clean-up-vs-galaxy-ai-photo-assist-in-a-7-round-test-and-i-was-surprised-with-how-close-it-was">Clean Up</a>, notification summaries, Writing Tools, <a href="https://www.tomsguide.com/phones/iphones/i-just-installed-the-ios-27-beta-and-reframe-is-unlike-any-other-ai-feature-ive-come-across">Reframe</a>, and more.</p><p>One of the biggest driving forces that comes with these titans is the arrival of <a href="https://www.tomsguide.com/phones/iphones/i-spent-a-week-with-siri-ai-here-are-my-honest-pros-and-cons">Siri AI</a>, which works identically on both models. This turbocharged version of Apple’s virtual assistant is more proactive and aware, offering contextual responses based on whatever you’re doing — like suggesting a calendar event if someone mentions an upcoming appointment in Messages. I’ve also tested out <a href="https://www.tomsguide.com/phones/iphones/i-just-tried-siri-ai-in-the-ios-27-carplay-beta-and-this-assistant-is-way-more-helpful-than-before">Siri AI with the new CarPlay in iOS 27</a>, and I can say that it’s way more reliable at handling multi-step tasks.</p><p>However, the iPhone 18 Pro Max pulls away with a couple of standout exclusive features. I’ve already pointed out the slimmer Dynamic Island, which takes advantage of the redesigned cutout to monitor three simultaneous Live Activities at once — compared to the two-activity limit on the iPhone 17 Pro Max. Secondly, the 18 Pro Max exclusively packs native Pro Controls into the camera app, something Apple simply doesn’t include with the updated iOS 27 experience on the 17 Pro Max.</p><p><strong>Winner:</strong> iPhone 18 Pro Max</p><h2 class="article-body__section" id="section-iphone-18-pro-max-vs-iphone-17-pro-max-verdict"><span>iPhone 18 Pro Max vs. iPhone 17 Pro Max: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="FDJ2VgTWRJ4st6bGiL5nh9" name="iPhone 18 Pro Max vs. iPhone 17 Pro Max" alt="iPhone 18 Pro Max vs. iPhone 17 Pro Max." src="https://cdn.mos.cms.futurecdn.net/FDJ2VgTWRJ4st6bGiL5nh9-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Apple didn’t just deliver a routine refresh with the iPhone 18 Pro Max — it pushed the envelope where it matters most. Pairing the physical variable aperture with native Pro Controls transforms the camera into a creative setup that could happily replace my point-and-shoot camera. Backed by the blistering performance of the A20 Pro silicon, a much brighter display, faster 60W charging, and class-leading battery endurance, the iPhone 18 Pro Max handily wins this matchup.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>iPhone 18 Pro Max</strong></p></th><th  ><p><strong>iPhone 17 Pro Max</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ></td><td  ><p>X</p></td></tr><tr><td class="firstcol " ><p><strong>Design</strong></p></td><td  ><p>X</p></td><td  ><p>X</p></td></tr><tr><td class="firstcol " ><p><strong>Display</strong></p></td><td  ><p>X</p></td><td  ></td></tr><tr><td class="firstcol " ><p><strong>Cameras</strong></p></td><td  ><p>X</p></td><td  ></td></tr><tr><td class="firstcol " ><p><strong>Performance</strong></p></td><td  ><p>X</p></td><td  ></td></tr><tr><td class="firstcol " ><p><strong>Battery Life</strong></p></td><td  ><p>X</p></td><td  ></td></tr><tr><td class="firstcol " ><p><strong>Software</strong></p></td><td  ><p>X</p></td><td  ></td></tr><tr><td class="firstcol " ><p><strong>Total</strong></p></td><td  ><p>6</p></td><td  ><p>2</p></td></tr></tbody></table></div><p>That said, if you already own an iPhone 17 Pro Max, you will find it hard to justify spending even more money — especially with Apple slapping a $100 price hike on the 18 Pro Max. Last year’s flagship still delivers phenomenal battery life, blazing-fast speed, and nearly the exact same iOS 27 and Siri AI software experience.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ODmljX"></div>                            </div>                            <script src="https://kwizly.com/embed/ODmljX.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom’s Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-iphone-18-pro-your-10-biggest-questions-answered"><strong>I've been testing the iPhone 18 Pro Max and iPhone 18 Pro — your 10 biggest questions answered</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-teardown-reveals-the-ins-and-outs-of-the-latest-iphone-models-including-one-annoying-repair-issue"><strong>iPhone 18 Pro teardown reveals the ins and outs of the latest iPhone models — including one annoying repair issue</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/apples-usd250-million-class-action-settlement-website-is-now-open-heres-how-eligible-iphone-owners-can-file-a-claim-and-how-much-theyll-get"><strong>Apple's $250 million class action settlement website is now open — here's how eligible iPhone owners can file a claim and how much they'll get</strong></a><strong></strong></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Android president on Apple iPhone Duo: 'Android is usually where you see the future first' ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Even before the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice"><u>iPhone Duo</u></a> launched, Android and Samsung fans were ribbing Apple for being so late to the <a href="https://www.tomsguide.com/best-picks/best-foldable-phones"><u>foldable phone</u></a> party. After all, the first Galaxy Fold launched in 2019.</p><p>Right after the Apple September event, <a href="https://x.com/SamsungMobileUS/status/2097748103478591990"><u>Samsung tweeted</u></a> “Let us know when you're done reheating our leftovers.”</p><p>Now that we’re edging closer to the iPhone Duo pre-order date of Oct 16, I thought it would be interesting to get the reaction of Sameer Samat, who is the president of Android Ecosystem at Google.</p><p>We were sitting down to talk about the new <a href="https://www.tomsguide.com/computing/laptops/inside-the-googlebook-i-asked-the-head-of-android-why-people-will-pay-a-premium-for-its-new-macbook-alternative"><u>Googlebook</u></a> push, but since those laptops are powered by Android, I wanted to ask him what he thought about Apple’s foldable entry versus Android foldables. </p><h2 id="better-late-than-never">Better late than never</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:42.85%;"><img id="gLnGtWucCeyaZRZHLrQoMe" name="samsung-galaxy-fold_01-hero.jpg" alt="Samsung Galaxy Fold mid-fold" src="https://cdn.mos.cms.futurecdn.net/gLnGtWucCeyaZRZHLrQoMe-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="857" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">The original Samsung Galaxy Fold in 2019 </span><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>As you might expect, Samat pointed out that Apple’s foldable launch is a wee bit behind the Android camp.</p><div><blockquote><p>“I think that it's wonderful to see more people realizing after so long that the foldable space is the place to be."</p><p>Sameer Samat, Google </p></blockquote></div><p>“I think that it's wonderful to see more people realizing after so long that the foldable space is the place to be. And Android is usually where you see the future first.”</p><p>It’s true that Android beat Apple to the foldable punch by a long shot, including the wide passport form factor the iPhone Duo has. Samat has been using the <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-review-wide-for-the-win"><u>Galaxy Z Fold 8</u></a> and is a big fan of that device in particular.</p><p>“The Fold 8 is an amazing device, Samat said. “It helps me get so much work done. I actually find myself starting productivity quite often on that device, and then moving to my laptop.”</p><h2 id="but-the-duo-is-still-a-real-threat">But the Duo is still a real threat</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2144px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4QQN7JtKkmsE7V6tNMwe2M" name="Apple iPhone Duo hands on-2" alt="Apple iPhone Duo shown in hand" src="https://cdn.mos.cms.futurecdn.net/4QQN7JtKkmsE7V6tNMwe2M-1920-80.jpg" mos="" align="middle" fullscreen="" width="2144" height="1206" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>At the same time, analysts predict a big foldable phone market share for Apple. For example, <a href="https://counterpointresearch.com/en/insights/global-foldable-shipments-to-hit-100-million-cumulative-milestone-by-end-of-2026"><u>Counterpoint Research</u></a> says Apple will gain about 25% of the market in year one, growing to 40% by the end of 2027.</p><p>A lot of that likely has to do with the ecosystem factor. I did a story recently ranking the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-trade-offs"><u>iPhone Duo trade-offs </u></a>— from the lack of telephoto zoom to a heavier weight versus the Fold 8 — and this reader comment summed up the pent-up demand best.</p><p>“Seriously, I've been waiting since the first Galaxy Z Fold for Apple to enter the arena (tried the Fold 5 and Fold 6, but just couldn't do Android because I'm locked into the rest of Apple's ecosystem).”</p><p>Despite Apple’s momentum at the moment, Samat is confident that the Duo will have a halo effect on Android foldables, because it will only increase interest in the category overall.</p><p>“I think that what this speaks to is something that we've known for a long time in the Android ecosystem, which is that the foldable space, the foldable form factor is awesome.”</p><h2 id="apple-app-advantage">Apple = app advantage?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="N49opwHV76RM3BfKvL8REa" name="iPhone duo edit 2" alt="iPhone Duo" src="https://cdn.mos.cms.futurecdn.net/N49opwHV76RM3BfKvL8REa-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>In addition, Apple could have a sizable advantage when it comes to app support for larger foldable displays, as it is making a big push with developers.</p><p>In fact, Apple specifically called out Slack during its event as one of the optimized apps, which as we speak still looks like a stretched out phone app on Android foldables. Apple also showed off a foldable-friendly version of Netflix.</p><div><blockquote><p>“I think that as this form factor becomes more and more popular, developers realize that there's more and more value in investing in it.”</p><p>Sameer Samat, Google</p></blockquote></div><p>Samat admitted that there’s still work to be done. And ironically Apple’s entry could be the tide to lift Android’s boat.</p><p>“I think that as this form factor becomes more and more popular, developers realize that there's more and more value in investing in it,” Samat said. “I think one of the things that we've done is to make the tools simpler and easier for them to invest in. And of course there are apps that haven't made that transition yet. Either they're working on it, or we're in conversations with them, but there are also thousands of thousands of apps that have.”</p><p>We talked about one of those apps in TikTok, which works very well on the Samsung Fold 8. You get an immersive viewing experience on the outside display, and on the inside you can scroll videos on the left and view comments on the right.</p><p>In addition, many of Google’s own apps have been fully optimized for foldables, including Gmail and YouTube.</p><p>“We can cherry pick an app or two that you know one platform will have or the other platform will have, but the reality is this form factor is a hit,” Samat said. “It's growing. It was growing even before these last couple weeks, and I'm glad to see more people joining what is now the obvious party.”</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo hands-on: Apple nailed it — and just put everyone else on notice</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-vs-samsung-galaxy-z-fold-8-which-foldable-is-best-for-you">iPhone Duo vs Samsung Galaxy Z Fold 8</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-spent-30-minutes-with-the-iphone-duo-3-things-you-just-dont-get-from-the-pictures">I spent 30 minutes with the iPhone Duo — 3 things you just don't get from the pictures</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/android-phones/googles-android-president-on-apple-iphone-duo-android-is-usually-where-you-see-the-future-first</link>
                                                                            <description>
                            <![CDATA[ Google isn’t scared of the iPhone Duo. And the president of Android Sameer Samat explains why ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">9R5SUNcpPKeU6DNiNywaXg</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/NE3m4C3QUpw7U8uQfUAmea-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 23 Sep 2026 04:15:00 +0000</pubDate>                                                                                                                                <updated>Wed, 23 Sep 2026 17:39:06 +0000</updated>
                                                                                                                                            <category><![CDATA[Android Phones]]></category>
                                                    <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                                    <dc:creator><![CDATA[ Mark Spoonauer ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/wtAspSzVfcKLB4JEd39AMo-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Mark Spoonauer is the global editor in chief of Tom&#039;s Guide and has covered technology for over 20 years. He oversees the direction of Tom&#039;s Guide and leads a team of over 25 journalists to bring you our expert buying guides, reviews, news, how-to articles, deals and other coverage.&lt;/p&gt;&lt;p&gt;Mark has a passion for covering all things mobile, having reviewed dozens of smartphones and other gadgets. He enjoys testing the top mobile devices and putting them up against each other in our in-depth face-offs. He also works hand in hand with our editors and testing team to continually improve how we evaluate products. &lt;/p&gt;&lt;p&gt;Having led Tom&#039;s Guide since 2013, Mark has focused on growing the core tech coverage of the site while also expanding into new areas, such as entertainment, fitness and home, recruiting talented writers and editors to help our readers figure out what to buy and how to get the most out of the products and services they use every day. &lt;/p&gt;&lt;p&gt;Mark has spoken at key industry events and appears regularly on TV to discuss the latest trends, including &lt;a href=&quot;https://cheddar.com/media/pixel-watch-gets-a-release-date-at-google-i-o-2022&quot;&gt;Cheddar&lt;/a&gt;, Fox 5, &lt;a href=&quot;https://www.foxbusiness.com/technology/apple-march-event-5g-iphone&quot;&gt;Fox Business&lt;/a&gt; and other outlets. Mark was previously editor in chief of Laptop Mag, and his work has appeared in Wired, Popular Science and Inc. Follow him on Twitter at @mspoonauer.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/NE3m4C3QUpw7U8uQfUAmea-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[IPhone duo vs galaxy Z Fold 8]]></media:description>                                                            <media:text><![CDATA[IPhone duo vs galaxy Z Fold 8]]></media:text>
                                <media:title type="plain"><![CDATA[IPhone duo vs galaxy Z Fold 8]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/NE3m4C3QUpw7U8uQfUAmea-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Even before the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice"><u>iPhone Duo</u></a> launched, Android and Samsung fans were ribbing Apple for being so late to the <a href="https://www.tomsguide.com/best-picks/best-foldable-phones"><u>foldable phone</u></a> party. After all, the first Galaxy Fold launched in 2019.</p><p>Right after the Apple September event, <a href="https://x.com/SamsungMobileUS/status/2097748103478591990"><u>Samsung tweeted</u></a> “Let us know when you're done reheating our leftovers.”</p><p>Now that we’re edging closer to the iPhone Duo pre-order date of Oct 16, I thought it would be interesting to get the reaction of Sameer Samat, who is the president of Android Ecosystem at Google.</p><p>We were sitting down to talk about the new <a href="https://www.tomsguide.com/computing/laptops/inside-the-googlebook-i-asked-the-head-of-android-why-people-will-pay-a-premium-for-its-new-macbook-alternative"><u>Googlebook</u></a> push, but since those laptops are powered by Android, I wanted to ask him what he thought about Apple’s foldable entry versus Android foldables. </p><h2 id="better-late-than-never">Better late than never</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:42.85%;"><img id="gLnGtWucCeyaZRZHLrQoMe" name="samsung-galaxy-fold_01-hero.jpg" alt="Samsung Galaxy Fold mid-fold" src="https://cdn.mos.cms.futurecdn.net/gLnGtWucCeyaZRZHLrQoMe-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="857" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">The original Samsung Galaxy Fold in 2019 </span><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>As you might expect, Samat pointed out that Apple’s foldable launch is a wee bit behind the Android camp.</p><div><blockquote><p>“I think that it's wonderful to see more people realizing after so long that the foldable space is the place to be."</p><p>Sameer Samat, Google </p></blockquote></div><p>“I think that it's wonderful to see more people realizing after so long that the foldable space is the place to be. And Android is usually where you see the future first.”</p><p>It’s true that Android beat Apple to the foldable punch by a long shot, including the wide passport form factor the iPhone Duo has. Samat has been using the <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-review-wide-for-the-win"><u>Galaxy Z Fold 8</u></a> and is a big fan of that device in particular.</p><p>“The Fold 8 is an amazing device, Samat said. “It helps me get so much work done. I actually find myself starting productivity quite often on that device, and then moving to my laptop.”</p><h2 id="but-the-duo-is-still-a-real-threat">But the Duo is still a real threat</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2144px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4QQN7JtKkmsE7V6tNMwe2M" name="Apple iPhone Duo hands on-2" alt="Apple iPhone Duo shown in hand" src="https://cdn.mos.cms.futurecdn.net/4QQN7JtKkmsE7V6tNMwe2M-1920-80.jpg" mos="" align="middle" fullscreen="" width="2144" height="1206" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>At the same time, analysts predict a big foldable phone market share for Apple. For example, <a href="https://counterpointresearch.com/en/insights/global-foldable-shipments-to-hit-100-million-cumulative-milestone-by-end-of-2026"><u>Counterpoint Research</u></a> says Apple will gain about 25% of the market in year one, growing to 40% by the end of 2027.</p><p>A lot of that likely has to do with the ecosystem factor. I did a story recently ranking the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-trade-offs"><u>iPhone Duo trade-offs </u></a>— from the lack of telephoto zoom to a heavier weight versus the Fold 8 — and this reader comment summed up the pent-up demand best.</p><p>“Seriously, I've been waiting since the first Galaxy Z Fold for Apple to enter the arena (tried the Fold 5 and Fold 6, but just couldn't do Android because I'm locked into the rest of Apple's ecosystem).”</p><p>Despite Apple’s momentum at the moment, Samat is confident that the Duo will have a halo effect on Android foldables, because it will only increase interest in the category overall.</p><p>“I think that what this speaks to is something that we've known for a long time in the Android ecosystem, which is that the foldable space, the foldable form factor is awesome.”</p><h2 id="apple-app-advantage">Apple = app advantage?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="N49opwHV76RM3BfKvL8REa" name="iPhone duo edit 2" alt="iPhone Duo" src="https://cdn.mos.cms.futurecdn.net/N49opwHV76RM3BfKvL8REa-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>In addition, Apple could have a sizable advantage when it comes to app support for larger foldable displays, as it is making a big push with developers.</p><p>In fact, Apple specifically called out Slack during its event as one of the optimized apps, which as we speak still looks like a stretched out phone app on Android foldables. Apple also showed off a foldable-friendly version of Netflix.</p><div><blockquote><p>“I think that as this form factor becomes more and more popular, developers realize that there's more and more value in investing in it.”</p><p>Sameer Samat, Google</p></blockquote></div><p>Samat admitted that there’s still work to be done. And ironically Apple’s entry could be the tide to lift Android’s boat.</p><p>“I think that as this form factor becomes more and more popular, developers realize that there's more and more value in investing in it,” Samat said. “I think one of the things that we've done is to make the tools simpler and easier for them to invest in. And of course there are apps that haven't made that transition yet. Either they're working on it, or we're in conversations with them, but there are also thousands of thousands of apps that have.”</p><p>We talked about one of those apps in TikTok, which works very well on the Samsung Fold 8. You get an immersive viewing experience on the outside display, and on the inside you can scroll videos on the left and view comments on the right.</p><p>In addition, many of Google’s own apps have been fully optimized for foldables, including Gmail and YouTube.</p><p>“We can cherry pick an app or two that you know one platform will have or the other platform will have, but the reality is this form factor is a hit,” Samat said. “It's growing. It was growing even before these last couple weeks, and I'm glad to see more people joining what is now the obvious party.”</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo hands-on: Apple nailed it — and just put everyone else on notice</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-vs-samsung-galaxy-z-fold-8-which-foldable-is-best-for-you">iPhone Duo vs Samsung Galaxy Z Fold 8</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-spent-30-minutes-with-the-iphone-duo-3-things-you-just-dont-get-from-the-pictures">I spent 30 minutes with the iPhone Duo — 3 things you just don't get from the pictures</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ iPhone Duo — I ranked the 7 trade-offs you need to know before you pre-order ]]></title>
                                                                                                <dc:content><![CDATA[ <p>The <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> is the most expensive phone Apple has ever made, and for good reason. </p><p>You get a compact 5.4-inch phone and tablet in one device with a huge 7.6-inch nano-texture display. And Apple promises unparalleled durability in the Duo’s design along with a new software experience that takes multitasking to the next level — and makes the most of all the positions you can put this foldable in.</p><p>But it’s only fair to call out the compromises for this <a href="https://www.tomsguide.com/best-picks/best-foldable-phones">foldable phone</a> versus other flagship phones, including Apple’s own <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max that I just reviewed</a>.</p><p>What annoys me is that people are already lumping all of the missing features and trade-offs into a list of “dealbreakers” as if they’re all of equal value. Spoiler: they’re not.</p><p>As we get closer to the Oct. 16 iPhone Duo pre-order date, I think it’s worth sense checking these trade-offs. I’m scoring each trade-off on a scale of 1-10 to tell you what’s an annoyance versus an actual dealbreaker.</p><h2 id="no-telephoto-zoom-dealbreaker-score-8-10">No telephoto zoom: ‘Dealbreaker’ score 8/10</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="SoAi2j7o9Dqs6v288A4cEa" name="iPhone Duo edit 3" alt="iPhone Duo" src="https://cdn.mos.cms.futurecdn.net/SoAi2j7o9Dqs6v288A4cEa-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>There’s no getting around it. The iPhone Duo’s 2x optical quality zoom is not the same thing as having a dedicated telephoto lens. You’re getting that zoom via cropping on the 48MP main sensor. If you want to get closer to the action, you’ll max out at just 10x digital zoom.</p><p>Meanwhile, the iPhone 18 Pro and Pro Max both have 4x telephoto lenses with 8x optical quality zooms. And you get a 40x digital zoom. If you like to zoom in a lot when shooting pics, don’t get the Duo.</p><h2 id="no-face-id-dealbreaker-score-7-10">No Face ID: ‘Dealbreaker’ score 7/10</h2><div class="looped-video"><video class="lazyload-in-view lazyloading" data-src="https://cdn.mos.cms.futurecdn.net/8x5XKH2YY6DQ5cDzDE3ETR/iPhone%20Duo%20TouchID%202.mp4" autoplay loop muted playsinline src="https://cdn.mos.cms.futurecdn.net/8x5XKH2YY6DQ5cDzDE3ETR/iPhone%20Duo%20TouchID%202.mp4"></video></div><p>It’s understandable why the iPhone Duo doesn’t have Face ID given that there’s less space for all of the sensors that are required for it, but it’s still a bummer because it’s such an easy way to unlock your phone. And Face ID is better than any face unlock solution on any Android phone.</p><p>Instead, you get a Touch ID sensor built into the power button on the right side. At least I’m fairly confident it will work well based on how reliable Touch ID is on the MacBook, iPad and previous iPhones.</p><h2 id="weight-dealbreaker-score-6-10">Weight: ‘Dealbreaker’ score 6/10</h2><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="GTrSzbvbSigPgscpMS3JsU" name="iPhone Duo-LIST1" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/GTrSzbvbSigPgscpMS3JsU-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>The iPhone Duo is certainly compact enough to slip into your front pocket, but it’s definitely heftier than the iPhone 18 Pro Max and Apple’s main foldable rival. </p><p>Weighing 8.96 ounces, the Duo is the heaviest iPhone yet and slightly heavier than the iPhone 18 Pro Max’s 8.78 ounces. </p><p>The Galaxy Z Fold 8 is the portability champ, weighing just 7.09 ounces. You really notice it in the hand.</p><p>But it’s worth keeping in mind that the iPhone Duo packs in some features that to many will be worth the extra weight, including IP68 durability, a vapor chamber and a digitizer layer on the display to support Apple Pencil input.</p><h2 id="price-dealbreaker-score-5-10">Price: ‘Dealbreaker’ score 5/10</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="tMqrxu9xgE5keuWLjFoH4V" name="iPhone Duo-7" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/tMqrxu9xgE5keuWLjFoH4V-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>You might have thought I would have ranked the high $2,000 price of the Duo higher on this list of dealbreakers. But it’s really more of a dealbreaker for the category as opposed to this particular phone. </p><p>After all, most foldable phones like this are in the same range. The Galaxy Fold 8 and Google Pixel 11 Pro Fold are $100 less. Still, the price certainly skyrockets as you add more storage. We’re talking $2,200 for 512GB, $2,599 for 1TB and a whopping $3,200 for 2TB. Though the competition makes out at 1TB.</p><h2 id="less-battery-life-than-iphone-18-pro-max-dealbreaker-score-4-10">Less battery life than iPhone 18 Pro Max: ‘Dealbreaker’ score 4/10</h2><p>Based on Apple’s own estimates, the iPhone Duo is going to last less than the iPhone 18 Pro Max in a charge. And that makes sense because the Duo’s dual battery system has to power a larger display. </p><p>Apple claims the iPhone Duo will last 24 hours with regular use versus 30 hours for the 18 Pro Max. But that gap grows with video playback, with the Duo rated for 31 hours and the Pro Max 45 hours. You can get up to 44 hours on the Duo’s small display.</p><h2 id="under-display-camera-dealbreaker-score-3-5-10">Under-display camera: ‘Dealbreaker’ score 3.5/10</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2297px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="g8hRHytY7NFuF8mBGUagyL" name="Apple iPhone Duo hands on" alt="Apple iPhone Duo shown in hand" src="https://cdn.mos.cms.futurecdn.net/g8hRHytY7NFuF8mBGUagyL-1920-80.jpg" mos="" align="middle" fullscreen="" width="2297" height="1292" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Apple decided to give the iPhone Duo an under display FaceTime camera while other companies have ditched them due to quality issues. Based on what I’ve seen so far, I’d say it looks good enough for video calls but you'll want to use the front 12MP camera or even the main 48MP camera for selfies.</p><h2 id="lacks-variable-aperture-and-pro-controls-dealbreaker-score-3-10">Lacks variable aperture and Pro Controls: ‘Dealbreaker’ score 3/10</h2><div class="looped-video"><video class="lazyload-in-view lazyloading" data-src="https://cdn.mos.cms.futurecdn.net/qQMWZGYtCvZJhcdDWSpHCZ/iPhone%2018%20Pro%20variable%20aperture%202.mp4" autoplay loop muted playsinline src="https://cdn.mos.cms.futurecdn.net/qQMWZGYtCvZJhcdDWSpHCZ/iPhone%2018%20Pro%20variable%20aperture%202.mp4"></video></div><p>It’s a bummer that the variable aperture main camera is limited to the iPhone 18 Pro and Pro Max. It does give you more flexibility when shooting. </p><p>But the bigger annoyance for me is that Apple didn’t grace the Duo with Pro controls. Why not make it easier to control shutter speed, white balance and more?</p><h2 id="bottom-line-5">Bottom line</h2><p>When you add it all up the only real iPhone Duo dealbreaker for me is the lack of a telephoto zoom. And while I really wish it had Face ID, I can live with Touch ID.</p><p>But what about you? Are there any iPhone Duo dealbreakers high on your list or do you plan to buy despite any trade-offs? Let us know in the comments.</p> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/iphone-duo-trade-offs</link>
                                                                            <description>
                            <![CDATA[ The iPhone Duo has a lot going for it, but is this foldable phone worth $2,000? Let’s break down the trade-offs before you pre-order. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">rfZebXWVwRCm6aG4jTjQhQ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/ENFN2u4hpSYiQYfbA6WbcL-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 22 Sep 2026 12:00:00 +0000</pubDate>                                                                                                                                <updated>Tue, 22 Sep 2026 12:20:42 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                                    <dc:creator><![CDATA[ Mark Spoonauer ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/wtAspSzVfcKLB4JEd39AMo-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Mark Spoonauer is the global editor in chief of Tom&#039;s Guide and has covered technology for over 20 years. He oversees the direction of Tom&#039;s Guide and leads a team of over 25 journalists to bring you our expert buying guides, reviews, news, how-to articles, deals and other coverage.&lt;/p&gt;&lt;p&gt;Mark has a passion for covering all things mobile, having reviewed dozens of smartphones and other gadgets. He enjoys testing the top mobile devices and putting them up against each other in our in-depth face-offs. He also works hand in hand with our editors and testing team to continually improve how we evaluate products. &lt;/p&gt;&lt;p&gt;Having led Tom&#039;s Guide since 2013, Mark has focused on growing the core tech coverage of the site while also expanding into new areas, such as entertainment, fitness and home, recruiting talented writers and editors to help our readers figure out what to buy and how to get the most out of the products and services they use every day. &lt;/p&gt;&lt;p&gt;Mark has spoken at key industry events and appears regularly on TV to discuss the latest trends, including &lt;a href=&quot;https://cheddar.com/media/pixel-watch-gets-a-release-date-at-google-i-o-2022&quot;&gt;Cheddar&lt;/a&gt;, Fox 5, &lt;a href=&quot;https://www.foxbusiness.com/technology/apple-march-event-5g-iphone&quot;&gt;Fox Business&lt;/a&gt; and other outlets. Mark was previously editor in chief of Laptop Mag, and his work has appeared in Wired, Popular Science and Inc. Follow him on Twitter at @mspoonauer.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/ENFN2u4hpSYiQYfbA6WbcL-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Apple iPhone Duo shown in hand]]></media:description>                                                            <media:text><![CDATA[Apple iPhone Duo shown in hand]]></media:text>
                                <media:title type="plain"><![CDATA[Apple iPhone Duo shown in hand]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/ENFN2u4hpSYiQYfbA6WbcL-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> is the most expensive phone Apple has ever made, and for good reason. </p><p>You get a compact 5.4-inch phone and tablet in one device with a huge 7.6-inch nano-texture display. And Apple promises unparalleled durability in the Duo’s design along with a new software experience that takes multitasking to the next level — and makes the most of all the positions you can put this foldable in.</p><p>But it’s only fair to call out the compromises for this <a href="https://www.tomsguide.com/best-picks/best-foldable-phones">foldable phone</a> versus other flagship phones, including Apple’s own <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max that I just reviewed</a>.</p><p>What annoys me is that people are already lumping all of the missing features and trade-offs into a list of “dealbreakers” as if they’re all of equal value. Spoiler: they’re not.</p><p>As we get closer to the Oct. 16 iPhone Duo pre-order date, I think it’s worth sense checking these trade-offs. I’m scoring each trade-off on a scale of 1-10 to tell you what’s an annoyance versus an actual dealbreaker.</p><h2 id="no-telephoto-zoom-dealbreaker-score-8-10">No telephoto zoom: ‘Dealbreaker’ score 8/10</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="SoAi2j7o9Dqs6v288A4cEa" name="iPhone Duo edit 3" alt="iPhone Duo" src="https://cdn.mos.cms.futurecdn.net/SoAi2j7o9Dqs6v288A4cEa-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>There’s no getting around it. The iPhone Duo’s 2x optical quality zoom is not the same thing as having a dedicated telephoto lens. You’re getting that zoom via cropping on the 48MP main sensor. If you want to get closer to the action, you’ll max out at just 10x digital zoom.</p><p>Meanwhile, the iPhone 18 Pro and Pro Max both have 4x telephoto lenses with 8x optical quality zooms. And you get a 40x digital zoom. If you like to zoom in a lot when shooting pics, don’t get the Duo.</p><h2 id="no-face-id-dealbreaker-score-7-10">No Face ID: ‘Dealbreaker’ score 7/10</h2><div class="looped-video"><video class="lazyload-in-view lazyloading" data-src="https://cdn.mos.cms.futurecdn.net/8x5XKH2YY6DQ5cDzDE3ETR/iPhone%20Duo%20TouchID%202.mp4" autoplay loop muted playsinline src="https://cdn.mos.cms.futurecdn.net/8x5XKH2YY6DQ5cDzDE3ETR/iPhone%20Duo%20TouchID%202.mp4"></video></div><p>It’s understandable why the iPhone Duo doesn’t have Face ID given that there’s less space for all of the sensors that are required for it, but it’s still a bummer because it’s such an easy way to unlock your phone. And Face ID is better than any face unlock solution on any Android phone.</p><p>Instead, you get a Touch ID sensor built into the power button on the right side. At least I’m fairly confident it will work well based on how reliable Touch ID is on the MacBook, iPad and previous iPhones.</p><h2 id="weight-dealbreaker-score-6-10">Weight: ‘Dealbreaker’ score 6/10</h2><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="GTrSzbvbSigPgscpMS3JsU" name="iPhone Duo-LIST1" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/GTrSzbvbSigPgscpMS3JsU-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>The iPhone Duo is certainly compact enough to slip into your front pocket, but it’s definitely heftier than the iPhone 18 Pro Max and Apple’s main foldable rival. </p><p>Weighing 8.96 ounces, the Duo is the heaviest iPhone yet and slightly heavier than the iPhone 18 Pro Max’s 8.78 ounces. </p><p>The Galaxy Z Fold 8 is the portability champ, weighing just 7.09 ounces. You really notice it in the hand.</p><p>But it’s worth keeping in mind that the iPhone Duo packs in some features that to many will be worth the extra weight, including IP68 durability, a vapor chamber and a digitizer layer on the display to support Apple Pencil input.</p><h2 id="price-dealbreaker-score-5-10">Price: ‘Dealbreaker’ score 5/10</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="tMqrxu9xgE5keuWLjFoH4V" name="iPhone Duo-7" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/tMqrxu9xgE5keuWLjFoH4V-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>You might have thought I would have ranked the high $2,000 price of the Duo higher on this list of dealbreakers. But it’s really more of a dealbreaker for the category as opposed to this particular phone. </p><p>After all, most foldable phones like this are in the same range. The Galaxy Fold 8 and Google Pixel 11 Pro Fold are $100 less. Still, the price certainly skyrockets as you add more storage. We’re talking $2,200 for 512GB, $2,599 for 1TB and a whopping $3,200 for 2TB. Though the competition makes out at 1TB.</p><h2 id="less-battery-life-than-iphone-18-pro-max-dealbreaker-score-4-10">Less battery life than iPhone 18 Pro Max: ‘Dealbreaker’ score 4/10</h2><p>Based on Apple’s own estimates, the iPhone Duo is going to last less than the iPhone 18 Pro Max in a charge. And that makes sense because the Duo’s dual battery system has to power a larger display. </p><p>Apple claims the iPhone Duo will last 24 hours with regular use versus 30 hours for the 18 Pro Max. But that gap grows with video playback, with the Duo rated for 31 hours and the Pro Max 45 hours. You can get up to 44 hours on the Duo’s small display.</p><h2 id="under-display-camera-dealbreaker-score-3-5-10">Under-display camera: ‘Dealbreaker’ score 3.5/10</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2297px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="g8hRHytY7NFuF8mBGUagyL" name="Apple iPhone Duo hands on" alt="Apple iPhone Duo shown in hand" src="https://cdn.mos.cms.futurecdn.net/g8hRHytY7NFuF8mBGUagyL-1920-80.jpg" mos="" align="middle" fullscreen="" width="2297" height="1292" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Apple decided to give the iPhone Duo an under display FaceTime camera while other companies have ditched them due to quality issues. Based on what I’ve seen so far, I’d say it looks good enough for video calls but you'll want to use the front 12MP camera or even the main 48MP camera for selfies.</p><h2 id="lacks-variable-aperture-and-pro-controls-dealbreaker-score-3-10">Lacks variable aperture and Pro Controls: ‘Dealbreaker’ score 3/10</h2><div class="looped-video"><video class="lazyload-in-view lazyloading" data-src="https://cdn.mos.cms.futurecdn.net/qQMWZGYtCvZJhcdDWSpHCZ/iPhone%2018%20Pro%20variable%20aperture%202.mp4" autoplay loop muted playsinline src="https://cdn.mos.cms.futurecdn.net/qQMWZGYtCvZJhcdDWSpHCZ/iPhone%2018%20Pro%20variable%20aperture%202.mp4"></video></div><p>It’s a bummer that the variable aperture main camera is limited to the iPhone 18 Pro and Pro Max. It does give you more flexibility when shooting. </p><p>But the bigger annoyance for me is that Apple didn’t grace the Duo with Pro controls. Why not make it easier to control shutter speed, white balance and more?</p><h2 id="bottom-line-5">Bottom line</h2><p>When you add it all up the only real iPhone Duo dealbreaker for me is the lack of a telephoto zoom. And while I really wish it had Face ID, I can live with Touch ID.</p><p>But what about you? Are there any iPhone Duo dealbreakers high on your list or do you plan to buy despite any trade-offs? Let us know in the comments.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ iOS 27.2 beta is here — 5 biggest upgrades for your iPhone, including a revamped Health app ]]></title>
                                                                                                <dc:content><![CDATA[ <p>A lot of iPhone users are still getting to grips with the <a href="https://www.tomsguide.com/phones/iphones/ios-27-is-live-heres-how-to-download-and-install-it-now">recent release of iOS 27</a>, but that doesn't mean Apple gets to take a break. It's just released iOS 27.2 beta, which comes with a bunch more changes and upgrades for beta testers to try out. </p><p>Some of you may be wondering what happened to <a href="https://www.macworld.com/article/3237296/ios-27-2-beta-is-out-now-skipping-over-ios-27-1.html" target="_blank">iOS 27.1 beta</a>, and that's a fair question. Apparently Apple has skipped over that bit of software, and it's speculated that the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> is the reason. The foldable will apparently arrive running iOS 27.1 out of the box, complete with all the extra software needed to run a foldable phone. Whether other devices will get iOS 27.1, or if they'll jump straight to iOS 27.2, isn't clear.</p><p>In the meantime, here are all the newest features and changes coming as part of the iOS 27.2 beta release.</p><h2 id="revamped-health-app">Revamped Health app</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="e3YWp5GXo2G4kLyjX3XZwW" name="Apple Health.shutterstock_2126141624" alt="Apple Health app icon on iPhone" src="https://cdn.mos.cms.futurecdn.net/e3YWp5GXo2G4kLyjX3XZwW-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>Back during its <a href="https://www.tomsguide.com/phones/iphones/apple-september-event-preview-all-the-new-products-to-expect-at-iphone-18-pro-launch-and-beyond">September iPhone launch event</a>, Apple confirmed that it would be revamping the Health app — and iOS 27.2 beta is our first chance to see it in action. This new version of the app is laid out with three tabs: Insight, Longevity and Browse.</p><p>Insights includes general health information, such as vitals, sleep score, heart rate and your activity rings. Longevity takes that information and applies it over time, offering a Health Age score calculated from various health metrics — including VO2 max, sleep time and activity levels. Browse is the same as it always was, offering health-based resources to help you with your fitness, or general healthy-living goals.</p><h2 id="call-context">Call context</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="aqBaZYFdSMFXbg2coDszxR" name="TG Deals Template 2023 copy" alt="ios 27 call context" src="https://cdn.mos.cms.futurecdn.net/aqBaZYFdSMFXbg2coDszxR-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>iOS 27.2 beta will now surface relevant information during phone calls, specifically warning you about birthdays or anniversaries. The caveat being that you need to have entered that information into the Contacts app first. You also need to call those people to get the reminder, which means you actively need to be calling them for a totally different reason.</p><p>It might be worth making sure your calendar reminders are set up properly instead. But this could be the start of even more contextual information in calls, some of which may not be quite as difficult to to forget.</p><h2 id="carplay-ultra">CarPlay Ultra</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="isBpmghbge75iTxRbyf3HV" name="CarPlay Ultra edit" alt="Apple CarPlay Ultra in Aston Martin" src="https://cdn.mos.cms.futurecdn.net/isBpmghbge75iTxRbyf3HV-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>Apple's advanced version of CarPlay isn't that widespread, but if you do have a compatible car the iOS 27.2 beta will let you select new options for the wallpaper, gauge style and overall color of your interfaces. Code references also suggest that ambient light may be supported in select vehicles, matching the overall theme.</p><h2 id="apple-tv">Apple TV</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="o8wLBQyVQJtrSw6RGdtEec" name="ios27  3" alt="ios 27.2 beta" src="https://cdn.mos.cms.futurecdn.net/o8wLBQyVQJtrSw6RGdtEec-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The Apple TV app now includes extended profiles in iOS 27.2 beta, letting users create specific profiles for different users. All they require is a name, profile rating and whether the user is a child. Child accounts are limited to PG rated content by default, but in line with Apple's new parental controls, those settings can be adjusted based on your wishes.</p><p>Sign language interpretation is also available and can be turned on in the Apple TV app settings.</p><h2 id="siri">Siri</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="J2MoDXHFoo8bsZfXkXaeoc" name="ios275" alt="ios 27.2 beta" src="https://cdn.mos.cms.futurecdn.net/J2MoDXHFoo8bsZfXkXaeoc-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Siri AI is also now available in French, Japanese, Korean, Portuguese and Spanish, letting those speakers use AI without having to revert to English. Meanwhile ,the Siri app has renamed "App Access" to "Excluded Apps", and tapping it lets you exclude multiple apps from Siri features in one go — rather than one at a time.</p><h2 id="other-ios-27-2-beta-upgrades">Other iOS 27.2 beta upgrades</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="2XJQkXqsjEuFNtFki6sVqc" name="ios27.JPG" alt="ios 27.2 beta" src="https://cdn.mos.cms.futurecdn.net/2XJQkXqsjEuFNtFki6sVqc-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The Clock app now features A.M. and P.M. readouts that are slightly smaller than the actual time of your alarms. The Music app has also removed some of the red accents, with shuffle and play buttons in the library now appearing black. Podcasts has also swapped the "Up Next" feature for a "New Episodes" option, and has added a "Continue Playing" option.</p><p>Apple's release notes also include an expanded App Tracking Transparency prompt for EU users, specifically those in France, Germany, Poland, Italy and Romania. This will need to be re-accepted every year.</p><h2 id="hidden-features-for-the-future">Hidden features for the future</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="K5SQbjBSv85JzgqYxoY5Lm" name="iPhone iOS 27 LIST_alt6" alt="iOS 27 icon shown on an iPhone screen" src="https://cdn.mos.cms.futurecdn.net/K5SQbjBSv85JzgqYxoY5Lm-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide/Apple/Shutterstock)</span></figcaption></figure><p>Deep dives into iOS 27.2 beta's code have also revealed some details on possible future features, which Apple is working on but isn't ready to roll out just yet. The first is a new release countdown timer that may be coming to Apple Music, showing you how long you have to wait before the next big album is available to listen to.</p><p>It was also discovered that the Shortcuts app may be opened to third-party developers, letting you create your own Shortcuts for apps and services that weren't made by Apple. Plus, references to an "AutoLock" feature have been uncovered, suggesting that Apple really is working on a feature to automatically detect when an iPhone has been snatched, and lock the phone down in response.</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/36-million-iphone-owners-can-soon-get-paid-from-usd250-million-apple-siri-false-advertising-lawsuit-how-to-claim-your-share">36 million iPhone owners can soon get paid from $250 million Apple Siri lawsuit — how to claim your share</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-teardown-reveals-the-ins-and-outs-of-the-latest-iphone-models-including-one-annoying-repair-issue">iPhone 18 Pro teardown reveals the ins and outs of the latest iPhone models — including one annoying repair issue</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-extended-my-iphones-telephoto-range-with-this-add-on-camera-lens-and-my-point-and-shoot-camera-is-officially-retired">I extended my iPhone's telephoto range with this add-on camera lens — and my point-and-shoot camera is officially retired</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/ios-27-2-beta-is-here-5-biggest-upgrades-for-your-iphone-including-a-revamped-health-app</link>
                                                                            <description>
                            <![CDATA[ iOS 27.2 beta is already here, and it's come with a bunch of useful upgrades — including the revamped Health app. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">VDrKFGnvXXWeDRvrEFFqxi</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/dWb4LmZqmHyfE4qbeeCsKm-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 22 Sep 2026 11:22:30 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ tom.pritchard@futurenet.com (Tom Pritchard) ]]></author>                    <dc:creator><![CDATA[ Tom Pritchard ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/biCewUkKfSA6QnT2HxVc3f-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/dWb4LmZqmHyfE4qbeeCsKm-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide/Apple/Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iOS 27 icon shown on an iPhone screen]]></media:description>                                                            <media:text><![CDATA[iOS 27 icon shown on an iPhone screen]]></media:text>
                                <media:title type="plain"><![CDATA[iOS 27 icon shown on an iPhone screen]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/dWb4LmZqmHyfE4qbeeCsKm-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>A lot of iPhone users are still getting to grips with the <a href="https://www.tomsguide.com/phones/iphones/ios-27-is-live-heres-how-to-download-and-install-it-now">recent release of iOS 27</a>, but that doesn't mean Apple gets to take a break. It's just released iOS 27.2 beta, which comes with a bunch more changes and upgrades for beta testers to try out. </p><p>Some of you may be wondering what happened to <a href="https://www.macworld.com/article/3237296/ios-27-2-beta-is-out-now-skipping-over-ios-27-1.html" target="_blank">iOS 27.1 beta</a>, and that's a fair question. Apparently Apple has skipped over that bit of software, and it's speculated that the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> is the reason. The foldable will apparently arrive running iOS 27.1 out of the box, complete with all the extra software needed to run a foldable phone. Whether other devices will get iOS 27.1, or if they'll jump straight to iOS 27.2, isn't clear.</p><p>In the meantime, here are all the newest features and changes coming as part of the iOS 27.2 beta release.</p><h2 id="revamped-health-app">Revamped Health app</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="e3YWp5GXo2G4kLyjX3XZwW" name="Apple Health.shutterstock_2126141624" alt="Apple Health app icon on iPhone" src="https://cdn.mos.cms.futurecdn.net/e3YWp5GXo2G4kLyjX3XZwW-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>Back during its <a href="https://www.tomsguide.com/phones/iphones/apple-september-event-preview-all-the-new-products-to-expect-at-iphone-18-pro-launch-and-beyond">September iPhone launch event</a>, Apple confirmed that it would be revamping the Health app — and iOS 27.2 beta is our first chance to see it in action. This new version of the app is laid out with three tabs: Insight, Longevity and Browse.</p><p>Insights includes general health information, such as vitals, sleep score, heart rate and your activity rings. Longevity takes that information and applies it over time, offering a Health Age score calculated from various health metrics — including VO2 max, sleep time and activity levels. Browse is the same as it always was, offering health-based resources to help you with your fitness, or general healthy-living goals.</p><h2 id="call-context">Call context</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="aqBaZYFdSMFXbg2coDszxR" name="TG Deals Template 2023 copy" alt="ios 27 call context" src="https://cdn.mos.cms.futurecdn.net/aqBaZYFdSMFXbg2coDszxR-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>iOS 27.2 beta will now surface relevant information during phone calls, specifically warning you about birthdays or anniversaries. The caveat being that you need to have entered that information into the Contacts app first. You also need to call those people to get the reminder, which means you actively need to be calling them for a totally different reason.</p><p>It might be worth making sure your calendar reminders are set up properly instead. But this could be the start of even more contextual information in calls, some of which may not be quite as difficult to to forget.</p><h2 id="carplay-ultra">CarPlay Ultra</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="isBpmghbge75iTxRbyf3HV" name="CarPlay Ultra edit" alt="Apple CarPlay Ultra in Aston Martin" src="https://cdn.mos.cms.futurecdn.net/isBpmghbge75iTxRbyf3HV-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>Apple's advanced version of CarPlay isn't that widespread, but if you do have a compatible car the iOS 27.2 beta will let you select new options for the wallpaper, gauge style and overall color of your interfaces. Code references also suggest that ambient light may be supported in select vehicles, matching the overall theme.</p><h2 id="apple-tv">Apple TV</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="o8wLBQyVQJtrSw6RGdtEec" name="ios27  3" alt="ios 27.2 beta" src="https://cdn.mos.cms.futurecdn.net/o8wLBQyVQJtrSw6RGdtEec-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The Apple TV app now includes extended profiles in iOS 27.2 beta, letting users create specific profiles for different users. All they require is a name, profile rating and whether the user is a child. Child accounts are limited to PG rated content by default, but in line with Apple's new parental controls, those settings can be adjusted based on your wishes.</p><p>Sign language interpretation is also available and can be turned on in the Apple TV app settings.</p><h2 id="siri">Siri</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="J2MoDXHFoo8bsZfXkXaeoc" name="ios275" alt="ios 27.2 beta" src="https://cdn.mos.cms.futurecdn.net/J2MoDXHFoo8bsZfXkXaeoc-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Siri AI is also now available in French, Japanese, Korean, Portuguese and Spanish, letting those speakers use AI without having to revert to English. Meanwhile ,the Siri app has renamed "App Access" to "Excluded Apps", and tapping it lets you exclude multiple apps from Siri features in one go — rather than one at a time.</p><h2 id="other-ios-27-2-beta-upgrades">Other iOS 27.2 beta upgrades</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="2XJQkXqsjEuFNtFki6sVqc" name="ios27.JPG" alt="ios 27.2 beta" src="https://cdn.mos.cms.futurecdn.net/2XJQkXqsjEuFNtFki6sVqc-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The Clock app now features A.M. and P.M. readouts that are slightly smaller than the actual time of your alarms. The Music app has also removed some of the red accents, with shuffle and play buttons in the library now appearing black. Podcasts has also swapped the "Up Next" feature for a "New Episodes" option, and has added a "Continue Playing" option.</p><p>Apple's release notes also include an expanded App Tracking Transparency prompt for EU users, specifically those in France, Germany, Poland, Italy and Romania. This will need to be re-accepted every year.</p><h2 id="hidden-features-for-the-future">Hidden features for the future</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="K5SQbjBSv85JzgqYxoY5Lm" name="iPhone iOS 27 LIST_alt6" alt="iOS 27 icon shown on an iPhone screen" src="https://cdn.mos.cms.futurecdn.net/K5SQbjBSv85JzgqYxoY5Lm-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide/Apple/Shutterstock)</span></figcaption></figure><p>Deep dives into iOS 27.2 beta's code have also revealed some details on possible future features, which Apple is working on but isn't ready to roll out just yet. The first is a new release countdown timer that may be coming to Apple Music, showing you how long you have to wait before the next big album is available to listen to.</p><p>It was also discovered that the Shortcuts app may be opened to third-party developers, letting you create your own Shortcuts for apps and services that weren't made by Apple. Plus, references to an "AutoLock" feature have been uncovered, suggesting that Apple really is working on a feature to automatically detect when an iPhone has been snatched, and lock the phone down in response.</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/36-million-iphone-owners-can-soon-get-paid-from-usd250-million-apple-siri-false-advertising-lawsuit-how-to-claim-your-share">36 million iPhone owners can soon get paid from $250 million Apple Siri lawsuit — how to claim your share</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-teardown-reveals-the-ins-and-outs-of-the-latest-iphone-models-including-one-annoying-repair-issue">iPhone 18 Pro teardown reveals the ins and outs of the latest iPhone models — including one annoying repair issue</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-extended-my-iphones-telephoto-range-with-this-add-on-camera-lens-and-my-point-and-shoot-camera-is-officially-retired">I extended my iPhone's telephoto range with this add-on camera lens — and my point-and-shoot camera is officially retired</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 5 things Galaxy Z Fold 9 needs to steal from iPhone Duo — and 2 it shouldn't ]]></title>
                                                                                                <dc:content><![CDATA[ <p>The <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> is ticking all of the right boxes at the moment, wowing just about everyone that's been able to use it ahead of its official release Oct. 23. We still don't know how much of a success the phone will be, especially considering the $2,000 price tag, but you can be sure other phone makers are watching closely — especially Samsung.</p><p>Samsung has been the de-factor king of the foldable phone business for several years. Mainly because, outside of China, the <a href="https://www.tomsguide.com/best-picks/best-foldable-phones">best foldables</a> have been limited to Google and Motorola — who haven't exactly put up much of a fight. Apple could finally bring the Galaxy Fold series some serious competition, and if I were Samsung I'd be looking for ways to make my foldables stand out. Even if it means blatantly copying Apple's ideas.</p><p>Here are five things the Galaxy Z Fold 9 should steal from iPhone Duo, and two things it should leave well alone.</p><h2 id="what-z-fold-9-should-steal-from-iphone-duo">What Z Fold 9 should steal from iPhone Duo</h2><h3 class="article-body__section" id="section-under-display-camera"><span>Under display camera</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="Mdj8kozN6J8WNXPhazFQFa" name="iPhone Duo edit 1" alt="iPhone Duo" src="https://cdn.mos.cms.futurecdn.net/Mdj8kozN6J8WNXPhazFQFa-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Samsung had under-display cameras on the Galaxy Z Fold lineup for four generations, from the <a href="https://www.tomsguide.com/reviews/samsung-galaxy-z-fold-3">Galaxy Z Fold 3</a> to <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-6-review-test-results">Z Fold 6</a>. The quality of those cameras was a little... weak, to say the least, so it's no surprise that Samsung pulled them for the last two generations. But maybe now is the time to bring them back.</p><p>Apple has added an under-display camera to the iPhone Duo's foldable display, though this one isn't designed for selfies. Apple has referred to it as a FaceTime camera, and talked about its use as an aid for video calling. That suggests the quality isn't all that either, but by limiting its use cases (at least in marketing) Apple can avoid the same criticisms as Samsung.</p><p>This means the Z Fold 9 could be the perfect time for Samsung to bring the under-display camera back — and give you more of your screen back. Plus, considering you can already take selfies with the rear cameras and the hole-punch on the cover display, I'd avoid using it as a way to take photos of yourself.</p><h3 class="article-body__section" id="section-s-pen-support"><span>S Pen support</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="JUVSwuTeFABcGUzkRL8WtU" name="Galaxy Z Fold 6 and S Pen.jpg" alt="Samsung Galaxy Z Fold 6 and S Pen" src="https://cdn.mos.cms.futurecdn.net/JUVSwuTeFABcGUzkRL8WtU-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The loss of the stylus is one of the things Galaxy foldable fans have been complaining about since the release of <a href="https://www.tomsguide.com/phones/samsung-galaxy-z-fold-7-review">Galaxy Z Fold 7</a>. The stylus requires a special digitizer layer in the display, which was removed in an apparent attempt to reduce thickness. Which isn't a great reason to remove a long-standing feature, especially when it leaves Galaxy foldables feeling a little bit lacking.</p><p>Not only does the<a href="https://www.tomsguide.com/phones/iphones/steve-jobs-said-there-would-never-be-an-iphone-stylus-but-iphone-duo-just-proved-him-wrong-and-itll-be-a-better-device-for-it"> iPhone Duo have stylus support, it uses the Apple Pencil USB-C</a> — which is compatible with almost every iPad on sale. There's no special iPhone-exclusive stylus; it's the one a lot of iPad users may already have. The same couldn't be said for past Z Fold models, which needed a special foldable-exclusive stylus designed for the more fragile folding display.</p><p>I felt that the Galaxy Z Fold 8 Ultra was missing out on account of its lost stylus, and the launch of Z Fold 9 would be the perfect opportunity to reintroduce that support. Ideally, it would the form of a stylus that will work across Galaxy devices, including tablets and other phones.</p><h3 class="article-body__section" id="section-ip68-durability"><span>IP68 durability</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="F6qr2SDN3gLqxsmgpqVYsY" name="Fold 8 back 2" alt="Samsung Galaxy Z Fold 8" src="https://cdn.mos.cms.futurecdn.net/F6qr2SDN3gLqxsmgpqVYsY-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Google was the first foldable phone maker in the U.S. to add IP68 water and dust resistance to foldables with <a href="https://www.tomsguide.com/phones/google-pixel-phones/pixel-10-pro-fold-review">Pixel 10 Pro Fold</a>, and Apple has followed its example with iPhone Duo. Galaxy Z Fold 8, on the other hand only has an IP48 rating, which means it's totally exposed to dust — even if it is sealed tight against water.</p><p>Obviously, that's not a good look for Samsung, especially when you consider all the moving parts associated with a foldable hinge. You should be able to take your $1,900 to $2,000 foldable to the beach. So Samsung definitely needs to do better with the Z Fold 9.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-exgNKX"></div>                            </div>                            <script src="https://kwizly.com/embed/exgNKX.js" async></script><h3 class="article-body__section" id="section-magnetic-wireless-charging-built-in"><span>Magnetic wireless charging built in</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="q4DNX2SeEFU5sCTTt45wEa" name="iphone duo edit 5" alt="iPhone Duo" src="https://cdn.mos.cms.futurecdn.net/q4DNX2SeEFU5sCTTt45wEa-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>One of the things I'll never understand is why Samsung is so <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-may-skip-adding-qi2-to-the-galaxy-s26-ultra-and-i-think-theyve-made-the-right-call">seemingly against adding magnetic wireless charging</a> to its phones — foldables included. The phones support Qi2 wireless charging technology, but they lack the integrated magnets that let chargers and accessories snap into place.</p><p>One reason I was given was that<a href="https://www.tomsguide.com/phones/samsung-phones/samsung-may-skip-adding-qi2-to-the-galaxy-s26-ultra-and-i-think-theyve-made-the-right-call"> the magnets interfered with the S Pen</a>, and Samsung couldn't offer both. But considering the iPhone Duo has Apple Pencil support and MagSafe, it's clear that there is a way to offer both features without asking users to compromise. Because a magnetic case system is just a poor show for a phone company that sells devices for close to two thousand dollars.</p><h3 class="article-body__section" id="section-an-actual-vapor-chamber"><span>An actual Vapor Chamber</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:3330px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="tgL6AweqbNKzVVmQctz95Z" name="Galaxy Z Fold 8 review-22" alt="Galaxy Z Fold 8 shown held in-hand" src="https://cdn.mos.cms.futurecdn.net/tgL6AweqbNKzVVmQctz95Z-1920-80.jpg" mos="" align="middle" fullscreen="" width="3330" height="1873" attribution="" endorsement="" class="inline"></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 Snapdragon 8 Elite Gen 5 for Galaxy chipset is powerful. But the phones that use it can get quite hot, and a lack of cooling can lead to worse sustained performance.That's why Samsung needs to add a vapor chamber, much like the Galaxy S26 Ultra and the iPhone Duo.</p><p>Vapor chambers help move heat across the phone, allowing it to dissipate more evenly, and keep key components from overheating. It also helps improve sustained performance, and les the phone work harder for longer. </p><p>Admittedly, the Z Fold 8 does have pretty good sustained performance compared to the S26 Ultra (72.4% versus 53.9%) but it's behind the iPhone 18 Pro Max (79.4%), But can you imagine how much better things could be if there was a vapor chamber to help keep everything cool?</p><h2 id="two-things-iphone-duo-can-keep">Two things iPhone Duo can keep</h2><h3 class="article-body__section" id="section-curved-corners"><span>Curved corners</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:2144px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4oMko37sfDNte8KzjvzD2M" name="Apple iPhone Duo hands on-3" alt="Apple iPhone Duo shown in hand" src="https://cdn.mos.cms.futurecdn.net/4oMko37sfDNte8KzjvzD2M-1920-80.jpg" mos="" align="middle" fullscreen="" width="2144" height="1206" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Apple loves curved corners on its phones, a design that has made its way to foldables as well. Samsung may have opted for more curved corners on its non-folding phones, like Galaxy S26, but for the time being foldables have retained the sharper right-angles Samsung was once known for. The Galaxy Z Fold 9 should stay the same way.</p><p>My issue with the iPhone Duo is the lack of symmetry in the design. If you look at it from the cover display, the disparity between the left side and right side is painfully apparent. It looks wrong to have curved corners on one side and rounded edges on the other, even if you don't actually see that when the phone is unfolded.</p><p>The Z Fold 8 and Z Fold 8 Ultra are the total opposite, with a symmetrical design regardless of which screen you're actually looking at — and it makes Galaxy foldables all the better to look at. Plus, you're likely to get a little bit more screen space <a href="https://www.tomsguide.com/phones/samsung-phones/does-the-galaxy-z-fold-8-ultra-make-the-most-use-of-its-screen-space-i-streamed-a-bunch-of-movies-and-tv-shows-to-find-out">if you're using the phone in certain display configurations.</a></p><h3 class="article-body__section" id="section-the-esim-only-design"><span>The eSIM only design</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3000px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="Z4xNVatT98sDPTLnax5YtC" name="GettyImages-921346060.jpg" alt="eSIM" src="https://cdn.mos.cms.futurecdn.net/Z4xNVatT98sDPTLnax5YtC-1920-80.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: AndreyPopov)</span></figcaption></figure><p>Apple has been aggressively pushing eSIMs the past few years, and that's led to a foldable with no support for physical SIM cards — regardless of which part of the world you buy it in. Samsung, on the other hand, has stuck to the physical nano SIM slot on all its flagship phones — and it should continue that trend for Z Fold 9.</p><p>I get the appeal of eSIMs in certain situations, but I also feel as though they come with a key disadvantage compared to physical SIM cards. A physical SIM pops out of your phone and into another device without issue, while eSIMs have to be digitally transferred. The process is not as awkward or laborious as it used to be, but it's still not as convenient.</p><p>If you prefer eSIMs, that's great, more power to you. But it's good to offer users a choice on how they connect to cell networks, rather than deciding for you and giving you no flexibility. Which is a very Apple way of doing things.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom’s Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-iphone-18-pro-your-10-biggest-questions-answered">I've been testing the iPhone 18 Pro Max and iPhone 18 Pro — your 10 biggest questions answered</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-teardown-reveals-the-ins-and-outs-of-the-latest-iphone-models-including-one-annoying-repair-issue">iPhone 18 Pro teardown reveals the ins and outs of the latest iPhone models — including one annoying repair issue</a></li><li><a href="https://www.tomsguide.com/phones/iphones/apples-usd250-million-class-action-settlement-website-is-now-open-heres-how-eligible-iphone-owners-can-file-a-claim-and-how-much-theyll-get">Apple's $250 million class action settlement website is now open — here's how eligible iPhone owners can file a claim and how much they'll get</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/5-things-galaxy-z-fold-9-needs-to-steal-from-iphone-duo-and-2-it-shouldnt</link>
                                                                            <description>
                            <![CDATA[ Samsung Galaxy Z Fold 9 is going to need to copy these iPhone Duo features if it wants to avoid being knocked off the top spot. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">oAEvPxR7JwegDPSQ2aA38b</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/NE3m4C3QUpw7U8uQfUAmea-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 22 Sep 2026 04:30:00 +0000</pubDate>                                                                                                                                <updated>Tue, 22 Sep 2026 08:42:09 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Samsung Phones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                    <category><![CDATA[Android Phones]]></category>
                                                                                                <author><![CDATA[ tom.pritchard@futurenet.com (Tom Pritchard) ]]></author>                    <dc:creator><![CDATA[ Tom Pritchard ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/biCewUkKfSA6QnT2HxVc3f-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/NE3m4C3QUpw7U8uQfUAmea-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[IPhone duo vs galaxy Z Fold 8]]></media:description>                                                            <media:text><![CDATA[IPhone duo vs galaxy Z Fold 8]]></media:text>
                                <media:title type="plain"><![CDATA[IPhone duo vs galaxy Z Fold 8]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/NE3m4C3QUpw7U8uQfUAmea-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> is ticking all of the right boxes at the moment, wowing just about everyone that's been able to use it ahead of its official release Oct. 23. We still don't know how much of a success the phone will be, especially considering the $2,000 price tag, but you can be sure other phone makers are watching closely — especially Samsung.</p><p>Samsung has been the de-factor king of the foldable phone business for several years. Mainly because, outside of China, the <a href="https://www.tomsguide.com/best-picks/best-foldable-phones">best foldables</a> have been limited to Google and Motorola — who haven't exactly put up much of a fight. Apple could finally bring the Galaxy Fold series some serious competition, and if I were Samsung I'd be looking for ways to make my foldables stand out. Even if it means blatantly copying Apple's ideas.</p><p>Here are five things the Galaxy Z Fold 9 should steal from iPhone Duo, and two things it should leave well alone.</p><h2 id="what-z-fold-9-should-steal-from-iphone-duo">What Z Fold 9 should steal from iPhone Duo</h2><h3 class="article-body__section" id="section-under-display-camera"><span>Under display camera</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="Mdj8kozN6J8WNXPhazFQFa" name="iPhone Duo edit 1" alt="iPhone Duo" src="https://cdn.mos.cms.futurecdn.net/Mdj8kozN6J8WNXPhazFQFa-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Samsung had under-display cameras on the Galaxy Z Fold lineup for four generations, from the <a href="https://www.tomsguide.com/reviews/samsung-galaxy-z-fold-3">Galaxy Z Fold 3</a> to <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-6-review-test-results">Z Fold 6</a>. The quality of those cameras was a little... weak, to say the least, so it's no surprise that Samsung pulled them for the last two generations. But maybe now is the time to bring them back.</p><p>Apple has added an under-display camera to the iPhone Duo's foldable display, though this one isn't designed for selfies. Apple has referred to it as a FaceTime camera, and talked about its use as an aid for video calling. That suggests the quality isn't all that either, but by limiting its use cases (at least in marketing) Apple can avoid the same criticisms as Samsung.</p><p>This means the Z Fold 9 could be the perfect time for Samsung to bring the under-display camera back — and give you more of your screen back. Plus, considering you can already take selfies with the rear cameras and the hole-punch on the cover display, I'd avoid using it as a way to take photos of yourself.</p><h3 class="article-body__section" id="section-s-pen-support"><span>S Pen support</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="JUVSwuTeFABcGUzkRL8WtU" name="Galaxy Z Fold 6 and S Pen.jpg" alt="Samsung Galaxy Z Fold 6 and S Pen" src="https://cdn.mos.cms.futurecdn.net/JUVSwuTeFABcGUzkRL8WtU-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The loss of the stylus is one of the things Galaxy foldable fans have been complaining about since the release of <a href="https://www.tomsguide.com/phones/samsung-galaxy-z-fold-7-review">Galaxy Z Fold 7</a>. The stylus requires a special digitizer layer in the display, which was removed in an apparent attempt to reduce thickness. Which isn't a great reason to remove a long-standing feature, especially when it leaves Galaxy foldables feeling a little bit lacking.</p><p>Not only does the<a href="https://www.tomsguide.com/phones/iphones/steve-jobs-said-there-would-never-be-an-iphone-stylus-but-iphone-duo-just-proved-him-wrong-and-itll-be-a-better-device-for-it"> iPhone Duo have stylus support, it uses the Apple Pencil USB-C</a> — which is compatible with almost every iPad on sale. There's no special iPhone-exclusive stylus; it's the one a lot of iPad users may already have. The same couldn't be said for past Z Fold models, which needed a special foldable-exclusive stylus designed for the more fragile folding display.</p><p>I felt that the Galaxy Z Fold 8 Ultra was missing out on account of its lost stylus, and the launch of Z Fold 9 would be the perfect opportunity to reintroduce that support. Ideally, it would the form of a stylus that will work across Galaxy devices, including tablets and other phones.</p><h3 class="article-body__section" id="section-ip68-durability"><span>IP68 durability</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="F6qr2SDN3gLqxsmgpqVYsY" name="Fold 8 back 2" alt="Samsung Galaxy Z Fold 8" src="https://cdn.mos.cms.futurecdn.net/F6qr2SDN3gLqxsmgpqVYsY-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Google was the first foldable phone maker in the U.S. to add IP68 water and dust resistance to foldables with <a href="https://www.tomsguide.com/phones/google-pixel-phones/pixel-10-pro-fold-review">Pixel 10 Pro Fold</a>, and Apple has followed its example with iPhone Duo. Galaxy Z Fold 8, on the other hand only has an IP48 rating, which means it's totally exposed to dust — even if it is sealed tight against water.</p><p>Obviously, that's not a good look for Samsung, especially when you consider all the moving parts associated with a foldable hinge. You should be able to take your $1,900 to $2,000 foldable to the beach. So Samsung definitely needs to do better with the Z Fold 9.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-exgNKX"></div>                            </div>                            <script src="https://kwizly.com/embed/exgNKX.js" async></script><h3 class="article-body__section" id="section-magnetic-wireless-charging-built-in"><span>Magnetic wireless charging built in</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="q4DNX2SeEFU5sCTTt45wEa" name="iphone duo edit 5" alt="iPhone Duo" src="https://cdn.mos.cms.futurecdn.net/q4DNX2SeEFU5sCTTt45wEa-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>One of the things I'll never understand is why Samsung is so <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-may-skip-adding-qi2-to-the-galaxy-s26-ultra-and-i-think-theyve-made-the-right-call">seemingly against adding magnetic wireless charging</a> to its phones — foldables included. The phones support Qi2 wireless charging technology, but they lack the integrated magnets that let chargers and accessories snap into place.</p><p>One reason I was given was that<a href="https://www.tomsguide.com/phones/samsung-phones/samsung-may-skip-adding-qi2-to-the-galaxy-s26-ultra-and-i-think-theyve-made-the-right-call"> the magnets interfered with the S Pen</a>, and Samsung couldn't offer both. But considering the iPhone Duo has Apple Pencil support and MagSafe, it's clear that there is a way to offer both features without asking users to compromise. Because a magnetic case system is just a poor show for a phone company that sells devices for close to two thousand dollars.</p><h3 class="article-body__section" id="section-an-actual-vapor-chamber"><span>An actual Vapor Chamber</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:3330px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="tgL6AweqbNKzVVmQctz95Z" name="Galaxy Z Fold 8 review-22" alt="Galaxy Z Fold 8 shown held in-hand" src="https://cdn.mos.cms.futurecdn.net/tgL6AweqbNKzVVmQctz95Z-1920-80.jpg" mos="" align="middle" fullscreen="" width="3330" height="1873" attribution="" endorsement="" class="inline"></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 Snapdragon 8 Elite Gen 5 for Galaxy chipset is powerful. But the phones that use it can get quite hot, and a lack of cooling can lead to worse sustained performance.That's why Samsung needs to add a vapor chamber, much like the Galaxy S26 Ultra and the iPhone Duo.</p><p>Vapor chambers help move heat across the phone, allowing it to dissipate more evenly, and keep key components from overheating. It also helps improve sustained performance, and les the phone work harder for longer. </p><p>Admittedly, the Z Fold 8 does have pretty good sustained performance compared to the S26 Ultra (72.4% versus 53.9%) but it's behind the iPhone 18 Pro Max (79.4%), But can you imagine how much better things could be if there was a vapor chamber to help keep everything cool?</p><h2 id="two-things-iphone-duo-can-keep">Two things iPhone Duo can keep</h2><h3 class="article-body__section" id="section-curved-corners"><span>Curved corners</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:2144px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4oMko37sfDNte8KzjvzD2M" name="Apple iPhone Duo hands on-3" alt="Apple iPhone Duo shown in hand" src="https://cdn.mos.cms.futurecdn.net/4oMko37sfDNte8KzjvzD2M-1920-80.jpg" mos="" align="middle" fullscreen="" width="2144" height="1206" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Apple loves curved corners on its phones, a design that has made its way to foldables as well. Samsung may have opted for more curved corners on its non-folding phones, like Galaxy S26, but for the time being foldables have retained the sharper right-angles Samsung was once known for. The Galaxy Z Fold 9 should stay the same way.</p><p>My issue with the iPhone Duo is the lack of symmetry in the design. If you look at it from the cover display, the disparity between the left side and right side is painfully apparent. It looks wrong to have curved corners on one side and rounded edges on the other, even if you don't actually see that when the phone is unfolded.</p><p>The Z Fold 8 and Z Fold 8 Ultra are the total opposite, with a symmetrical design regardless of which screen you're actually looking at — and it makes Galaxy foldables all the better to look at. Plus, you're likely to get a little bit more screen space <a href="https://www.tomsguide.com/phones/samsung-phones/does-the-galaxy-z-fold-8-ultra-make-the-most-use-of-its-screen-space-i-streamed-a-bunch-of-movies-and-tv-shows-to-find-out">if you're using the phone in certain display configurations.</a></p><h3 class="article-body__section" id="section-the-esim-only-design"><span>The eSIM only design</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3000px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="Z4xNVatT98sDPTLnax5YtC" name="GettyImages-921346060.jpg" alt="eSIM" src="https://cdn.mos.cms.futurecdn.net/Z4xNVatT98sDPTLnax5YtC-1920-80.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: AndreyPopov)</span></figcaption></figure><p>Apple has been aggressively pushing eSIMs the past few years, and that's led to a foldable with no support for physical SIM cards — regardless of which part of the world you buy it in. Samsung, on the other hand, has stuck to the physical nano SIM slot on all its flagship phones — and it should continue that trend for Z Fold 9.</p><p>I get the appeal of eSIMs in certain situations, but I also feel as though they come with a key disadvantage compared to physical SIM cards. A physical SIM pops out of your phone and into another device without issue, while eSIMs have to be digitally transferred. The process is not as awkward or laborious as it used to be, but it's still not as convenient.</p><p>If you prefer eSIMs, that's great, more power to you. But it's good to offer users a choice on how they connect to cell networks, rather than deciding for you and giving you no flexibility. Which is a very Apple way of doing things.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom’s Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-iphone-18-pro-your-10-biggest-questions-answered">I've been testing the iPhone 18 Pro Max and iPhone 18 Pro — your 10 biggest questions answered</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-teardown-reveals-the-ins-and-outs-of-the-latest-iphone-models-including-one-annoying-repair-issue">iPhone 18 Pro teardown reveals the ins and outs of the latest iPhone models — including one annoying repair issue</a></li><li><a href="https://www.tomsguide.com/phones/iphones/apples-usd250-million-class-action-settlement-website-is-now-open-heres-how-eligible-iphone-owners-can-file-a-claim-and-how-much-theyll-get">Apple's $250 million class action settlement website is now open — here's how eligible iPhone owners can file a claim and how much they'll get</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 36 million iPhone owners can soon get paid from $250 million Apple Siri lawsuit — how to claim your share ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Apple <a href="https://www.tomsguide.com/phones/iphones/apple-agrees-usd250m-settlement-over-siri-class-action-lawsuit-that-means-up-to-36m-iphone-users-could-be-eligible-for-a-pay-out-this-is-how-much-you-could-receive">settled a $250 million class action lawsuit</a> over claims of false advertising about Siri's AI capabilities in May of this year. The settlement allows up to 36 million iPhone users in the U.S. to receive up to $95.</p><p>That window is finally opening, but it runs for only three months, starting Monday, September 21. Here's what you need to know to claim your share of the settlement. </p><h2 id="how-we-got-here">How we got here</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="EjLomL6cUAsVygMTKgKWJK" name="Siri AI edit 1" alt="Siri AI" src="https://cdn.mos.cms.futurecdn.net/EjLomL6cUAsVygMTKgKWJK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The lawsuit was <a href="https://www.tomsguide.com/ai/apple-intelligence/apple-responds-to-siri-lawsuit-heres-how-it-claims-to-protect-your-data">initially filed in California in 2024</a> by Peter Landsheft after Apple promoted its more "personalized Siri" and the introduction of Apple Intelligence. The National Advertising Division bolstered the lawsuit, concluding that Apple misled users by claiming the new Siri was "now available."</p><p>Apple filed the settlement, which includes no admissions of wrongdoing, on May 5. "We resolved this matter to stay focused on doing what we do ⁠best, delivering ​the most innovative products and ​services to our users," the company said in a statement.</p><p>“False advertising settlements aim to raise the floor of truth-telling, protect fair competition, and increase consumer choice. The $250 million settlement fund represents the largest false advertising settlement in history, and we are proud to have achieved this result for Apple customers," Ryan Clarkson, one of the lawyers on the case, said in a statement to Tom's Guide.</p><h2 id="eligibility-and-how-to-claim">Eligibility and how to claim</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3751px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="3k6Adi4EV6vZt9CvUkYDPo" name="iPhone 15 Pro vs iPhone 15 Pro Max.jpg" alt="iPhone 15 Pro Max and iPhone 15 Pro cameras" src="https://cdn.mos.cms.futurecdn.net/3k6Adi4EV6vZt9CvUkYDPo-1920-80.jpg" mos="" align="middle" fullscreen="" width="3751" height="2110" attribution="" endorsement="" 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 settlement covers roughly 36 million iPhones, including the <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-16-review">iPhone 16</a>, <a href="https://www.tomsguide.com/reviews/iphone-15-pro">iPhone 15 Pro</a> and <a href="https://www.tomsguide.com/reviews/iphone-15-pro-max">iPhone 15 Pro Max.</a> All of which must have been <strong>purchased in the U.S. between June 10, 2024, and March 29, 2025</strong>. </p><p>The window for entering a claim starts <strong>September 21 and closes on December 21, 2026</strong>.</p><p>You can enter a claim by going to <a href="https://smartphoneaisettlement.com/" target="_blank">SmartphoneAISettlement.com</a>. You will need your device's serial number. You can find the number by opening Settings, going to General, tapping About, and scrolling to Serial Number.</p><p>As for payout, claimants will receive at least $25 per device and up to $95, depending on how many claims are submitted. </p><p>Final approval by a judge won't happen until February 24, 2027, and Apple will have a set number of days after that to issue payments. Typically, those windows are 180 days.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/apple-increased-the-price-of-iphone-18-pro-battery-repairs-heres-how-much-youll-pay-now"><strong>Apple increased the price of iPhone 18 Pro battery repairs — here's how much you'll pay now</strong></a></li><li><a href="https://www.tomsguide.com/phones/iphones/siri-in-ios-27-actually-lives-up-to-the-hype-here-are-the-3-truly-unique-uses"><strong>Siri in iOS 27 actually lives up to the hype — here are 3 truly unique uses</strong></a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-ultra-4-review"><strong>Apple Watch Ultra 4 review: I ran 22 miles to test Apple’s ultimate adventure watch</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/36-million-iphone-owners-can-soon-get-paid-from-usd250-million-apple-siri-false-advertising-lawsuit-how-to-claim-your-share</link>
                                                                            <description>
                            <![CDATA[ Months after settling, the claims window for Apple's $250m settlement is finally opening ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">njPc6Sj28832xJibDTPR5a</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/AFwjWBtTjiru8PAQgLdDX7-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 22 Sep 2026 04:00:00 +0000</pubDate>                                                                                                                                <updated>Tue, 22 Sep 2026 09:56:29 +0000</updated>
                                                                                                                                            <category><![CDATA[AI]]></category>
                                                    <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ scott.younker@futurenet.com (Scott Younker) ]]></author>                    <dc:creator><![CDATA[ Scott Younker ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/RZsUpqcJ6Uj2q83oCUwNhQ-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Scott Younker is the West Coast Reporter at Tom’s Guide. He covers all the latest tech news, including phones, computing and more. He’s been involved in tech since 2011 covering everything from cameras and swimming pool equipment to the latest gaming consoles and smart TVs. He is on a seemingly never ending hunt to build the easiest to use home media system. &lt;/p&gt;&lt;p&gt;Before Tom’s Guide, Scott worked for publications like &lt;em&gt;Digital Trends, Outdoor Photographer, Dead Beats Panel&lt;/em&gt;, and in a brief detour, &lt;em&gt;America’s Funniest Home Videos&lt;/em&gt;. Yes, he has seen more pratfalls, silly pets and ridiculous home movie fails than is reasonably healthy. &lt;/p&gt;&lt;p&gt;When not writing about the latest devices or advances in chipsets, be sure to ask about Scott about disc golf and sustainability, or just if you’re being cheeky, ask about his noodle arm. If you truly want to get nerdy, bring up board games and his ongoing losing streak. &lt;/p&gt;&lt;p&gt;Scott joined Tom&#039;s Guide in 2024 as the West Coast Reporter. He graduated from the School of Journalism at the University of Oregon with a degree in magazine journalism and a minor in communications. While there he blogged or wrote for several magazines including the Fluxx, Ethos and the Oregon Commentator. He briefly wrote and managed a moderately successful blog focused on web comics. &lt;br&gt;Send secure tips on Signal: scyo1.55.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/AFwjWBtTjiru8PAQgLdDX7-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Apple Store with white Apple logo ]]></media:description>                                                            <media:text><![CDATA[Apple Store with white Apple logo ]]></media:text>
                                <media:title type="plain"><![CDATA[Apple Store with white Apple logo ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/AFwjWBtTjiru8PAQgLdDX7-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Apple <a href="https://www.tomsguide.com/phones/iphones/apple-agrees-usd250m-settlement-over-siri-class-action-lawsuit-that-means-up-to-36m-iphone-users-could-be-eligible-for-a-pay-out-this-is-how-much-you-could-receive">settled a $250 million class action lawsuit</a> over claims of false advertising about Siri's AI capabilities in May of this year. The settlement allows up to 36 million iPhone users in the U.S. to receive up to $95.</p><p>That window is finally opening, but it runs for only three months, starting Monday, September 21. Here's what you need to know to claim your share of the settlement. </p><h2 id="how-we-got-here">How we got here</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="EjLomL6cUAsVygMTKgKWJK" name="Siri AI edit 1" alt="Siri AI" src="https://cdn.mos.cms.futurecdn.net/EjLomL6cUAsVygMTKgKWJK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The lawsuit was <a href="https://www.tomsguide.com/ai/apple-intelligence/apple-responds-to-siri-lawsuit-heres-how-it-claims-to-protect-your-data">initially filed in California in 2024</a> by Peter Landsheft after Apple promoted its more "personalized Siri" and the introduction of Apple Intelligence. The National Advertising Division bolstered the lawsuit, concluding that Apple misled users by claiming the new Siri was "now available."</p><p>Apple filed the settlement, which includes no admissions of wrongdoing, on May 5. "We resolved this matter to stay focused on doing what we do ⁠best, delivering ​the most innovative products and ​services to our users," the company said in a statement.</p><p>“False advertising settlements aim to raise the floor of truth-telling, protect fair competition, and increase consumer choice. The $250 million settlement fund represents the largest false advertising settlement in history, and we are proud to have achieved this result for Apple customers," Ryan Clarkson, one of the lawyers on the case, said in a statement to Tom's Guide.</p><h2 id="eligibility-and-how-to-claim">Eligibility and how to claim</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3751px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="3k6Adi4EV6vZt9CvUkYDPo" name="iPhone 15 Pro vs iPhone 15 Pro Max.jpg" alt="iPhone 15 Pro Max and iPhone 15 Pro cameras" src="https://cdn.mos.cms.futurecdn.net/3k6Adi4EV6vZt9CvUkYDPo-1920-80.jpg" mos="" align="middle" fullscreen="" width="3751" height="2110" attribution="" endorsement="" 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 settlement covers roughly 36 million iPhones, including the <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-16-review">iPhone 16</a>, <a href="https://www.tomsguide.com/reviews/iphone-15-pro">iPhone 15 Pro</a> and <a href="https://www.tomsguide.com/reviews/iphone-15-pro-max">iPhone 15 Pro Max.</a> All of which must have been <strong>purchased in the U.S. between June 10, 2024, and March 29, 2025</strong>. </p><p>The window for entering a claim starts <strong>September 21 and closes on December 21, 2026</strong>.</p><p>You can enter a claim by going to <a href="https://smartphoneaisettlement.com/" target="_blank">SmartphoneAISettlement.com</a>. You will need your device's serial number. You can find the number by opening Settings, going to General, tapping About, and scrolling to Serial Number.</p><p>As for payout, claimants will receive at least $25 per device and up to $95, depending on how many claims are submitted. </p><p>Final approval by a judge won't happen until February 24, 2027, and Apple will have a set number of days after that to issue payments. Typically, those windows are 180 days.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/apple-increased-the-price-of-iphone-18-pro-battery-repairs-heres-how-much-youll-pay-now"><strong>Apple increased the price of iPhone 18 Pro battery repairs — here's how much you'll pay now</strong></a></li><li><a href="https://www.tomsguide.com/phones/iphones/siri-in-ios-27-actually-lives-up-to-the-hype-here-are-the-3-truly-unique-uses"><strong>Siri in iOS 27 actually lives up to the hype — here are 3 truly unique uses</strong></a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-ultra-4-review"><strong>Apple Watch Ultra 4 review: I ran 22 miles to test Apple’s ultimate adventure watch</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ T-Mobile has the best iPhone 18 Pro freebie deals: here's how to get one ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Apple's new iPhones are officially on sale and there are dozens of <a href="https://www.tomsguide.com/phones/iphones/best-iphone-18-pro-and-pro-max-deals">iPhone 18 Pro deals</a> to choose from. However, my favorite freebie deals come from T-Mobile. </p><p>Right now, <a href="https://tmobilepostpaid.pxf.io/c/1943169/4032247/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow">T-Mobile is offering the iPhone 18 Pro for free</a> when you bring your number and open an Experience Beyond plan. Or you can get it for free with trade-in and an Experience Beyond plan. Meanwhile, <a href="https://tmobilepostpaid.pxf.io/c/1943169/4032248/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow">T-Mobile is also taking up to $1,200 off the iPhone 18 Pro Max</a> with trade-in and Experience Beyond plan. Here's how you can get yours. </p><h3 class="article-body__section" id="section-quick-links"><span>Quick Links</span></h3><ul><li><strong>iPhone 18 Pro: </strong><a href="https://tmobilepostpaid.pxf.io/c/1943169/4032247/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow"><strong>free w/ new line + unlimited </strong></a><strong></strong></li><li><strong>iPhone 18 Pro Max: </strong><a href="https://tmobilepostpaid.pxf.io/c/1943169/4032248/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow"><strong>up to $1,200 off w/ unlimited</strong></a><strong></strong></li></ul><h3 class="article-body__section" id="section-iphone-18-pro"><span>iPhone 18 Pro</span></h3><div class="product"><a data-dimension112="7875e560-b604-11f1-ac18-09499ce3e148" data-action="Deal Block" data-label="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" href="https://tmobilepostpaid.pxf.io/c/1943169/4032247/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:50.00%;"><img id="Y26QJd7Ff7aeQmTHuW8nCP" name="NEW T-Mobile Logo" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Y26QJd7Ff7aeQmTHuW8nCP-1920-80.png" mos="" align="middle" fullscreen="" width="600" height="300" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro: </strong><a href="https://tmobilepostpaid.pxf.io/c/1943169/4032247/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow" data-dimension112="7875e560-b604-11f1-ac18-09499ce3e148" data-action="Deal Block" data-label="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension25=""><strong>free w/ trade-in + unlimited @ T-Mobile</strong></a><br>T-Mobile is offering the iPhone 18 Pro for free when you switch and bring your number or when you trade-in an eligible phone and sign up for T-Mobile's Experience Beyond plan. The iPhone 18 Pro features a 6.3-inch OLED 120Hz display (2622 x 1206), A20 Pro chipset, and 256GB of storage. You also get a 48MP main, 48MP ultrawide, and 48MP telephoto lens w/ 4x zoom. The front camera is 18MP. <a class="view-deal button" href="https://tmobilepostpaid.pxf.io/c/1943169/4032247/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow" data-dimension112="7875e560-b604-11f1-ac18-09499ce3e148" data-action="Deal Block" data-label="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension25="">View Deal</a></p></div><h3 class="article-body__section" id="section-iphone-18-pro-max"><span>iPhone 18 Pro Max</span></h3><div class="product"><a data-dimension112="7875e6be-b604-11f1-87af-3f845dce4e6c" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" href="https://tmobilepostpaid.pxf.io/c/1943169/4032248/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:50.00%;"><img id="Y26QJd7Ff7aeQmTHuW8nCP" name="NEW T-Mobile Logo" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Y26QJd7Ff7aeQmTHuW8nCP-1920-80.png" mos="" align="middle" fullscreen="" width="600" height="300" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro Max: </strong><a href="https://tmobilepostpaid.pxf.io/c/1943169/4032248/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow" data-dimension112="7875e6be-b604-11f1-87af-3f845dce4e6c" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension25=""><strong>up to $1,200 off w/ trade-in + unlimited @ T-Mobile</strong></a><br>T-Mobile is taking up to $1,200 off the iPhone 18 Pro Max when you trade-in an old device and sign up for an eligible unlimited data plan. The iPhone 18 Pro Max features a 6.9-inch OLED 120Hz display (2868 x 1320), A20 Pro chipset, and 256GB of storage. You also get a 48MP main, 48MP ultrawide, and 48MP telephoto lens w/ 4x zoom. The front camera is 18MP.<a class="view-deal button" href="https://tmobilepostpaid.pxf.io/c/1943169/4032248/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow" data-dimension112="7875e6be-b604-11f1-87af-3f845dce4e6c" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension25="">View Deal</a></p></div><h3 class="article-body__section" id="section-what-s-new"><span>What's new</span></h3><p>The 6.3-inch <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro</a> and 6.9-inch <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max</a> cost $1,199 and $1,299, respectively. Yes, that's $100 pricier than their predecessors, which is why T-Mobile's deals are so great. The carrier is offering various ways to save on your new iPhone. </p><p>As for the phones, they generally stick to Apple's familiar playbook. They feature rigid enclosures, proven water resistance, and toughened glass surfaces that have repeatedly demonstrated they can take real-world abuse. Both phones offer rock solid reliability, so which phone you get depends on how big of a screen you want and how much battery life you require. </p><p>The former packs a 6.3-inch OLED display, whereas the iPhone 18 Pro Max sports a larger 6.9-inch OLED screen. No matter which phone you get, you'll be in for a treat as they are Apple's flagship Pro devices. Stay tuned to Tom's Guide for all of the best Apple deals. </p><h3 class="article-body__section" id="section-shop-more-deals"><span>Shop more deals</span></h3><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?search=Everything&rows=8&view_mode=savings_squad&widget_title=Top+Deals+Handpicked+by+Our+Editors&widget_subtitle=Discover+the+best+discounts+currently+available%2C+curated+daily+by+the+Tom%27s+Guide+Savings+Squad.&bg_color=transparent" data-vizualizer-embed="true"></div>    <script>    /**     * Tom's Guide Deals Finder - Vanilla JS Encapsulated Engine     */    (function() {      // --- Freyr Analytics Adapter ---      function initAnalytics() {        window.dataLayer = window.dataLayer || [];        window.googletag = window.googletag || {};        window.googletag.cmd = window.googletag.cmd || [];        window.hawk = window.hawk || { analytics: { freyr: [] } };        window.hawk.analytics = window.hawk.analytics || { freyr: [] };        window.hawk.analytics.freyr = window.hawk.analytics.freyr || [];        window.freyr = window.freyr || { cmd: [] };        const scriptSrc = 'https://freyr.futurecdn.net/freyr.js';        const hostname = typeof window !== 'undefined' ? window.location.hostname : '';        const isTestEnv = typeof window.navigator !== 'undefined' && (window.navigator.webdriver || window.navigator.userAgent.includes('Headless'));        const shouldSendRealAnalytics = !isTestEnv && hostname && hostname !== 'localhost' && hostname !== '127.0.0.1' && !hostname.includes('run.app');        if (shouldSendRealAnalytics && !document.querySelector(`script[src="${scriptSrc}"]`)) {          const script = document.createElement('script');          script.src = scriptSrc;          script.async = true;          document.head.appendChild(script);        }      }      function storeEventForDebug(name, data) {        if (!window.hawk || !window.hawk.analytics || !window.hawk.analytics.freyr) return;        window.hawk.analytics.freyr.push({ name, data });        try {          if (typeof window !== 'undefined' && window.localStorage) {            window.localStorage.setItem("hawk", JSON.stringify(window.hawk));          }        } catch (e) {          // Ignore storage issues        }        try {          window.dispatchEvent(new CustomEvent("hawk-analytics-update"));        } catch (e) {}      }      function sendToFreyr(eventName, data) {        if (typeof window === 'undefined') return;        window.freyr = window.freyr || { cmd: [] };        window.freyr.cmd.push(() => {          if (window.freyr && window.freyr.pushAndUpdate) {            window.freyr.pushAndUpdate(eventName, data);          }        });      }      function sendEvent(event, skip = false) {        try {          storeEventForDebug(event.name, event.data);          if (!skip) {            sendToFreyr(event.name, event.data);          }        } catch (e) {          // Ensure tracking errors don't surface to the user        }      }      function getCookie(name) {        try {          const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));          return match ? match[2] : null;        } catch (e) {          return null;        }      }      function getTimeAgo(dateString) {        if (!dateString) return '';        const date = new Date(dateString);        const now = new Date();        const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);        if (diffInSeconds < 60) return 'Just now';        const diffInMinutes = Math.floor(diffInSeconds / 60);        if (diffInMinutes < 60) return `${diffInMinutes} min${diffInMinutes > 1 ? 's' : ''} ago`;        const diffInHours = Math.floor(diffInMinutes / 60);        if (diffInHours < 24) return `${diffInHours} hr${diffInHours > 1 ? 's' : ''} ago`;        const diffInDays = Math.floor(diffInHours / 24);        if (diffInDays < 30) return `${diffInDays} day${diffInDays > 1 ? 's' : ''} ago`;        const diffInMonths = Math.floor(diffInDays / 30);        if (diffInMonths < 12) return `${diffInMonths} mo${diffInMonths > 1 ? 's' : ''} ago`;        const diffInYears = Math.floor(diffInDays / 365);        return `${diffInYears} yr${diffInYears > 1 ? 's' : ''} ago`;      }      function normalizeCurrency(symbol) {        const map = {          '£': 'GBP',          '$': 'USD',          'A$': 'AUD',          'CA$': 'CAD',          '€': 'EUR'        };        return map[symbol] || symbol;      }      function trackElementInteraction(props) {        sendEvent({          name: 'elementInteraction',          data: {            element: {              action: props.action || "click",              id: props.id || undefined,              class: props.class || undefined,              name: props.name || undefined,              text: props.text || undefined,              label: props.label || undefined,              container: props.container || undefined,              url: props.url || undefined,              articleId: props.articleId || undefined            }          }        });      }      function generateRevenueId(url, productName, merchantName, modelId) {        const str = `${window.location.href}|${productName}|${merchantName}|${modelId || ''}|${new Date().toDateString()}|tomsguide`;        let hash = 0;        for (let i = 0; i < str.length; i++) {          const char = str.charCodeAt(i);          hash = ((hash << 5) - hash) + char;          hash = hash & hash;        }        let numericStr = Math.abs(hash).toString();        while (numericStr.length < 19) {          numericStr += Math.floor(Math.random() * 10).toString();        }        return numericStr.substring(0, 19);      }      function rewriteAffiliateLink(url, territory, revenueId) {        if (!url) return url;        const t = (territory || 'gb').toLowerCase();        return url.replace(/hawk-custom-tracking/g, `tomsguide-${t}-${revenueId}`);      }      function trackHawkEvent(params) {        const { clickType, widgetId, productCategoryName, product, productsArray, zeroBasedProductIndexOrNull, totalDealsOrProducts, areaClicked, merchant, revenueId, isoCurrencyCode, queryName, widgetTypeName } = params;        const data = {          event: "hawkEvent",          category: "Affiliates",          affiliate: {            action: {              type: clickType,              id: widgetId,              event: clickType === "appeared" ? "viewed" : "Click from",              timestamp: Date.now()            },            component: {              flag: "Editor",              product: productCategoryName || "deals",              category: `Signal Deal Finder ${widgetTypeName || "Carousel"} widget`,              type: clickType === "appeared" ? "review" : "signal product",              label: queryName || (product ? (product.name || "") : ""),              index: zeroBasedProductIndexOrNull === null || zeroBasedProductIndexOrNull === undefined ? -1 : zeroBasedProductIndexOrNull,              linkCount: totalDealsOrProducts || 0,              blockLayout: "",              areaClicked: areaClicked || ""            }          },          products: productsArray || (product && merchant ? [            {              product: {                primary: {                  id: product.id || product.matchId || null,                  name: product.name,                  type: "deal",                  price: product.price,                  previousPrice: product.previousPrice || null,                  currency: isoCurrencyCode || "USD",                  preorder: false,                  labels: [],                  link: product.link,                  originalLink: product.originalLink || null,                  revenueId: revenueId || null,                  startTime: null,                  endTime: null,                  voucherCode: null,                  voucherAudience: null,                  voucherPercentageSaving: null,                  voucherMoneySaving: null,                  voucherType: null,                  offerExclusive: false,                  offerScope: null,                  globalId: product.globalId || null,                  inStock: product.inStock !== false,                  contractProvider: null,                  contractMinutes: null,                  contractTexts: null,                  contractData: null,                  contractLength: null,                  contractMonthlyPrice: null,                  contractCurrency: isoCurrencyCode || "USD"                }              },              merchant: {                id: merchant.id || null,                name: merchant.name,                url: merchant.url || null,                network: merchant.network || null              },              model: {                id: product.modelId || null,                brand: product.brand || null,                name: product.name,                parent: product.parent || null              }            }          ] : []),          reviews: [],          _clear: true,          "gtm.uniqueEventId": Date.now() % 10000        };        sendEvent({ name: 'hawkEvent', data });      }      function trackDealClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Product Card" });      }      function trackViewSimilarClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Product Card View Similar" });      }      function trackPriceComparisonClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Price Comparison" });      }      function trackReviewClick(params) {        trackHawkEvent({ ...params, clickType: "review", areaClicked: "Signal Product Card Review Link" });      }      function trackShare(params) {        trackHawkEvent({ ...params, clickType: "share", areaClicked: "Signal Product Card Share" });      }      function trackDealsAppeared(widgetId, deals, revenueId, currency, queryName, widgetTypeName) {         if (!deals || deals.length === 0) return;                  const productsArray = deals.slice(0, 50).map((deal) => {            let voucherPct = null;            let rawPrice = parseFloat(deal.rawPrice) || parseFloat(deal.price) || null;            let rawMsrp = parseFloat(deal.rawMsrp) || parseFloat(deal.msrp) || null;            if (rawMsrp > rawPrice && rawPrice > 0) {              voucherPct = Math.round((1 - (rawPrice / rawMsrp)) * 100);            }            let numId = null;            if (deal.externalProductId && !isNaN(parseInt(deal.externalProductId))) {              numId = parseInt(deal.externalProductId);            } else if (deal.id && !isNaN(parseInt(deal.id))) {              numId = parseInt(deal.id);            } else {              numId = deal.matchId || null;            }            return {              product: {                primary: {                  id: numId,                  name: deal.productName || deal.title || "",                  type: "deal",                  price: rawPrice,                  previousPrice: rawMsrp,                  currency: currency || 'USD',                  preorder: false,                  labels: deal.modelBrand || deal.brand ? [                     { type: "brand", value: deal.modelBrand || deal.brand }                  ] : [],                  link: deal.url,                  originalLink: deal.url,                  revenueId: revenueId || null,                  startTime: null,                  endTime: null,                  voucherCode: null,                  voucherAudience: null,                  voucherPercentageSaving: voucherPct,                  voucherMoneySaving: null,                  voucherType: null,                  offerExclusive: false,                  offerScope: null,                  globalId: deal.productKey || null,                  inStock: deal.inStock !== false,                  contractProvider: null,                  contractMinutes: null,                  contractTexts: null,                  contractData: null,                  contractLength: null,                  contractMonthlyPrice: null,                  contractCurrency: currency || 'USD'                }              },              merchant: {                id: deal.merchantId ? parseInt(deal.merchantId) : null,                name: deal.merchant || "Retailer",                url: deal.merchantUrl || null,                network: deal.merchantNetwork || null              },              model: {                id: deal.modelId ? parseInt(deal.modelId) : null,                brand: deal.modelBrand || deal.brand || null,                name: deal.productName || deal.title || "",                parent: deal.modelParent || null              }            };         });                  trackHawkEvent({             clickType: "appeared",             widgetId: widgetId,             productCategoryName: "deals",             zeroBasedProductIndexOrNull: null,             totalDealsOrProducts: deals.length,             productsArray: productsArray,             queryName: queryName,             widgetTypeName: widgetTypeName         });      }      // 1. Setup Shadow DOM Sandbox      const currentScript = document.currentScript;      let hostContainer = null;      let template = null;            if (currentScript) {        let prev = currentScript.previousElementSibling;        while (prev) {          if (prev.tagName === 'TEMPLATE' && prev.classList.contains('tg-df-widget-template')) {            template = prev;          } else if (prev.tagName === 'DIV' && prev.classList.contains('tg-df-widget-host') && !prev.hasAttribute('data-initialized')) {            hostContainer = prev;            break;          }          prev = prev.previousElementSibling;        }      }            // Fallbacks in case script is deferred      if (!hostContainer) {        const hosts = document.querySelectorAll('.tg-df-widget-host:not([data-initialized])');        if (hosts.length > 0) hostContainer = hosts[0];      }            // Safely embedded template for CMS environments      const rawTemplate = `  \x3Cstyle>    /* --- Shadow DOM Base Reset --- */    *, *::before, *::after {      box-sizing: border-box;    }    img, picture, svg, video {      max-width: 100%;      height: auto;      display: block;    }    /*       1. Scoped CSS for Tom's Guide Deals Widget       All classes are prefixed with \`tg-df-\` to prevent CMS style leakage.    */    .tg-df-container {      container-type: inline-size;      container-name: tg-df;      --tg-df-blue: #1F69FF;      --tg-df-blue-hover: #004d8c;      --tg-df-text: #222222;      --tg-df-text-muted: #555555;      --tg-df-bg: #ffffff;      --tg-df-bg-secondary: #f4f4f4;      --tg-df-border: #e2e8f0;      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;      color: var(--tg-df-text);      background-color: transparent;       width: 100%;      max-width: 1200px;      margin: 0 auto;      padding-bottom: 24px;    }    .tg-df-container *, .tg-df-container *::before, .tg-df-container *::after {      margin: 0;      padding: 0;      box-sizing: border-box;    }    .tg-df-container img {      border: none;      margin: 0;      padding: 0;    }    .tg-df-container a {      text-decoration: none;      color: inherit;    }    /*       2. Search & Filter Bar    */    .tg-df-controls {      display: flex;      flex-direction: column;      align-items: center;      gap: 20px;      margin-bottom: 32px;      width: 100%;      position: relative;      z-index: 20;    }    .tg-df-top-bar {      display: flex;      width: 100%;      max-width: 760px;      gap: 12px;      margin: 0 auto;      align-items: center;    }    .tg-df-search-wrapper {      position: relative;      flex: 1;      width: 100%;      box-shadow: 0 8px 24px rgba(0,0,0,0.06);      border-radius: 40px;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      z-index: 100;    }    .tg-df-autocomplete-dropdown {      position: absolute;      top: calc(100% + 4px);      left: 0;      right: 0;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 12px;      box-shadow: 0 8px 32px rgba(0,0,0,0.12);      max-height: 300px;      overflow-y: auto;      z-index: 200;      display: none;    }    .tg-df-autocomplete-dropdown.active {      display: block;    }    .tg-df-autocomplete-item {      padding: 12px 24px;      cursor: pointer;      font-size: 14px;      color: var(--tg-df-text);      transition: background 0.1s ease;    }    .tg-df-autocomplete-item:hover {      background: var(--tg-df-bg-secondary);    }    .tg-df-search-input {      width: 100%;      padding: 16px 64px 16px 24px;      font-size: 16px;      border: 2px solid transparent;      border-radius: 40px;      outline: none;      transition: border-color 0.2s ease, box-shadow 0.2s ease;      color: var(--tg-df-text);      background: transparent;    }    .tg-df-search-input:focus {      border-color: transparent;      box-shadow: 0 0 0 3px rgba(0, 108, 196, 0.15);    }    .tg-df-search-input::placeholder {      color: #999999;    }        .tg-df-search-btn {      position: absolute;      right: 8px;      top: 50%;      transform: translateY(-50%);      width: 40px;      height: 40px;      border-radius: 50%;      background: #222;      border: none;      display: flex;      align-items: center;      justify-content: center;      cursor: pointer;      transition: background 0.2s ease;    }        .tg-df-search-btn:hover {      background: #000;    }    .tg-df-search-icon {      width: 16px;      height: 16px;      fill: #fff;    }    .tg-df-settings-wrapper {      position: relative;    }        .tg-df-settings-btn {      width: 48px;      height: 48px;      border-radius: 50%;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      box-shadow: 0 4px 12px rgba(0,0,0,0.04);      display: flex;      align-items: center;      justify-content: center;      cursor: pointer;      transition: all 0.2s ease;      color: var(--tg-df-text-muted);      flex-shrink: 0;    }    .tg-df-settings-btn:hover {      background: var(--tg-df-bg-secondary);      border-color: #0000ff;      color: var(--tg-df-text);    }    .tg-df-settings-btn svg {      width: 24px;      height: 24px;      fill: currentColor;    }    .tg-df-settings-dropdown {      position: absolute;      top: calc(100% + 8px);      right: 0;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 12px;      box-shadow: 0 8px 32px rgba(0,0,0,0.12);      width: 280px;      padding: 20px;      display: none;      z-index: 100;      flex-direction: column;      gap: 20px;    }    .tg-df-settings-dropdown.active {      display: flex;    }        .tg-df-settings-dropdown-backdrop {      display: none;      position: fixed;      inset: 0;      z-index: 99;    }        .tg-df-settings-dropdown-backdrop.active {      display: block;    }    .tg-df-setting-item {      display: flex;      flex-direction: column;      gap: 10px;    }    .tg-df-setting-label {      font-size: 11px;      font-weight: 700;      color: var(--tg-df-text-muted);      text-transform: uppercase;      letter-spacing: 0.5px;    }        .tg-df-region-select {        padding: 10px 12px;        border-radius: 8px;        border: 1px solid var(--tg-df-border);        font-size: 15px;        outline: none;        background: var(--tg-df-bg-secondary);        color: var(--tg-df-text);        cursor: pointer;        width: 100%;    }    .tg-df-toggle {        position: relative;        display: inline-block;        width: 44px;        height: 24px;        flex-shrink: 0;    }    .tg-df-toggle input {        opacity: 0;        width: 0;        height: 0;    }    .tg-df-slider {        position: absolute;        cursor: pointer;        top: 0; left: 0; right: 0; bottom: 0;        background-color: #ccc;        transition: .2s;        border-radius: 24px;    }    .tg-df-slider:before {        position: absolute;        content: "";        height: 18px;        width: 18px;        left: 3px;        bottom: 3px;        background-color: white;        transition: .2s;        border-radius: 50%;    }    .tg-df-toggle input:checked + .tg-df-slider {        background-color: #1F69FF;    }    .tg-df-toggle input:checked + .tg-df-slider:before {        transform: translateX(20px);    }    .tg-df-dl-row {        flex-direction: row;        align-items: center;        justify-content: space-between;    }    .tg-df-dl-row-text {        font-size: 14px;        font-weight: 600;        color: var(--tg-df-text);    }    .tg-df-dl-row-subtext {        font-size: 12px;        font-weight: 400;        line-height: 1.3;        color: var(--tg-df-text-muted);        margin-top: 4px;        display: block;    }    .tg-df-filters-container {      position: relative;      width: 100%;      max-width: 800px;    }    .tg-df-scroll-btn {      display: none;      position: absolute;      top: 50%;      transform: translateY(-50%);      width: 32px;      height: 32px;      background: white;      border: 1px solid var(--tg-df-border);      border-radius: 50%;      align-items: center;      justify-content: center;      cursor: pointer;      z-index: 10;      box-shadow: 0 2px 8px rgba(0,0,0,0.1);      color: var(--tg-df-text-primary);      padding: 0;    }    .tg-df-scroll-btn svg {      width: 16px;      height: 16px;    }    .tg-df-scroll-btn:hover {      background: #f4f4f4;    }    .tg-df-scroll-btn.left {      left: 0px;    }    .tg-df-scroll-btn.right {      right: 0px;    }    @container tg-df (max-width: 768px) {      .tg-df-scroll-btn {        display: flex;        top: 22px; /* vertically center within the 44px high filter buttons */      }    }    .tg-df-filters {      display: grid;      width: 100%;      grid-template-columns: repeat(4, 1fr);      gap: 12px;      margin: 0 auto;      max-width: 800px;    }                 .tg-df-sort-wrapper {      position: relative;      display: flex;      align-items: center;      width: 100%;    }        .tg-df-sort-icon {      position: absolute;      left: 14px;      width: 14px;      height: 14px;      fill: var(--tg-df-text-muted);      pointer-events: none;    }    .tg-df-sort-select, .tg-df-filter-select {      width: 100%;      padding: 10px 36px 10px 38px;      font-size: 14px;      border: 1px solid var(--tg-df-border);      border-radius: 100px;      outline: none;      appearance: none;      background-color: var(--tg-df-bg-secondary);      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12'%3E%3Cpath fill='%23555555' d='M6 8L1 3h10z'/%3E%3C/svg%3E");      background-repeat: no-repeat;      background-position: right 14px center;      color: var(--tg-df-text);      cursor: pointer;      font-weight: 500;      transition: all 0.2s ease;    }        .tg-df-price-input::-webkit-outer-spin-button,    .tg-df-price-input::-webkit-inner-spin-button {      -webkit-appearance: none;      margin: 0;    }    .tg-df-price-input {      -moz-appearance: textfield;    }    .tg-df-sort-select:hover, .tg-df-filter-select:hover {      background-color: #e2e8f0;    }    .tg-df-multiselect-container {      position: relative;    }    @container tg-df (max-width: 768px) {      .tg-df-filters-container {      position: relative;      width: 100%;      max-width: 800px;    }    .tg-df-scroll-btn {      display: none;      position: absolute;      top: 50%;      transform: translateY(-50%);      width: 32px;      height: 32px;      background: white;      border: 1px solid var(--tg-df-border);      border-radius: 50%;      align-items: center;      justify-content: center;      cursor: pointer;      z-index: 10;      box-shadow: 0 2px 8px rgba(0,0,0,0.1);      color: var(--tg-df-text-primary);      padding: 0;    }    .tg-df-scroll-btn svg {      width: 16px;      height: 16px;    }    .tg-df-scroll-btn:hover {      background: #f4f4f4;    }    .tg-df-scroll-btn.left {      left: 0px;    }    .tg-df-scroll-btn.right {      right: 0px;    }    @container tg-df (max-width: 768px) {      .tg-df-scroll-btn {        display: flex;        top: 22px; /* vertically center within the 44px high filter buttons */      }    }    .tg-df-filters {        width: 100%;        margin: 0;        margin-bottom: -320px;        padding: 0 16px 320px 16px;        display: flex;        flex-wrap: nowrap;        gap: 8px;        overflow-x: auto;        overflow-y: hidden;        pointer-events: none;        scrollbar-width: none;        -webkit-overflow-scrolling: touch;      }      .tg-df-filters::-webkit-scrollbar {        display: none;      }      .tg-df-sort-wrapper {        pointer-events: auto;        flex: 0 0 auto;        width: 175px;        min-width: 175px;      }    }        .tg-df-multiselect-trigger {      display: block;      background: #fff;      user-select: none;      width: 100%;      overflow: hidden;      white-space: nowrap;      text-overflow: ellipsis;    }        .tg-df-multiselect-dropdown {      display: none;      position: absolute;      top: calc(100% + 4px);      left: 0;      width: 100%;      min-width: 220px;      max-height: 300px;      overflow-y: auto;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 8px;      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);      z-index: 100;      padding: 8px 0;    }    .tg-df-multiselect-dropdown.active {      display: block;    }    .tg-df-ms-option {      padding: 8px 16px;      display: flex;      align-items: center;      gap: 8px;      cursor: pointer;      font-size: 14px;    }    .tg-df-ms-option:hover {      background-color: var(--tg-df-bg-secondary);    }        .tg-df-ms-option input {      cursor: pointer;      accent-color: #1f69ff;    }    .tg-df-sort-select:focus, .tg-df-filter-select:focus {      border-color: #0000ff;      box-shadow: 0 0 0 3px rgba(0, 0, 255, 0.2);      background-color: var(--tg-df-bg);    }    /*       3. Deal Grid Layout    */    .tg-df-grid.tg-df-grid-auto {      padding-top: 24px;    }    .tg-df-grid, .tg-df-grid.layout-grid {      display: grid;      grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));      gap: 10px;    }    .tg-df-grid.layout-row {      grid-template-columns: 1fr;      gap: 16px;    }        .tg-df-grid.layout-row .tg-df-card {      flex-direction: row;      align-items: stretch;      height: auto;      box-shadow: none;      border-bottom: 1px solid var(--tg-df-border);    }    .tg-df-grid.layout-row .tg-df-card:hover {      box-shadow: none;    }    .tg-df-grid.layout-row .tg-df-card-image-box {      width: 140px;      min-width: 140px;      aspect-ratio: 3/4;      border-right: none;      padding: 16px 16px 16px 32px;    }    .tg-df-grid.layout-row .tg-df-card-body {      padding: 16px;      justify-content: space-between;    }    .tg-df-grid.layout-row .tg-df-card-title {      font-size: 15px;      margin-bottom: 16px;    }    .tg-df-grid.layout-row .tg-df-card-stars { margin-bottom: 8px; }    .tg-df-grid.layout-row .tg-df-card-footer {      flex-direction: column;      align-items: flex-start;      gap: 0;    }    .tg-df-grid.layout-row .tg-df-card-merchant-pill {      margin-bottom: 4px;    }    .tg-df-grid.layout-row .tg-df-card-price-group {      margin-bottom: 8px;    }    .tg-df-grid.layout-row .tg-df-price-group {      width: auto;    }    .tg-df-grid.layout-row .tg-df-card-cta {      width: 100%;      max-width: 200px;      padding: 10px 24px;      font-size: 13px;      flex-shrink: 0;      text-align: center;      justify-content: center;    }    /*       4. Deal Card Design    */    .tg-df-card {      position: relative;      display: flex;      flex-direction: column;      background-color: #ffffff;      border-radius: 0;      overflow: hidden;      transition: transform 0.2s ease, box-shadow 0.2s ease;      text-decoration: none;      color: inherit;      height: 100%;      box-shadow: 0 0 16px rgba(0, 0, 0, 0.08);      border: 1px solid var(--tg-df-border);    }    .tg-df-card:hover {      box-shadow: 0 0 24px rgba(0, 0, 0, 0.12);    }    .tg-df-card-image-box {      width: 100%;      aspect-ratio: 3/4;      background-color: #f8f8f8;      display: flex;      align-items: center;      justify-content: center;      position: relative;      overflow: hidden;      padding: 32px;      flex: 0 0 auto;    }    .tg-df-card-image {      max-width: 100%;      max-height: 100%;      width: auto;      height: auto;      object-fit: contain;      mix-blend-mode: multiply; /* Helps white background images blend into secondary bg */      transition: transform 0.3s ease;    }    .tg-df-card:hover .tg-df-card-image {      transform: scale(1.05); /* Zoom in on hover */    }    .tg-df-card-discount-badge {      position: absolute;      top: 12px;      left: 12px;      background: #dc2626; /* Red */      color: #ffffff;      padding: 6px 8px;      font-size: 11px;      font-weight: 500;      text-transform: uppercase;      letter-spacing: 0.5px;      border-radius: 0;      z-index: 10;    }        .tg-df-card-merchant-pill {      display: block;      padding: 0;      font-size: 11px;      font-weight: 600;      text-transform: uppercase;      letter-spacing: 0.5px;      border-radius: 0;      color: var(--tg-df-text-muted);      margin-bottom: 8px;      white-space: nowrap;      overflow: hidden;      text-overflow: ellipsis;    }    .tg-df-card-body {      padding: 16px;      display: flex;      flex-direction: column;      flex-grow: 1;      min-width: 0;    }    .tg-df-card-badges {      display: flex;      flex-wrap: wrap;      gap: 6px;      margin-bottom: 8px;    }    .tg-df-tag {      display: inline-flex;      align-items: center;      padding: 4px 6px;      font-size: 11px;      font-weight: 700;      text-transform: uppercase;      border-radius: 4px;      gap: 4px;    }    .tg-df-tag-prime {      background-color: #00A8E1;      color: #fff;    }    .tg-df-tag-coupons {      background-color: #f1f5f9;      color: #334155;      border: 1px solid #cbd5e1;      cursor: pointer;      transition: background-color 0.2s;    }    .tg-df-tag-coupons:hover {      background-color: #e2e8f0;    }        .tg-df-tag-outline {      background-color: #f1f5f9;      color: #334155;      border: 1px solid #cbd5e1;      cursor: pointer;      transition: background-color 0.2s;    }    .tg-df-tag-outline:hover {      background-color: #e2e8f0;    }        @keyframes tg-df-spin {      0% { transform: rotate(0deg); }      100% { transform: rotate(360deg); }    }    .tg-df-coupon-spinner {      border: 2px solid #e2e8f0;      border-top: 2px solid #3b82f6;      border-radius: 50%;      width: 14px;      height: 14px;      animation: tg-df-spin 1s linear infinite;      margin: 4px 8px;      display: inline-block;    }        /* Vouchers Modal */    .tg-df-modal-backdrop {      position: fixed;      top: 0; left: 0; right: 0; bottom: 0;      background: rgba(0,0,0,0.5);      z-index: 10000;      display: flex;      align-items: center;      justify-content: center;      opacity: 0;      pointer-events: none;      transition: opacity 0.3s;    }    .tg-df-modal-backdrop.active {      opacity: 1;      pointer-events: auto;    }    .tg-df-modal {      background: #fff;      border-radius: 12px;      width: 90%;      max-width: 400px;      max-height: 80vh;      display: flex;      flex-direction: column;      box-shadow: 0 10px 40px rgba(0,0,0,0.2);      transform: translateY(20px);      transition: transform 0.3s;    }    .tg-df-modal-backdrop.active .tg-df-modal {      transform: translateY(0);    }    .tg-df-modal-header {      padding: 16px;      border-bottom: 1px solid #e2e8f0;      display: flex;      align-items: center;      justify-content: space-between;    }    .tg-df-modal-title {      font-size: 16px;      font-weight: 600;      margin: 0;    }    .tg-df-modal-close {      background: none;      border: none;      cursor: pointer;      padding: 4px;      color: #64748b;    }    .tg-df-modal-body {      padding: 16px;      overflow-y: auto;    }    .tg-df-voucher-item {      padding: 12px;      border: 1px dashed #cbd5e1;      border-radius: 8px;      margin-bottom: 10px;      background: #f8fafc;      display: flex;      align-items: center;      gap: 12px;      text-decoration: none;      color: inherit;      transition: background-color 0.2s, border-color 0.2s;    }    .tg-df-voucher-item:hover {      background: #f1f5f9;      border-color: #94a3b8;    }    .tg-df-voucher-item:last-child {      margin-bottom: 0;    }    .tg-df-voucher-logo {      width: 48px;      height: 48px;      object-fit: contain;      border-radius: 4px;      background: #fff;      border: 1px solid #e2e8f0;      flex-shrink: 0;    }    .tg-df-voucher-content {      flex: 1;      min-width: 0;    }    .tg-df-voucher-title {      font-size: 14px;      font-weight: 600;      margin: 0 0 4px 0;      line-height: 1.3;      color: #0f172a;    }    .tg-df-voucher-expiry {      font-size: 12px;      color: #64748b;      display: flex;      align-items: center;      gap: 4px;      margin-top: 6px;    }    .tg-df-voucher-code {      display: inline-flex;      align-items: center;      background: #f1f5f9;      border: 1px dashed #cbd5e1;      padding: 6px 10px;      font-family: monospace;      font-weight: 700;      font-size: 14px;      color: #0f172a;      border-radius: 4px;      margin-top: 8px;      cursor: pointer;      transition: all 0.2s ease;    }    .tg-df-voucher-code:hover {      background: #e2e8f0;      border-color: #94a3b8;    }    .tg-df-voucher-code.copied {      background: #ecfdf5;      border-color: #10b981;      color: #10b981;    }    .tg-df-voucher-cta {      display: inline-block;      margin-top: 8px;      font-size: 13px;      font-weight: 600;      color: #2563eb;      text-decoration: none;    }    .tg-df-card-title {      font-size: 15px;      font-weight: 400;      line-height: 1.4;      margin: 0 0 12px 0;      color: var(--tg-df-text);    }    .tg-df-card-footer {      margin-top: auto;      display: flex;      flex-direction: column;      width: 100%;    }    .tg-df-card-price-group {      display: flex;      flex-direction: row;      align-items: center;      gap: 8px;      margin-bottom: 12px;    }    .tg-df-card-price {      font-size: 16px;      font-weight: 700;      color: #dc2626; /* Red price */      line-height: 1;    }        .tg-df-card-msrp {      font-size: 13px;      color: var(--tg-df-text-muted);      text-decoration: line-through;    }    .tg-df-container .tg-df-card-cta {      display: flex;      align-items: center;      justify-content: center;      width: 100%;      box-sizing: border-box;      background-color: #1f69ff;      color: #ffffff;      font-size: 12px;      font-weight: 700;      text-transform: uppercase;      letter-spacing: 0.5px;      padding: 12px 16px;      border-radius: 0;      border: none;      cursor: pointer;      transition: background-color 0.2s ease;    }    .tg-df-card:hover .tg-df-card-cta,    .tg-df-card-cta:hover {      background-color: #1555cc;    }    /*       5. State & Skeleton Styles    */    .tg-df-message {      grid-column: 1 / -1;      text-align: center;      padding: 48px 24px;      color: var(--tg-df-text-muted);      font-size: 16px;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 8px;    }    @keyframes tg-df-shimmer {      0% { background-position: -200% 0; }      100% { background-position: 200% 0; }    }    .tg-df-skeleton {      background: linear-gradient(90deg, var(--tg-df-bg-secondary) 25%, #e2e8f0 50%, var(--tg-df-bg-secondary) 75%);      background-size: 200% 100%;      animation: tg-df-shimmer 1.5s infinite;      border-radius: 4px;    }    .tg-df-skeleton-img {      width: 100%;      height: 100%;      position: absolute;      top: 0; left: 0;    }        .tg-df-skeleton-text {      height: 16px;      margin-bottom: 8px;      width: 100%;    }    .tg-df-skeleton-text.short { width: 40%; }    .tg-df-skeleton-text.title { height: 20px; margin-bottom: 16px; }    /* Editor Floating Bar & Elements */    .tg-df-editor-bar {      position: sticky;      top: 120px;      z-index: 1000;      background: #111827;      color: #fff;      padding: 12px 16px;      border-radius: 8px;      margin-bottom: 16px;      display: flex;      align-items: center;      justify-content: space-between;      box-shadow: 0 4px 12px rgba(0,0,0,0.15);    }    .tg-df-editor-bar-text {      font-weight: 600;      font-size: 14px;    }    .tg-df-editor-copy-btn {      background: #10b981;      color: #fff;      padding: 6px 16px;      border: none;      border-radius: 4px;      font-weight: 600;      cursor: pointer;      display: flex;      align-items: center;      font-size: 13px;    }    .tg-df-editor-copy-btn:hover { background: #059669; }        .tg-df-deal-checkbox {      position: absolute;      top: 12px;      right: 12px;      z-index: 10;      width: 20px;      height: 20px;      cursor: pointer;      pointer-events: auto;    }    /*       6. Mobile List View (Stacks into a cleaner horizontal row/list)    */    @container tg-df (max-width: 599px) {      .tg-df-controls {        padding: 16px 16px 8px;      }            .tg-df-top-bar {        width: 100%;      }            .tg-df-settings-dropdown {        position: fixed;        top: auto;        bottom: 0;        left: 0;        right: 0;        width: 100%;        border-radius: 20px 20px 0 0;        padding: 24px;        box-shadow: 0 -8px 32px rgba(0,0,0,0.15);        z-index: 1000;        border: none;        border-top: 1px solid var(--tg-df-border);      }            .tg-df-settings-dropdown-backdrop.active {        background: rgba(0,0,0,0.4);      }            .tg-df-search-wrapper {        box-shadow: 0 0 16px rgba(0,0,0,0.08);      }                  .tg-df-sort-wrapper.tg-df-price-range-wrapper {        flex: 0 0 auto;        min-width: max-content;        width: auto;      }            .tg-df-sort-select, .tg-df-filter-select {        width: 100%;        text-align: left;        padding: 10px 24px 10px 32px;        background-position: right 8px center;        text-overflow: ellipsis;        white-space: nowrap;        overflow: hidden;      }      .tg-df-sort-icon {        left: 10px;      }      .tg-df-grid:not(.layout-grid):not(.layout-row),      .tg-df-grid.layout-row {        grid-template-columns: 1fr;        gap: 16px;      }            .tg-df-grid.tg-df-grid-auto {        padding-top: 24px;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card,      .tg-df-grid.layout-row .tg-df-card {        flex-direction: row;        align-items: stretch;        height: auto;        box-shadow: none; /* simple line on mobile if preferred, or keep */        border-bottom: 1px solid var(--tg-df-border);      }      .tg-df-grid.tg-df-grid-auto .tg-df-card:hover,      .tg-df-grid.layout-row .tg-df-card:hover {        box-shadow: none;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-image-box,      .tg-df-grid.layout-row .tg-df-card-image-box {        width: 120px;        min-width: 120px;        aspect-ratio: 3/4;        border-right: none;        padding: 12px;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-body,      .tg-df-grid.layout-row .tg-df-card-body {        padding: 12px;        justify-content: space-between;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-title,      .tg-df-grid.layout-row .tg-df-card-title {        font-size: 14px;        margin-bottom: 12px;      }      /* Single column mobile grid override */      .tg-df-grid.layout-grid {        grid-template-columns: 1fr;        gap: 16px;      }      .tg-df-grid.layout-grid .tg-df-card-image-box {        padding: 12px;      }      .tg-df-grid.layout-grid .tg-df-card-body {        padding: 10px;      }      .tg-df-grid.layout-grid .tg-df-card-title {        font-size: 13px;        margin-bottom: 8px;      }      .tg-df-grid.layout-grid .tg-df-card-price {        font-size: 14px;      }            .tg-df-card-footer {        flex-direction: column;        align-items: stretch;        gap: 0;        width: 100%;        min-width: 0;      }      .tg-df-card-merchant-pill {        margin-bottom: 4px;      }      .tg-df-card-price-group {        flex: 1 1 auto;        margin-bottom: 8px;      }      .tg-df-card-price {        font-size: 16px;      }      .tg-df-card-msrp {        display: block;       }      .tg-df-grid.layout-row .tg-df-card-cta,      .tg-df-container .tg-df-card-cta {        width: 100%;        max-width: none;        min-width: 0;        box-sizing: border-box;        padding: 8px 16px;        font-size: 12px;        flex: 0 0 auto;        text-align: center;        white-space: normal;        line-height: 1.2;      }    }    .tg-df-container.is-carousel {      min-height: 760px;      background-color: #E7F0FF;      padding: 0 0 24px 0;      border-radius: 24px;      width: 100vw;      max-width: 1200px;      position: relative;      left: 50%;      transform: translateX(-50%);    }    .tg-df-container.is-carousel.hide-header-details {      min-height: 480px;    }    /*       7. Carousel View Mode    */    .tg-df-container .tg-df-carousel-host {      /* Layout is now handled by container wrapper */    }    .tg-df-container .tg-df-carousel-eyebrow {      color: #1F69FF;      font-weight: 700;      font-size: 14px;      text-transform: uppercase;      letter-spacing: 1px;      padding: 24px 16px 0 16px;      display: none;    }    .tg-df-container .tg-df-carousel-query-title {      color: #011535;      font-size: 28px;      font-weight: 600;      padding: 0 16px 24px 16px;      line-height: 1.2;      display: none;    }    .tg-df-container .tg-df-carousel-blue-box {      background-color: transparent;      border-radius: 0;      padding: 24px 24px 0 24px;      margin: 0;      color: #1F69FF;          position: relative;      overflow: hidden;    }    .tg-df-container .tg-df-carousel-bg-circle-1 {      display: none;    }    .tg-df-container .tg-df-carousel-bg-circle-2 {      display: none;    }    .tg-df-container .tg-df-carousel-bg-circle-3 {      display: none;    }    .tg-df-container .tg-df-carousel-box-content {      position: relative;      z-index: 10;    }    .tg-df-container .tg-df-carousel-box-eyebrow {      background-color: transparent;      color: #1F69FF;      font-weight: 700;      font-size: 14px;      text-transform: uppercase;      letter-spacing: 1px;      display: inline-block;      padding: 0;      border-radius: 0;    }    .tg-df-container .tg-df-carousel-box-title {      font-size: 28px;      font-weight: 600;      line-height: 1.2;      margin-top: 8px;      color: #1e293b;    }    .tg-df-container .tg-df-countdown-wrapper {      position: absolute;      top: 0;      right: 0;      display: flex;      flex-direction: column;      align-items: flex-end;      gap: 12px;      transform: scale(0.67);      transform-origin: top right;    }    .tg-df-container .tg-df-countdown-title {      font-size: 14px;      font-weight: 600;      color: #011535;      margin: 0;    }    .tg-df-container .tg-df-countdown-blocks {      display: flex;      gap: 16px;    }    .tg-df-container .tg-df-countdown-item {      display: flex;      flex-direction: column;      align-items: center;      gap: 4px;    }    .tg-df-container .tg-df-countdown-box {      width: 59px;      height: 59px;      background: #03FE9E;      border-radius: 15px;      display: flex;      align-items: center;      justify-content: center;    }    .tg-df-container .tg-df-countdown-num {      font-family: 'Inter', sans-serif;      font-weight: 700;      font-size: 20px;      line-height: normal;      color: #011535;    }    .tg-df-container .tg-df-countdown-label {      font-family: 'Inter', sans-serif;      font-weight: 500;      font-size: 16px;      line-height: normal;      color: #1e293b;      text-transform: uppercase;    }    .tg-df-container .tg-df-carousel-box-subtitle {      font-size: 16px;      margin-top: 8px;      font-weight: 300;      color: #1e293b;      line-height: 24px;    }    .tg-df-container .tg-df-carousel-roundels-wrapper {      position: relative;      margin-top: 24px;      margin-left: -24px;      margin-right: -24px;    }    .tg-df-container .tg-df-carousel-roundels {      display: flex;      gap: 16px;      overflow-x: auto;            scrollbar-width: none;      padding-top: 12px;      padding-bottom: 24px;      padding-left: 24px;      padding-right: 24px;      margin-left: 0;      margin-right: 0;    }        .tg-df-container .tg-df-carousel-scroll-left,    .tg-df-container .tg-df-carousel-scroll-right {      position: absolute;      top: 50%;      transform: translateY(-50%);      height: 36px;      width: 36px;      display: flex;      align-items: center;      justify-content: center;      border-radius: 50%;      background-color: #ffffff;      border: 1px solid #e2e8f0;      box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);      color: #1F69FF;      cursor: pointer;      transition: all 0.2s;      margin-top: -4px;      z-index: 20;    }    .tg-df-container .tg-df-carousel-scroll-left { left: 8px; }    .tg-df-container .tg-df-carousel-scroll-right { right: 8px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-left { left: 0px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-right { right: 0px; }    .tg-df-carousel-filters-outer { margin-left: -24px; margin-right: -24px; padding-left: 24px; padding-right: 24px; }    .tg-df-grid-wrapper { position: relative; }    @container tg-df (max-width: 599px) { .tg-df-carousel-filters-outer { margin-left: -16px; margin-right: -16px; padding-left: 16px; padding-right: 16px; } }        .tg-df-container .tg-df-carousel-scroll-left:hover,    .tg-df-container .tg-df-carousel-scroll-right:hover {      background-color: rgba(255, 255, 255, 0.6);    }    .tg-df-container .tg-df-carousel-roundels::-webkit-scrollbar {      display: none;    }    .tg-df-container .tg-df-roundel {      display: flex;      flex-direction: column;      align-items: center;      gap: 8px;      cursor: pointer;      min-width: 120px;      flex-shrink: 0;    }    .tg-df-container .tg-df-roundel-img-box {      width: 120px;      height: 120px;      border-radius: 50%;      background: white;      display: flex;      align-items: center;      justify-content: center;      overflow: hidden;      box-shadow: 0px 3px 14px 0px rgba(30, 41, 59, 0.08);      transition: box-shadow 0.2s;    }    .tg-df-container .tg-df-roundel:hover .tg-df-roundel-img-box {      box-shadow: 0 0 0 2px #E7F0FF, 0 0 0 4px #1F69FF;    }    .tg-df-container .tg-df-roundel.active .tg-df-roundel-img-box {      box-shadow: 0 0 0 2px #E7F0FF, 0 0 0 4px #1F69FF;    }    .tg-df-container .tg-df-roundel:hover .tg-df-roundel-img-box img {      transform: scale(1.08);    }    .tg-df-container .tg-df-roundel-img-box img {      width: 100%;      height: 100%;      object-fit: contain;      padding: 10px;      box-sizing: border-box;      transition: transform 0.3s ease;    }    .tg-df-container .tg-df-roundel-label {      font-size: 13px;      font-weight: 400;      color: #1e293b;      text-align: center;    }    .tg-df-container .tg-df-carousel-filters-label {      font-size: 16px;      font-weight: 400;      color: #1e293b;      white-space: nowrap;      margin-right: 4px;    }    .tg-df-container .tg-df-carousel-filters-wrap {      display: flex;      align-items: center;      flex-wrap: nowrap;      gap: 8px;      margin-top: 8px;      overflow-x: auto;      scrollbar-width: none;      -webkit-overflow-scrolling: touch;      padding-bottom: 8px;      margin-left: -24px;      margin-right: -24px;      padding-left: 24px;      padding-right: 24px;    }    .tg-df-container .tg-df-carousel-filters-wrap::-webkit-scrollbar {      display: none;    }        .tg-df-container .tg-df-carousel-filter-btn img,    .tg-df-container .tg-df-carousel-filter-btn picture {      height: 20px;      width: 20px;      object-fit: contain;      object-position: center;      display: inline-flex;      align-items: center;      justify-content: center;      margin-right: 6px;    }    .tg-df-container .tg-df-carousel-filter-btn picture img {      margin-right: 0;      height: 100%;      width: 100%;    }    .tg-df-container .tg-df-carousel-filter-btn img.active-img,    .tg-df-container .tg-df-carousel-filter-btn picture:has(.active-img) {      display: none;    }    .tg-df-container .tg-df-carousel-filter-btn:hover img.inactive-img,    .tg-df-container .tg-df-carousel-filter-btn.active img.inactive-img,    .tg-df-container .tg-df-carousel-filter-btn:hover picture:has(.inactive-img),    .tg-df-container .tg-df-carousel-filter-btn.active picture:has(.inactive-img) {      display: none;    }    .tg-df-container .tg-df-carousel-filter-btn:hover img.active-img,    .tg-df-container .tg-df-carousel-filter-btn.active img.active-img,    .tg-df-container .tg-df-carousel-filter-btn:hover picture:has(.active-img),    .tg-df-container .tg-df-carousel-filter-btn.active picture:has(.active-img) {      display: inline-flex;    }    .tg-df-container .tg-df-carousel-filter-btn {      background: #ffffff;      border: 2px solid #1e293b;      color: #1e293b;      border-radius: 24px;      padding: 6px 16px;      font-size: 14px;      font-weight: 600;      cursor: pointer;      transition: all 0.2s;      flex-shrink: 0;      white-space: nowrap;    }    .tg-df-container .tg-df-carousel-filter-btn svg {      margin-right: 6px;    }    .tg-df-container .tg-df-carousel-filter-btn {      display: inline-flex;      align-items: center;    }    .tg-df-container .tg-df-carousel-filter-btn:hover {      background: #1e293b;      color: white;      border-color: #1e293b;    }    .tg-df-container .tg-df-carousel-filter-btn.active {      background: #1e293b;      color: white;      border-color: #1e293b;    }        .tg-df-grid.carousel-compact {      display: flex;      flex-wrap: nowrap;      overflow-x: auto;      gap: 16px;      padding: 16px 24px;      align-items: stretch;      scrollbar-width: none;    }    .tg-df-grid.carousel-compact::-webkit-scrollbar {      display: none;    }    .tg-df-grid.carousel-compact .tg-df-card {      flex: 0 0 auto;      width: 200px;      min-height: auto;      height: auto;      display: flex;      flex-direction: column;      border-radius: 15px;      border: none;      box-shadow: 0 0 16px rgba(0,0,0,0.08);      overflow: visible;    }    .tg-df-grid.carousel-compact .tg-df-card-image-box {      padding: 12px;      background-color: transparent;      border-radius: 15px 15px 0 0;      height: 130px;    }    .tg-df-grid.carousel-compact .tg-df-card-image {      mix-blend-mode: normal;    }    .tg-df-grid.carousel-compact .tg-df-card-discount-badge {      border-radius: 0;      top: 0px;      left: 0px;      padding: 4px 8px;      font-size: 11px;    }    .tg-df-grid.carousel-compact .tg-df-card-body {      padding: 8px 12px 12px 12px;    }    .tg-df-grid.carousel-compact .tg-df-card-title {      font-size: 14px;      font-weight: 400;      margin-bottom: 8px;      color: #011535;    }    .tg-df-grid.carousel-compact .tg-df-card-body:not(:has(.tg-df-card-stars)):not(:has(.tg-df-tag-prime)):not(:has(.tg-df-coupon-wrapper:not([style*="none"]))) > .tg-df-card-title,    .tg-df-grid.carousel-compact .tg-df-card-body:not(:has(.tg-df-card-stars)):has(> .tg-df-card-title:first-child) > .tg-df-card-title {    }    .tg-df-grid.carousel-compact .tg-df-card-cta {      border-radius: 5px;      padding: 8px 10px;      margin-top: 4px;      background-color: #1F69FF;    }    .tg-df-grid.carousel-compact .tg-df-card-price-group {      margin-bottom: 2px;    }    .tg-df-grid.carousel-compact .tg-df-card-merchant-pill {      margin-bottom: 2px;    }    @container tg-df (max-width: 599px) {      .tg-df-container .tg-df-carousel-blue-box-title {        font-size: 24px;      }      .tg-df-container .tg-df-countdown-title {        display: none;      }      .tg-df-container .tg-df-countdown-wrapper {        position: absolute;        top: 0;        right: 0;        align-items: flex-end;        transform: scale(0.40);        transform-origin: top right;      }      .tg-df-container .tg-df-roundel {        min-width: 88px;      }      .tg-df-container .tg-df-roundel-img-box {        width: 88px;        height: 88px;      }    }    /* REPLICA BLOCK STYLES */    .tg-df-grid.layout-replica-2 { grid-template-columns: repeat(2, 1fr) !important; gap: 20px; }    .tg-df-grid.layout-replica-1 { grid-template-columns: 1fr !important; gap: 20px; }        .tg-df-container .hawk-deal-widget-container { border-bottom: 1px solid #e5e7eb; display: flex; flex-direction: column; margin: 0; padding: 20px 0; box-sizing: border-box; font-family: inherit; }    .tg-df-container .hawk-deal-widget-wrap { display: flex; flex-direction: row; align-items: flex-start; width: 100%; gap: 24px; }    .tg-df-container .hawk-deal-widget-image-container { display: flex; flex-shrink: 0; justify-content: center; width: 160px; height: 160px; align-items: center; background: white; margin-bottom: 0px; }    .tg-df-container .hawk-deal-widget-title-product-title { color: #111827; font-size: 18px; font-weight: 700; line-height: 1.4; display: inline; }    .tg-df-container .hawk-deal-widget-title-price { font-size: 18px; font-weight: 700; line-height: 1.4; white-space: nowrap; color: #2563eb; }    .tg-df-container .hawk-deal-widget-title-price-now { font-weight: 700; }    .tg-df-container .hawk-deal-widget-title-retailer-price:hover { text-decoration: underline; }    .tg-df-container .hawk-deal-widget-title-retailer { font-size: 18px; font-weight: 700; line-height: 1.4; color: #2563eb; }    .tg-df-container .hawk-deal-widget-title-was-price { color: #dc2626; font-size: 16px; font-weight: 500; line-height: 1.4; text-decoration: line-through; white-space: nowrap; margin-left: 8px; margin-right: 8px; }    .tg-df-container .hawk-deal-widget-text-body-container { position: relative; width: 100%; box-sizing: border-box; }    .tg-df-container .hawk-deal-widget-text-body-main { font-size: 16px; width: 100%; margin-bottom: 12px; }    .tg-df-container .hawk-deal-widget-text-body-description { display: block; font-size: 15px; margin-top: 12px; color: #4b5563; line-height: 1.6; }    .tg-df-container .hawk-deal-widget-text-body-description p { margin: 0; line-height: 1.6; }    .tg-df-container .hawk-deal-widget-text-cta-container { display: flex; flex-direction: column; gap: 12px; width: 100%; flex: 1; min-width: 0; box-sizing: border-box; }    .tg-df-container .hawk-deal-widget-footer { display: flex; justify-content: flex-end; width: 100%; margin-top: auto; }    .tg-df-container .hawk-deal-widget-button-wrapper { display: flex; flex-direction: column; align-items: flex-end; justify-content: flex-end; width: 100%; }    .tg-df-container .hawk-deal-widget-preferred-partner-wrapper { display: flex; flex-direction: row; }        @container tg-df (min-width: 600px) {      .tg-df-mobile-only { display: none !important; }    }    @container tg-df (max-width: 599px) {      .tg-df-desktop-only { display: none !important; }      .tg-df-grid.layout-replica-2 { grid-template-columns: 1fr !important; }      .tg-df-grid.savings-squad-cards { grid-template-columns: 1fr !important; display: flex; flex-direction: column; }    }    .tg-df-grid.savings-squad-cards .tg-df-card-title {      -webkit-line-clamp: unset !important;      display: block !important;      overflow: visible !important;    }    @container tg-df (max-width: 500px) {      .tg-df-container .hawk-deal-widget-wrap { display: block; }      .tg-df-container .hawk-deal-widget-image-container { display: block; float: left; margin: 0 16px 8px 0; width: 120px; max-width: 120px; height: auto; align-items: normal; justify-content: normal; }      .tg-df-container .hawk-deal-widget-text-cta-container { display: block; text-align: left; }      .tg-df-container .hawk-deal-widget-footer { display: block; margin-top: 16px; clear: both; width: 100%; }      .tg-df-container .hawk-deal-widget-button-wrapper { display: block; width: 100%; }      .tg-df-container .hawk-deal-widget-button-wrapper .hawk-deal-widget-preferred-partner-wrapper { display: block; width: 100%; }      .tg-df-container .hawk-affiliate-link-deal-button { box-sizing: border-box !important; display: flex !important; max-width: none !important; width: 100% !important; margin: 0 !important; }    }        .tg-df-container .hawk-affiliate-link-deal-button {       align-items: center; background-color: #1f69ff; box-sizing: border-box; color: #ffffff !important; display: flex; font-size: 14px; font-weight: 700; justify-content: center; letter-spacing: 0.5px; line-height: 1; min-width: 160px; padding: 14px 24px; text-align: center; text-decoration: none; text-transform: uppercase; width: 100%; word-break: normal; border-radius: 4px; border: 0; transition: background-color 0.2s;     }    .tg-df-container .hawk-affiliate-link-deal-button:hover { background-color: #0056e0; text-decoration: none; }    .tg-df-container .hawk-lazy-image-deal-widget { display: block; height: auto; margin: auto; max-height: 160px; max-width: 100%; mix-blend-mode: multiply; object-fit: contain; }    .tg-df-container .hawk-deal-widget-text-cta-container a { color: #2563eb; text-decoration: none; display: inline; }    .tg-df-container .hawk-deal-widget-text-cta-container a:hover { text-decoration: underline; }    .tg-df-container .hawk-deal-widget-text-cta-container a:has(.hawk-deal-widget-title-product-title) { color: #111827; }    .tg-df-container .hawk-deal-widget-text-cta-container a:hover .hawk-deal-widget-title-product-title,    .tg-df-container .hawk-deal-widget-text-cta-container a:hover .hawk-deal-widget-title-retailer-price { text-decoration: underline; }    .tg-df-savings-squad-header { margin-bottom: 24px; text-align: center; display: none; }    .tg-df-banner-img-desktop { display: block; width: 100%; height: auto; margin-bottom: 32px; }    .tg-df-banner-img-mobile { display: none; width: 100%; height: auto; margin-bottom: 32px; }    @container tg-df (max-width: 600px) {      .tg-df-banner-img-desktop { display: none; }      .tg-df-banner-img-mobile { display: block; }    }    .tg-df-header-title { font-size: 28px; font-weight: 700; color: var(--tg-df-text); margin: 32px 0 12px 0; line-height: 1.3; }    .tg-df-header-subtitle { font-size: 16px; color: var(--tg-df-text-muted); margin: 0 0 32px 0; line-height: 1.5; }  \x3C/style>  \x3C!-- Widget Container --\x3E  \x3Cdiv class="tg-df-container" id="signal-deals-finder-root">    \x3Cdiv class="tg-df-savings-squad-header" id="tg-df-savings-squad-header">      \x3Cpicture>        \x3Cimg src="https://cdn.mos.cms.futurecdn.net/flexiimages/xkh2og7m3d1778189998.png" alt="Deals Banner" class="tg-df-banner-img-desktop" />        \x3Cimg src="https://cdn.mos.cms.futurecdn.net/flexiimages/gmak6rtdf41778245089.png" alt="Deals Banner Mobile" class="tg-df-banner-img-mobile" />      \x3C/picture>      \x3Cdiv class="tg-df-header-text">        \x3Ch2 class="tg-df-header-title" id="tg-df-header-title">Editor's Choice Deals\x3C/h2>        \x3Cp class="tg-df-header-subtitle" id="tg-df-header-subtitle">Discover the best discounts currently available, curated daily by the Tom's Guide Savings Squad.\x3C/p>      \x3C/div>    \x3C/div>    \x3C!-- Editor Floating Bar --\x3E    \x3Cdiv class="tg-df-editor-bar" id="tg-df-editor-bar" style="display:none;">      \x3Cdiv class="tg-df-editor-bar-text" style="display: flex; align-items: center;">        \x3Cspan id="tg-df-selected-count">0\x3C/span>\x26nbsp;Deals Selected        \x3Cbutton class="tg-df-editor-clear-btn" id="tg-df-editor-clear" type="button" style="margin-left: 12px; font-size: 13px; color: #9ca3af; background: none; border: none; cursor: pointer; text-decoration: underline;">Clear All\x3C/button>      \x3C/div>      \x3Cbutton class="tg-df-editor-copy-btn" id="tg-df-editor-copy" type="button">        \x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2">\x3C/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">\x3C/path>\x3C/svg>        Copy to CMS      \x3C/button>    \x3C/div>    \x3Cdiv class="tg-df-carousel-host" id="tg-df-carousel-host" style="display: none;">      \x3Cdiv class="tg-df-carousel-eyebrow">DEAL FINDER\x3C/div>      \x3Cdiv class="tg-df-carousel-query-title" id="tg-df-carousel-title-label">Best Deals\x3C/div>            \x3Cdiv class="tg-df-carousel-blue-box">        \x3Cdiv class="tg-df-carousel-bg-circle-1" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-bg-circle-2" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-bg-circle-3" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-box-content">          \x3Cdiv class="tg-df-countdown-wrapper" id="tg-df-countdown-wrapper" style="display:none;">            \x3Cdiv class="tg-df-countdown-title" id="tg-df-countdown-title">Prime Day starts in\x3C/div>            \x3Cdiv class="tg-df-countdown-blocks">              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-days">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">DAYS\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-hrs">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">HRS\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-min">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">MIN\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-sec">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">SEC\x3C/div>\x3C/div>            \x3C/div>          \x3C/div>          \x3Cdiv class="tg-df-carousel-box-eyebrow">DEAL FINDER\x3C/div>          \x3Cdiv class="tg-df-carousel-box-title">Find Deals Fast\x3C/div>          \x3Cdiv class="tg-df-carousel-box-subtitle">The latest deals from the biggest retailers, all in one place\x3C/div>                    \x3Cdiv class="tg-df-carousel-roundels-wrapper">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-roundels').scrollBy({left: -200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \x3Cdiv class="tg-df-carousel-roundels">                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Televisions" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/wcMxTsHgqu3roMbAx7RLnT-132-100.png" alt="TVs" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">TVs\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Phones" data-pr="over50">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/G3KGaRGzj24F6PUsw4bWpT-132-100.png" alt="Phones" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Phones\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Computing" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/znNvsLzx8NEgNkD9HSFSnT-132-100.png" alt="Computing" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Computing\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Gaming" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/Pgew8yaRQeZFHqHjTzvBnT-132-100.png" alt="Gaming" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Gaming\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Mattresses" data-pr="over500">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/cW7xsaLyesxkHFVSiC4kmT-132-100.png" alt="Mattresses" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Mattresses\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Audio" data-pr="over30">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/pCvBVHuhaQVjKt3VgCjbqT-132-100.png" alt="Audio" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Audio\x3C/span>            \x3C/div>                  \x3C/div>        \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" onclick="this.parentElement.querySelector('.tg-df-carousel-roundels').scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>        \x3C/div>        \x3C/div>        \x3Cdiv class="tg-df-carousel-filters-outer" style="position: relative;">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').scrollBy({left: -200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \x3Cdiv class="tg-df-carousel-filters-wrap">                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="0">All\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-ot="amazon_lightning">              \x3Cimg src="https://cdn.mos.cms.futurecdn.net/HqAui7w97ft2NPqBtQ5r38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/yWPQ5yyQRhUwVKzGwYbh38-600-100.png" class="active-img" alt="" /> Lightning deals\x3C/button>            \x3Cbutton class="tg-df-carousel-filter-btn" data-ot="amazon_prime">              \x3Cimg src="https://cdn.mos.cms.futurecdn.net/fwoVXvL79turN3Ph535m38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/u75QjVpt3w2EsMimJiRo38-600-100.png" class="active-img" alt="" /> Prime deals\x3C/button>            \x3Cbutton class="tg-df-carousel-filter-btn" data-d="10">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 10% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="15">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 15% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="25">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 25% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-pr="under50">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-badge-dollar-sign">\x3Cpath d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z">\x3C/path>\x3Cpath d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8">\x3C/path>\x3Cpath d="M12 18V6">\x3C/path>\x3C/svg>            Under $50\x3C/button>        \x3C/div>        \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>      \x3C/div>    \x3C/div>    \x3C/div>      \x3C!-- Search & Filter Controls --\x3E      \x3Cdiv class="tg-df-top-bar" id="tg-df-top-bar" style="position: relative; z-index: 100; margin: 0 auto 20px;">        \x3Cdiv class="tg-df-search-wrapper">          \x3Cinput type="text" class="tg-df-search-input" placeholder="Search for deals, products, or brands...">          \x3Cbutton type="button" class="tg-df-search-btn" aria-label="Search">              \x3Csvg class="tg-df-search-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">                \x3Cpath d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>              \x3C/svg>          \x3C/button>          \x3Cdiv class="tg-df-autocomplete-dropdown" id="tg-df-autocomplete">\x3C/div>        \x3C/div>      \x3C/div>    \x3Cdiv class="tg-df-controls" id="tg-df-controls" style="display:flex;">              \x3Cdiv class="tg-df-filters-container" style="position: relative; width: 100%; max-width: 800px; margin: 0 auto;">          \x3Cbutton class="tg-df-scroll-btn left" style="display: none;" onclick="this.parentElement.querySelector('.tg-df-filters').scrollBy({left: -200, behavior: 'smooth'})">            \x3Csvg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\x3Cpath d="M15 18l-6-6 6-6"/>\x3C/svg>          \x3C/button>          \x3Cbutton class="tg-df-scroll-btn right" style="display: none;" onclick="this.parentElement.querySelector('.tg-df-filters').scrollBy({left: 200, behavior: 'smooth'})">            \x3Csvg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\x3Cpath d="M9 18l6-6-6-6"/>\x3C/svg>          \x3C/button>          \x3Cdiv class="tg-df-filters">          \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-category-filter-wrapper" style="display: none;">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-category-filter" aria-label="Category">            \x3Coption value="all">All Categories\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper tg-df-multiselect-container" id="tg-df-brand-filter-wrapper" style="display:none;">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M4.25 5.61C6.27 8.2 10 13 10 13v6c0 .55.45 1 1 1h2c.55 0 1-.45 1-1v-6s3.72-4.8 5.74-7.39A.998.998 0 0 0 18.95 4H5.04c-.83 0-1.3.95-.79 1.61z"/>          \x3C/svg>          \x3Cdiv class="tg-df-filter-select tg-df-multiselect-trigger" id="tg-df-brand-trigger" tabindex="0">            Any Brand          \x3C/div>          \x3Cdiv class="tg-df-multiselect-dropdown" id="tg-df-brand-dropdown">            \x3C!-- Populated via script --\x3E          \x3C/div>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper tg-df-price-range-wrapper" id="tg-df-custom-price-wrapper" style="display: flex; align-items:center; justify-content:center; padding: 10px 20px; gap: 8px; border: 1px solid var(--tg-df-border); border-radius: 100px; background-color: var(--tg-df-bg);">          \x3Cspan style="font-size:14px; font-weight:500; color:var(--tg-df-text-primary);">Price\x3C/span>          \x3Cinput type="number" class="tg-df-price-input" id="tg-df-custom-price-min" placeholder="Min" style="width: 48px; background: transparent; border: none; color: var(--tg-df-text-primary); outline: none; font-size: 14px; text-align: center; padding: 0;">          \x3Cspan style="color:var(--tg-df-text-muted)">-\x3C/span>          \x3Cinput type="number" class="tg-df-price-input" id="tg-df-custom-price-max" placeholder="Max" style="width: 48px; background: transparent; border: none; color: var(--tg-df-text-primary); outline: none; font-size: 14px; text-align: center; padding: 0;">        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-legacy-price-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-price-filter" aria-label="Filter Prices">            \x3Coption value="all">All Prices\x3C/option>            \x3Coption value="under50">Under $50\x3C/option>            \x3Coption value="50_100">$50 - $100\x3C/option>            \x3Coption value="100_200">$100 - $200\x3C/option>            \x3Coption value="200_500">$200 - $500\x3C/option>            \x3Coption value="over500">Over $500\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-discount-filter-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">            \x3Cpath d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-discount-filter" aria-label="Discount Amount">            \x3Coption value="all">Any discount\x3C/option>            \x3Coption value="5">Min 5%\x3C/option>            \x3Coption value="10">Min 10%\x3C/option>            \x3Coption value="15">Min 15%\x3C/option>            \x3Coption value="20">Min 20%\x3C/option>            \x3Coption value="25">Min 25%\x3C/option>            \x3Coption value="30">Min 30%\x3C/option>            \x3Coption value="40">Min 40%\x3C/option>            \x3Coption value="50">Min 50%\x3C/option>            \x3Coption value="60">Min 60%\x3C/option>            \x3Coption value="70">Min 70%\x3C/option>          \x3C/select>          \x3C/div>        \x3C/div>        \x3C/div>      \x3C/div>    \x3C!-- Deals Grid Wrapper --\x3E    \x3Cdiv class="tg-df-grid-wrapper tg-df-carousel-cards-wrapper" id="tg-df-grid-wrapper">      \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').scrollBy({left: -200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>      \x3Cdiv class="tg-df-grid" id="tg-df-grid">        \x3C!-- Content populated by JavaScript --\x3E      \x3C/div>      \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>    \x3C/div>        \x3C!-- Vouchers Modal --\x3E    \x3Cdiv class="tg-df-modal-backdrop" id="tg-df-vouchers-modal">      \x3Cdiv class="tg-df-modal">        \x3Cdiv class="tg-df-modal-header">          \x3Ch3 class="tg-df-modal-title" id="tg-df-vouchers-title">Available Coupons & Deals\x3C/h3>          \x3Cbutton class="tg-df-modal-close" id="tg-df-vouchers-close">            \x3Csvg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">              \x3Cline x1="18" y1="6" x2="6" y2="18">\x3C/line>              \x3Cline x1="6" y1="6" x2="18" y2="18">\x3C/line>            \x3C/svg>          \x3C/button>        \x3C/div>        \x3Cdiv class="tg-df-modal-body" id="tg-df-vouchers-content">          \x3C!-- Vouchers injected here --\x3E        \x3C/div>      \x3C/div>    \x3C/div>  \x3C/div>`;      if (!template) {        template = document.createElement('template');        template.innerHTML = rawTemplate;      }      let shadowRoot = null;      if (hostContainer && template) {        hostContainer.setAttribute('data-initialized', 'true');        shadowRoot = hostContainer.attachShadow({ mode: 'open' });        shadowRoot.appendChild(template.content.cloneNode(true));      }      class DealsFinderWidget {        constructor(config) {          this.rootNode = config.rootNode || document;          this.hostContainer = config.hostContainer || null;          this.rootId = config.rootId || 'signal-deals-finder-root';          this.root = this.rootNode.querySelector('#' + this.rootId);          if (!this.root) return;          this.widgetId = (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : 'widget-' + Date.now() + '-' + Math.random().toString(36).slice(2);          this.grid = this.root.querySelector('#tg-df-grid');          this.tagsContainer = this.root.querySelector('#tg-df-tags-container');          this.categoryFilter = this.root.querySelector('#tg-df-category-filter');          this.categoryFilterWrapper = this.root.querySelector('#tg-df-category-filter-wrapper');          this.searchInput = this.root.querySelector('.tg-df-search-input');          this.autocompleteDropdown = this.root.querySelector('#tg-df-autocomplete');          this.sortSelect = this.root.querySelector('.tg-df-sort-select');          this.searchBtn = this.root.querySelector('.tg-df-search-btn');                    this.settingsToggle = this.root.querySelector('#tg-df-settings-toggle');          this.settingsPanel = this.root.querySelector('#tg-df-settings-panel');          this.settingsBackdrop = this.root.querySelector('#tg-df-settings-backdrop');          this.regionSelect = this.root.querySelector('#tg-df-region-select');          this.retailerSelect = this.root.querySelector('#tg-df-retailer-select');          this.offerTypeSelect = this.root.querySelector('#tg-df-offer-type-select');          this.viewModeSelect = this.root.querySelector('#tg-df-view-mode-select');          this.rowsSelect = this.root.querySelector('#tg-df-rows-select');          this.dealModeToggle = this.root.querySelector('#tg-df-deal-mode');          this.editorModeToggle = this.root.querySelector('#tg-df-editor-mode');          this.priceFilter = this.root.querySelector('#tg-df-price-filter');          this.discountFilter = this.root.querySelector('#tg-df-discount-filter');                    this.editorBar = this.root.querySelector('#tg-df-editor-bar');          this.editorSelectedCount = this.root.querySelector('#tg-df-selected-count');          this.editorCopyBtn = this.root.querySelector('#tg-df-editor-copy');          this.editorClearBtn = this.root.querySelector('#tg-df-editor-clear');                    this.apiUrl = 'https://search-api.fie.future.net.uk/widget.php';          this.deals = [];          this.displayLimit = 12;          this.airedaleArticles = null;          this.airedaleTags = [];          this.airedaleTagCounts = {};          this.activeDealTag = null;          this.selectedBrands = [];          this.currentQuery = '';          this.editorMode = this.hostContainer ? this.hostContainer.hasAttribute('data-editor-mode') : false;          this.viewModeOverride = this.hostContainer ? this.hostContainer.getAttribute('data-view-mode') : null;          this.selectedDeals = new Map();                    this.brandFilterWrapper = this.root.querySelector('#tg-df-brand-filter-wrapper');          this.brandTrigger = this.root.querySelector('#tg-df-brand-trigger');          this.brandDropdown = this.root.querySelector('#tg-df-brand-dropdown');                    this.customPriceWrapper = this.root.querySelector('#tg-df-custom-price-wrapper');          this.customPriceMin = this.root.querySelector('#tg-df-custom-price-min');          this.customPriceMax = this.root.querySelector('#tg-df-custom-price-max');          this.legacyPriceWrapper = this.root.querySelector('#tg-df-legacy-price-wrapper');          this.discountFilterWrapper = this.root.querySelector('#tg-df-discount-filter-wrapper');          this.initResizeObserver();          this.init();        }        getViewMode() {          console.log("DEBUG getViewMode -> override:", this.viewModeOverride, "editorMode:", this.editorMode);          if (this.viewModeOverride && (!this.editorMode || !this.viewModeSelect)) {            return this.viewModeOverride;          }          return (this.viewModeSelect && this.viewModeSelect.value) ? this.viewModeSelect.value : (this.viewModeOverride || 'auto');        }        applyLayoutMode() {          if (!this.grid) return;          const mode = this.getViewMode();          console.log("[DEBUG] applyLayoutMode CALLED! mode=", mode);          this.grid.classList.remove('layout-row', 'layout-grid', 'tg-df-grid-auto', 'carousel-compact', 'layout-replica-1', 'layout-replica-2');                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          const showHeaderDetails = params.get('show_header_details') !== 'false';          const carouselHost = this.root.querySelector('#tg-df-carousel-host');          const controlsDiv = this.root.querySelector('#tg-df-controls');          const topBarDiv = this.root.querySelector('#tg-df-top-bar');          const headerElement = this.root.querySelector('#tg-df-savings-squad-header');          if (headerElement) {             headerElement.style.display = (mode === 'savings_squad' && showHeaderDetails) ? 'block' : 'none';          }          if (mode === 'carousel') {             this.grid.classList.add('carousel-compact');             if (carouselHost) carouselHost.style.display = 'block';             if (controlsDiv) controlsDiv.style.display = 'none';             if (topBarDiv) topBarDiv.style.display = 'none';             if (this.root.classList.contains('tg-df-container')) {               this.root.classList.add('is-carousel');             }          } else {             if (carouselHost) carouselHost.style.display = 'none';             if (controlsDiv) controlsDiv.style.display = 'flex';             if (topBarDiv) topBarDiv.style.display = 'block';             if (this.root.classList.contains('tg-df-container')) {               this.root.classList.remove('is-carousel');             }          }          if (mode === 'grid') {            this.grid.classList.add('layout-grid');          } else if (mode === 'row') {            this.grid.classList.add('layout-row');          } else if (mode === 'savings_squad') {            this.grid.classList.add('tg-df-grid-auto', 'savings-squad-cards');          } else if (mode !== 'carousel') {            this.grid.classList.add('tg-df-grid-auto');          }                    const settingsWrapper = this.root.querySelector('.tg-df-settings-wrapper');          if (settingsWrapper) {            settingsWrapper.style.display = mode === 'auto' ? 'none' : 'block';          }          if (this.customPriceWrapper) {             this.customPriceWrapper.style.display = mode === 'auto' ? 'flex' : 'none';          }          if (this.legacyPriceWrapper) {             this.legacyPriceWrapper.style.display = mode === 'auto' ? 'none' : 'flex';          }          if (this.discountFilterWrapper) {             this.discountFilterWrapper.style.display = mode === 'auto' ? 'none' : 'flex';          }        }        initResizeObserver() {          try {            if (window.parent === window) return;          } catch (e) {            // cross origin frame check threw          }          const emitHeight = () => {            try {              const height = document.documentElement.scrollHeight || document.body.scrollHeight;              const msg = { type: 'embed-size', height: height };              if (window.parent && window.parent !== window) {                window.parent.postMessage(msg, '*');                window.parent.postMessage(JSON.stringify({ ...msg, sentinel: 'amp' }), '*');              }            } catch (e) {}          };                    if (window.ResizeObserver) {            try {              const ro = new ResizeObserver(() => emitHeight());              ro.observe(document.body);              if (this.root) ro.observe(this.root);            } catch(e){ console.warn(e); }          }          window.addEventListener('resize', emitHeight);          setTimeout(emitHeight, 300);        }        initCountdown() {          this.cdWrapper = this.root.querySelector('#tg-df-countdown-wrapper');                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          this.showCountdown = params.get('show_countdown') === 'true';          const showHeaderDetails = params.get('show_header_details') !== 'false';          const eyebrow = this.root.querySelector('.tg-df-carousel-box-eyebrow');          const title = this.root.querySelector('.tg-df-carousel-box-title');          const subtitle = this.root.querySelector('.tg-df-carousel-box-subtitle');          if (!showHeaderDetails) {            let containerElement = this.root.classList.contains('tg-df-container') ? this.root : this.root.querySelector('.tg-df-container');            if (containerElement) containerElement.classList.add('hide-header-details');            if (eyebrow) eyebrow.style.display = 'none';            if (title) title.style.display = 'none';            if (subtitle) subtitle.style.display = 'none';          }          if (!this.cdWrapper) return;          this.cdTitle = this.root.querySelector('#tg-df-countdown-title');          this.cdDays = this.root.querySelector('#tg-df-cd-days');          this.cdHrs = this.root.querySelector('#tg-df-cd-hrs');          this.cdMin = this.root.querySelector('#tg-df-cd-min');          this.cdSec = this.root.querySelector('#tg-df-cd-sec');          this.updateCountdown();          this.cdInterval = setInterval(() => this.updateCountdown(), 1000);        }        updateCountdown() {          if (!this.cdWrapper) return;          if (!this.showCountdown) {            this.cdWrapper.style.display = 'none';            return;          }          const area = this.getAreaCode();          let offset = '-04:00';          if (['DE', 'FR', 'IT', 'ES', 'NL'].includes(area)) {             offset = '+02:00';          } else if (['GB', 'IE', 'UK'].includes(area)) {             offset = '+01:00';          }          const startTime = new Date('2026-06-23T00:00:00' + offset).getTime();          const endTime = new Date('2026-06-26T00:00:00' + offset).getTime();          const now = Date.now();          let targetTime = 0;          if (now < startTime) {             targetTime = startTime;             if (this.cdTitle) this.cdTitle.textContent = 'Prime Day starts in';             this.cdWrapper.style.display = 'flex';          } else if (now < endTime) {             targetTime = endTime;             if (this.cdTitle) this.cdTitle.textContent = 'Prime Day ends in';             this.cdWrapper.style.display = 'flex';          } else {             this.cdWrapper.style.display = 'none';             if (this.cdInterval) clearInterval(this.cdInterval);             return;          }          const diff = Math.max(0, targetTime - now);          const d = Math.floor(diff / (1000 * 60 * 60 * 24));          const h = Math.floor((diff / (1000 * 60 * 60)) % 24);          const m = Math.floor((diff / 1000 / 60) % 60);          const s = Math.floor((diff / 1000) % 60);          if (this.cdDays) this.cdDays.textContent = d;          if (this.cdHrs) this.cdHrs.textContent = h;          if (this.cdMin) this.cdMin.textContent = m;          if (this.cdSec) this.cdSec.textContent = s;        }        init() {          this.initCountdown();          try {            initAnalytics();          } catch (e) {            console.warn('Deals Widget Analytics Error:', e);          }                    this.bindEvents();                    let initialQuery = '';                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          let initialViewMode = params.get('view_mode');          if (!this.viewModeOverride && initialViewMode) {            this.viewModeOverride = initialViewMode;          }          if (!params.has('search') && !params.has('q') && !params.has('query') && initialViewMode !== 'savings_squad') {             initialQuery = 'Gaming laptops';          }          const website = params.get('website') || 'tomsguide';          this.website = website;          if (website === 'techradar') {            const squadHeader = this.root.querySelector('.tg-df-savings-squad-header');            if (squadHeader) {               const pic = squadHeader.querySelector('picture');               if (pic) pic.style.display = 'none';            }            const style = document.createElement('style');            style.innerHTML = `              .tg-df-container .hawk-affiliate-link-deal-button, .tg-df-container .tg-df-card-cta { background-color: #5DAF08 !important; }              .tg-df-container .hawk-affiliate-link-deal-button:hover, .tg-df-container .tg-df-card-cta:hover { background-color: #4a8c06 !important; }            `;            this.root.appendChild(style);          }                    if (this.regionSelect) {            this.regionSelect.value = params.get('region') || 'auto';            this.updatePriceDropdownCurrency();          }                    if (this.retailerSelect && params.has('retailer')) {            this.retailerSelect.value = params.get('retailer');          }                    if (params.has('brands')) {            const b = params.get('brands');            if (b) {              this.selectedBrands = b.split(',');            }          }                    if (this.offerTypeSelect && params.has('offer_type')) {            this.offerTypeSelect.value = params.get('offer_type');          }          if (this.viewModeSelect && params.has('view_mode')) {            this.viewModeSelect.value = params.get('view_mode');          }          if (this.rowsSelect && params.has('rows')) {            this.rowsSelect.value = params.get('rows');          }          if (params.has('price')) {            const priceVal = params.get('price');            if (this.priceFilter) {               // Try assigning it directly to select. If it's not present implicitly ignores               this.priceFilter.value = priceVal;            }            if (priceVal.includes('_')) {               const parts = priceVal.split('_');               if (this.customPriceMin && parts[0]) this.customPriceMin.value = parts[0];               if (this.customPriceMax && parts[1]) this.customPriceMax.value = parts[1];            }          }          if (this.discountFilter && params.has('min_discount_ratio')) {            // Need to convert back from ratio (e.g. 0.8) to select value (e.g. "20")            const ratioStr = params.get('min_discount_ratio');            const ratioFloat = parseFloat(ratioStr);            if (!isNaN(ratioFloat)) {               const percentage = Math.round((1 - ratioFloat) * 100);               this.discountFilter.value = percentage.toString();            }          }          if (this.sortSelect) {            this.sortSelect.value = params.get('sort') || 'date_desc';          }          if (this.dealModeToggle && params.has('deal_mode')) {            this.dealModeToggle.checked = params.get('deal_mode') === 'true' || params.get('deal_mode') === '1';          }          const headerTitleEl = this.root.querySelector('#tg-df-header-title');          const headerSubtitleEl = this.root.querySelector('#tg-df-header-subtitle');          if (params.has('widget_title') && headerTitleEl) {             headerTitleEl.textContent = params.get('widget_title');          }          if (params.has('widget_subtitle') && headerSubtitleEl) {             headerSubtitleEl.textContent = params.get('widget_subtitle');          }                    // Re-apply layout after params have updated control values          this.applyLayoutMode();                    if (params.get('search')) {            initialQuery = params.get('search');          } else if (params.get('q')) {            initialQuery = params.get('q');          } else if (params.get('query')) {            initialQuery = params.get('query');          }                    this.currentQuery = initialQuery;          if (this.searchInput) {            if (this.getViewMode() === 'savings_squad') {              this.searchInput.value = '';            } else {              this.searchInput.value = this.currentQuery;            }          }                    if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {            this.fetchDeals(this.currentQuery);          } else {            this.render();          }        }        updatePriceDropdownCurrency() {          if (!this.priceFilter || !this.regionSelect) return;          const currencySymbols = {            'US': '$',            'GB': '£',            'CA': '$CA',            'AU': '$AU',            'DE': '€',            'FR': '€',            'IT': '€',          };          const area = this.getAreaCode();          const cur = currencySymbols[area || 'US'] || '$';                    const options = this.priceFilter.options;          for (let i = 0; i < options.length; i++) {            const opt = options[i];            if (opt.value === 'all') {              opt.innerText = 'All Prices';            } else if (opt.value === 'under50') {              opt.innerText = `Under ${cur}50`;            } else if (opt.value === '50_100') {              opt.innerText = `${cur}50 - ${cur}100`;            } else if (opt.value === '100_200') {              opt.innerText = `${cur}100 - ${cur}200`;            } else if (opt.value === '200_500') {              opt.innerText = `${cur}200 - ${cur}500`;            } else if (opt.value === 'over500') {              opt.innerText = `Over ${cur}500`;            }          }        }        populateBrandDropdown(values) {          if (!this.brandDropdown || !this.brandFilterWrapper) return;          this.brandFilterWrapper.style.display = 'flex'; // show the wrapper                    let html = '';          const allChecked = this.selectedBrands.length === 0 ? 'checked' : '';          const _div = '<' + '/div>';          const _span = '<' + '/span>';          html += `\x3Cdiv class="tg-df-ms-option">\x3Cinput type="checkbox" value="" ${allChecked} class="tg-df-brand-chk"> Any Brand${_div}`;                    values.forEach(v => {             if (!v.formatted_value || v.formatted_value === 'Any Brand') return;             const isChecked = this.selectedBrands.includes(v.formatted_value) ? 'checked' : '';             html += `\x3Cdiv class="tg-df-ms-option">\x3Cinput type="checkbox" value="${this.escapeHTML(v.formatted_value)}" ${isChecked} class="tg-df-brand-chk"> ${this.escapeHTML(v.formatted_value)} \x3Cspan style="color:var(--tg-df-text-muted);font-size:12px">(${v.count || 0})${_span}${_div}`;          });                    this.brandDropdown.innerHTML = html;                    // Re-bind listeners          const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');          chks.forEach(chk => {            chk.addEventListener('change', (e) => {              const val = e.target.value;              if (val === '') {                this.selectedBrands = [];              } else {                if (e.target.checked) {                   if (!this.selectedBrands.includes(val)) this.selectedBrands.push(val);                } else {                   this.selectedBrands = this.selectedBrands.filter(b => b !== val);                }              }                            if (this.selectedBrands.length === 0) {                 this.brandTrigger.innerText = 'Any Brand';              } else if (this.selectedBrands.length === 1) {                 this.brandTrigger.innerText = this.selectedBrands[0];              } else {                 this.brandTrigger.innerText = `${this.selectedBrands.length} Brands selected`;              }                            // Only call API if changed from UI interactions              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                 this.updateURLParams();                 this.fetchDeals(this.currentQuery);              }            });          });                    // Update button text on load          if (this.selectedBrands.length === 0) {             this.brandTrigger.innerText = 'Any Brand';          } else if (this.selectedBrands.length === 1) {             this.brandTrigger.innerText = this.selectedBrands[0];          } else {             this.brandTrigger.innerText = `${this.selectedBrands.length} Brands selected`;          }        }        updateURLParams() {          const url = new URL(window.location);          if (this.currentQuery && this.currentQuery !== 'Gaming laptops') {            url.searchParams.set('q', this.currentQuery);          } else {            url.searchParams.delete('q');            url.searchParams.delete('search');            url.searchParams.delete('query');          }                    if (this.regionSelect && this.regionSelect.value !== 'auto') {            url.searchParams.set('region', this.regionSelect.value);          } else {            url.searchParams.delete('region');          }                    if (this.retailerSelect && this.retailerSelect.value) {            url.searchParams.set('retailer', this.retailerSelect.value);          } else {            url.searchParams.delete('retailer');          }                    if (this.selectedBrands && this.selectedBrands.length > 0) {            url.searchParams.set('brands', this.selectedBrands.join(','));          } else {            url.searchParams.delete('brands');          }                    if (this.offerTypeSelect && this.offerTypeSelect.value) {            url.searchParams.set('offer_type', this.offerTypeSelect.value);          } else {            url.searchParams.delete('offer_type');          }                    if (this.viewModeSelect && this.viewModeSelect.value !== 'auto') {            url.searchParams.set('view_mode', this.viewModeSelect.value);          } else {            url.searchParams.delete('view_mode');          }                    if (this.rowsSelect && this.rowsSelect.value !== '12') {            url.searchParams.set('rows', this.rowsSelect.value);          } else {            url.searchParams.delete('rows');          }                    const min = this.customPriceMin ? this.customPriceMin.value : '';          const max = this.customPriceMax ? this.customPriceMax.value : '';          if (min || max) {             url.searchParams.set('price', `${min}_${max}`);          } else if (this.priceFilter && this.priceFilter.value !== 'all') {            url.searchParams.set('price', this.priceFilter.value);          } else {            url.searchParams.delete('price');          }                    if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {            const v = parseInt(this.discountFilter.value);            if (!isNaN(v) && v > 0) {               const ratio = (100 - v) / 100;               url.searchParams.set('min_discount_ratio', ratio.toString());            }          } else {            url.searchParams.delete('min_discount_ratio');          }                    if (this.sortSelect && this.sortSelect.value !== 'date_desc') {            url.searchParams.set('sort', this.sortSelect.value);          } else {            url.searchParams.delete('sort');          }                    if (this.dealModeToggle && this.dealModeToggle.checked) {            url.searchParams.set('deal_mode', 'true');          } else {            url.searchParams.delete('deal_mode');          }                    window.history.replaceState({}, '', url);        }        bindEvents() {          const handleFiltersScroll = () => {            const filters = this.root.querySelector('.tg-df-filters');            const leftBtn = this.root.querySelector('.tg-df-scroll-btn.left');            const rightBtn = this.root.querySelector('.tg-df-scroll-btn.right');            if (filters && leftBtn && rightBtn) {              const { scrollLeft, scrollWidth, clientWidth } = filters;              leftBtn.style.display = scrollLeft > 0 ? 'flex' : 'none';              rightBtn.style.display = Math.ceil(scrollLeft + clientWidth) < scrollWidth - 5 ? 'flex' : 'none';            }          };          const filters = this.root.querySelector('.tg-df-filters');          if (filters) {            filters.addEventListener('scroll', handleFiltersScroll);            window.addEventListener('resize', handleFiltersScroll);            setTimeout(handleFiltersScroll, 100);                        // Also call after rendering dropdowns            const origRenderCategories = this.renderCategories;            if (origRenderCategories) {               this.renderCategories = (...args) => {                 origRenderCategories.apply(this, args);                 setTimeout(handleFiltersScroll, 50);               };            }          }                const roundels = this.root.querySelectorAll('.tg-df-carousel-cat');          roundels.forEach(r => {             r.addEventListener('click', () => {                const q = r.getAttribute('data-query');                const pr = r.getAttribute('data-pr');                if (typeof trackHawkEvent !== 'undefined') {                     trackHawkEvent({                         clickType: "CC",                         widgetId: this.widgetId,                         productCategoryName: "deals",                         zeroBasedProductIndexOrNull: null,                         totalDealsOrProducts: null,                         areaClicked: "Category Roundel",                         revenueId: this.revenueId,                         isoCurrencyCode: typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD',                         queryName: q,                         widgetTypeName: this.widgetTypeName                     });                 }                this.currentQuery = q;                const label = this.root.querySelector('#tg-df-carousel-title-label');                if (label) label.textContent = 'Best ' + q;                if (this.priceFilter) this.priceFilter.value = pr || 'all';                if (this.discountFilter) this.discountFilter.value = '5';                if (this.searchInput) this.searchInput.value = q;                                roundels.forEach(ro => ro.classList.remove('active'));                r.classList.add('active');                this.fetchDeals(this.currentQuery);             });          });          const discBtns = this.root.querySelectorAll('.tg-df-carousel-filter-btn');          discBtns.forEach(b => {             b.addEventListener('click', () => {                const d = b.getAttribute('data-d');                const pr = b.getAttribute('data-pr');                const ot = b.getAttribute('data-ot');                let label = b.innerText ? b.innerText.trim() : '';                let filterType = 'unknown';                let filterVal = 'unknown';                if (d !== null) { filterType = 'discount'; filterVal = d; }                else if (pr !== null) { filterType = 'price'; filterVal = pr; }                else if (ot !== null) { filterType = 'offertype'; filterVal = ot; }                if (typeof trackElementInteraction === 'function') trackElementInteraction({ id: `filter-${filterType}-${filterVal}`, name: 'Filter Button', label: label });                                if (d !== null) {                   if (this.discountFilter) this.discountFilter.value = this.discountFilter.value === d ? '0' : d;                } else if (pr !== null) {                   if (this.priceFilter) this.priceFilter.value = this.priceFilter.value === pr ? 'all' : pr;                } else if (ot !== null) {                   if (this.offerTypeSelect) this.offerTypeSelect.value = this.offerTypeSelect.value === ot ? 'all' : ot;                } else {                   if (this.discountFilter) this.discountFilter.value = '0';                   if (this.priceFilter) this.priceFilter.value = 'all';                   if (this.offerTypeSelect) this.offerTypeSelect.value = 'all';                }                if (d === null && pr === null && ot === null && b.getAttribute("data-type") !== "custom") {                   discBtns.forEach(ro => ro.classList.remove('active'));                   b.classList.add('active');                } else if (b.getAttribute("data-type") !== "custom") {                   // Only operate on hardcoded buttons (those without data-type)                   discBtns.forEach(ro => {                      if (!ro.getAttribute('data-d') && !ro.getAttribute('data-pr') && !ro.getAttribute('data-ot') && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active');                   });                                      let makeActive = true;                   if (d !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-d') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   } else if (pr !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-pr') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   } else if (ot !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-ot') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   }                                      if (makeActive) b.classList.add('active');                                      // Check if anything is active, if not activate "All"                   let anyActive = false;                   discBtns.forEach(ro => { if (ro.classList.contains('active') && ro.getAttribute('data-type') !== 'custom') anyActive = true; });                   if (!anyActive) {                       discBtns.forEach(ro => { if (!ro.getAttribute('data-d') && !ro.getAttribute('data-pr') && !ro.getAttribute('data-ot') && ro.getAttribute('data-type') !== 'custom') ro.classList.add('active'); });                   }                }                                this.fetchDeals(this.currentQuery);             });          });          if (this.brandTrigger && this.brandDropdown) {            this.brandTrigger.addEventListener('click', () => {              this.brandDropdown.classList.toggle('active');            });            document.addEventListener('click', (e) => {              if (this.brandFilterWrapper && !e.composedPath().includes(this.brandFilterWrapper)) {                this.brandDropdown.classList.remove('active');              }            });          }          const showAutocomplete = () => {             if (this.getViewMode() !== 'savings_squad' || !this.autocompleteDropdown || !this.airedaleTags) return;                          let terms = this.airedaleTags;             if (this.airedaleBrands) {                terms = terms.concat(this.airedaleBrands.map(b => b.formatted_value));             }             terms = [...new Set(terms)];                          const query = this.searchInput.value.trim();             let matches = [];             if (query.length > 0) {                 matches = terms.filter(t => t.toLowerCase().includes(query.toLowerCase()) && t.toLowerCase() !== query.toLowerCase());             } else {                 matches = terms;             }                          if (matches.length > 0) {                 this.autocompleteDropdown.innerHTML = matches.map(m => `\x3Cdiv class="tg-df-autocomplete-item" data-tag="${this.escapeHTML(m)}">${this.escapeHTML(m)}<` + `/div>`).join('');                 this.autocompleteDropdown.classList.add('active');             } else {                 this.autocompleteDropdown.classList.remove('active');             }          };          let debounceTimer;          if(this.searchInput) {            this.searchInput.addEventListener('focus', showAutocomplete);            this.searchInput.addEventListener('input', (e) => {              clearTimeout(debounceTimer);              const query = e.target.value.trim();              this.currentQuery = query;              showAutocomplete();              debounceTimer = setTimeout(() => {                this.updateURLParams();                if (query.length > 2) {                  this.fetchDeals(query);                } else if (query.length === 0) {                  if (this.getViewMode() === 'savings_squad') {                    this.activeDealTag = null;                    this.currentQuery = '';                    if (this.categoryFilter) this.categoryFilter.value = 'all';                    this.fetchDeals('');                  } else {                    this.deals = [];                    this.render();                  }                }              }, 400);            });            this.searchInput.addEventListener('keypress', (e) => {              if (e.key === 'Enter') {                if (this.autocompleteDropdown) this.autocompleteDropdown.classList.remove('active');                clearTimeout(debounceTimer);                const query = e.target.value.trim();                this.currentQuery = query;                                let isTag = false;                if (this.airedaleTags && this.airedaleTags.includes(query)) isTag = true;                if (this.airedaleBrands && this.airedaleBrands.some(b => b.formatted_value === query)) isTag = true;                this.activeDealTag = isTag ? query : null;                                trackElementInteraction({ id: 'search-submit', name: 'Ask', label: 'Ask (main search)', text: query });                this.updateURLParams();                if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                   if (query.length === 0 && this.getViewMode() === 'savings_squad') {                       if (this.categoryFilter) this.categoryFilter.value = 'all';                   }                   this.fetchDeals(query);                }              }            });          }          if (this.autocompleteDropdown) {             this.autocompleteDropdown.addEventListener('click', (e) => {                const item = e.target.closest('.tg-df-autocomplete-item');                if (item) {                   const tag = item.getAttribute('data-tag');                   this.currentQuery = tag;                   if (this.searchInput) this.searchInput.value = tag;                   this.activeDealTag = tag;                   if (this.categoryFilter && this.airedaleTags.includes(tag)) {                       this.categoryFilter.value = tag;                   }                   this.autocompleteDropdown.classList.remove('active');                   this.updateURLParams();                   this.fetchDeals(tag);                }             });             document.addEventListener('click', (e) => {               if (this.autocompleteDropdown && this.searchInput && !e.composedPath().includes(this.searchInput) && !e.composedPath().includes(this.autocompleteDropdown)) {                 this.autocompleteDropdown.classList.remove('active');               }             });          }          if (this.searchBtn) {            this.searchBtn.addEventListener('click', () => {              if (this.autocompleteDropdown) this.autocompleteDropdown.classList.remove('active');              clearTimeout(debounceTimer);              const query = this.searchInput.value.trim();              trackElementInteraction({ id: 'search-submit', name: 'Ask', label: 'Ask (main search)', text: query });                            let isTag = false;              if (this.airedaleTags && this.airedaleTags.includes(query)) isTag = true;              if (this.airedaleBrands && this.airedaleBrands.some(b => b.formatted_value === query)) isTag = true;              this.activeDealTag = isTag ? query : null;                            this.currentQuery = query;              this.updateURLParams();              if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                 if (query.length === 0 && this.getViewMode() === 'savings_squad') {                     if (this.categoryFilter) this.categoryFilter.value = 'all';                 }                 this.fetchDeals(query);              }            });          }          if(this.sortSelect && this.sortSelect.querySelector('option[value="date_desc"]') === null) {              const option = document.createElement('option');              option.value = "date_desc";              option.text = "Newest First";              this.sortSelect.insertBefore(option, this.sortSelect.firstChild);          }          if(this.sortSelect) this.sortSelect.addEventListener('change', () => {            trackElementInteraction({ id: `sort-option-${this.sortSelect.value}`, name: 'Sort', label: `Sort: ${this.sortSelect.options[this.sortSelect.selectedIndex].text}` });            this.updateURLParams();            if (this.deals.length > 0) {              this.sortData();              this.render();            }          });                    const priceFilter = this.root.querySelector('#tg-df-price-filter');          if (priceFilter) {            this.priceFilter = priceFilter;            this.priceFilter.addEventListener('change', () => {              trackElementInteraction({ id: `filter-price-${this.priceFilter.value}`, name: 'Price', label: this.priceFilter.options[this.priceFilter.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }            });          }          const updateCustomPrice = () => {             this.updateURLParams();             if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);             } else {                this.render();             }          };          if (this.customPriceMin) {             this.customPriceMin.addEventListener('change', updateCustomPrice);             this.customPriceMin.addEventListener('keypress', (e) => {                if (e.key === 'Enter') updateCustomPrice();             });          }          if (this.customPriceMax) {             this.customPriceMax.addEventListener('change', updateCustomPrice);             this.customPriceMax.addEventListener('keypress', (e) => {                if (e.key === 'Enter') updateCustomPrice();             });          }          const discountFilter = this.root.querySelector('#tg-df-discount-filter');          if (discountFilter) {            this.discountFilter = discountFilter;            this.discountFilter.addEventListener('change', () => {              trackElementInteraction({ id: `filter-discount-${this.discountFilter.value}`, name: 'Discount', label: this.discountFilter.options[this.discountFilter.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }            });          }          if (this.categoryFilter) {            this.categoryFilter.addEventListener('change', (e) => {               const val = e.target.value === 'all' ? null : e.target.value;               this.activeDealTag = val;               if (val) {                 this.currentQuery = val;               } else {                 if (this.searchInput && this.currentQuery === document.querySelector('#tg-df-brand-trigger')?.getAttribute('data-active-brand')) {                     // don't clear current query if a brand is selected                 } else if (this.searchInput) {                     this.currentQuery = '';                     this.searchInput.value = '';                 }               }               this.fetchSavingsSquad();            });          }                    if (this.settingsToggle) {            this.settingsToggle.addEventListener('click', () => {              const o = this.settingsPanel.classList.toggle('active');              this.settingsBackdrop.classList.toggle('active');              if (o) trackElementInteraction({ id: 'filter-open', name: 'Filters', label: 'Open filters' });            });          }                    if (this.settingsBackdrop) {            this.settingsBackdrop.addEventListener('click', () => {              this.settingsPanel.classList.remove('active');              this.settingsBackdrop.classList.remove('active');            });          }                    if (this.regionSelect) {            this.regionSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-region-${this.regionSelect.value}`, name: 'Region', label: this.regionSelect.options[this.regionSelect.selectedIndex].text });              this.updateURLParams();              this.updatePriceDropdownCurrency();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.retailerSelect) {            this.retailerSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-merchant-${this.retailerSelect.value}`, name: 'Retailer', label: this.retailerSelect.options[this.retailerSelect.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.offerTypeSelect) {            this.offerTypeSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-offertype-${this.offerTypeSelect.value}`, name: 'Offer Type', label: this.offerTypeSelect.options[this.offerTypeSelect.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.viewModeSelect) {            this._prevViewMode = this.viewModeSelect.value;            this.viewModeSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-viewmode-${this.viewModeSelect.value}`, name: 'View Mode', label: this.viewModeSelect.options[this.viewModeSelect.selectedIndex].text });                            // Reset all active toggles and filters to prevent config carry-over              this.selectedBrands = [];              if (this.brandTrigger) this.brandTrigger.innerText = 'Select Brands';              if (this.brandDropdown) {                const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                chks.forEach(chk => { chk.checked = false; });              }              if (this.priceFilter) this.priceFilter.value = 'all';              if (this.customPriceMin) this.customPriceMin.value = '';              if (this.customPriceMax) this.customPriceMax.value = '';              if (this.sortSelect) this.sortSelect.value = 'date_desc';              if (this.discountFilter) this.discountFilter.value = '0';              if (this.retailerSelect) this.retailerSelect.value = '';              if (this.offerTypeSelect) this.offerTypeSelect.value = '';              if (this.rowsSelect) this.rowsSelect.value = '12';              if (this.categoryFilter) this.categoryFilter.value = 'all';              this.activeDealTag = null;              this.updateURLParams();              this.applyLayoutMode();                            if (this.getViewMode() === 'savings_squad' || this._prevViewMode === 'savings_squad') {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }              this._prevViewMode = this.viewModeSelect.value;            });          }                    if (this.rowsSelect) {            this.rowsSelect.addEventListener('change', () => {              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.dealModeToggle) {            this.dealModeToggle.addEventListener('change', () => {              this.updateURLParams();              this.render();            });          }          if (this.editorModeToggle) {             this.editorModeToggle.addEventListener('change', (e) => {                this.editorMode = e.target.checked;                this.render();                this.updateFloatingCopyBar();             });          }          if (this.editorCopyBtn) {             this.editorCopyBtn.addEventListener('click', () => {                this.copySelectedDealsToCMS();             });          }          if (this.editorClearBtn) {             this.editorClearBtn.addEventListener('click', () => {                this.selectedDeals.clear();                this.render();                this.updateFloatingCopyBar();             });          }          if (this.grid) {            this.grid.addEventListener('change', (e) => {               if (e.target.classList.contains('tg-df-deal-checkbox')) {                  const dealId = e.target.getAttribute('data-id');                  if (e.target.checked) {                     const dealObj = this.deals.find(d => d.id === dealId);                     if (dealObj) this.selectedDeals.set(dealId, dealObj);                  } else {                     this.selectedDeals.delete(dealId);                  }                  this.updateFloatingCopyBar();               }            });            this.grid.addEventListener('click', (e) => {              const dealCard = e.target.closest('[data-action="deal-click"]');              const similarCard = e.target.closest('[data-action="view-similar-click"]');              const cardLink = dealCard || similarCard;              if (cardLink) {                const productName = cardLink.getAttribute('data-product-name');                const merchantName = cardLink.getAttribute('data-merchant-name');                const productId = cardLink.getAttribute('data-analytics-id');                const price = parseFloat(cardLink.getAttribute('data-price')) || null;                const prevPriceStr = cardLink.getAttribute('data-previous-price');                const previousPrice = prevPriceStr ? parseFloat(prevPriceStr) : null;                const originalLink = cardLink.getAttribute('data-original-link');                const finalHref = cardLink.href || cardLink.getAttribute('href') || '';                let actualRevenueId = cardLink.getAttribute('data-revenue-id');                const revMatch = finalHref.match(/(?:subId1|xcust|clickref|ascsubtag)=[^&]*?(\d{18,20})(?:&|$)/i);                if (revMatch && revMatch[1]) {                  actualRevenueId = revMatch[1];                }                const rewrittenLink = finalHref;                const revenueId = actualRevenueId;                const index = parseInt(cardLink.getAttribute('data-index'), 10) || 0;                const inStock = cardLink.getAttribute('data-in-stock') === 'true';                const totalText = cardLink.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: cardLink.getAttribute('data-model-id') || null,                    matchId: cardLink.getAttribute('data-match-id') || null,                    brand: cardLink.getAttribute('data-model-brand') || null,                    parent: cardLink.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: cardLink.getAttribute('data-merchant-id') || null,                    network: cardLink.getAttribute('data-merchant-network') || null,                    url: cardLink.getAttribute('data-merchant-url') || null,                    name: merchantName                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: normalizeCurrency(this.escapeHTML(cardLink.getAttribute('data-currency') || '$'))                };                if (dealCard) {                  trackDealClick(trackingParams);                } else {                  trackViewSimilarClick(trackingParams);                }              }              const couponsBtn = e.target.closest('[data-action="coupons-click"]');              if (couponsBtn) {                trackElementInteraction({                  id: 'product-card-show-coupons',                  name: 'Coupons',                  label: `Product card coupons: ${couponsBtn.getAttribute('data-merchant')}`                });              }            });          }          this.setupScrollListeners();        }        setupScrollListeners() {          const containers = [             this.root.querySelector('.tg-df-carousel-roundels'),             this.root.querySelector('.tg-df-carousel-filters-wrap'),             this.root.querySelector('#tg-df-grid')          ];                    containers.forEach(container => {             if (!container) return;                          const checkScroll = () => {                if (!container.parentElement) return;                const leftBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-left');                const rightBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-right');                                if (leftBtn) {                   if (container.scrollLeft <= 5) leftBtn.style.display = 'none';                   else leftBtn.style.display = 'flex';                }                                if (rightBtn) {                   if (container.scrollWidth <= container.clientWidth) {                       rightBtn.style.display = 'none';                   } else if (container.scrollLeft >= container.scrollWidth - container.clientWidth - 5) {                       rightBtn.style.display = 'none';                   } else {                       rightBtn.style.display = 'flex';                   }                }             };                          container.addEventListener('scroll', checkScroll);             checkScroll();                          window.addEventListener('resize', checkScroll);                          const observer = new MutationObserver(checkScroll);             observer.observe(container, { childList: true, subtree: true, characterData: false });          });        }        get widgetTypeName() {          const mode = this.viewModeSelect ? this.viewModeSelect.value : (this.viewModeOverride || 'auto');          switch(mode) {              case 'carousel': return 'Carousel';              case 'savings_squad': return 'Savings Squad';              case 'grid': return 'Grid';              case 'row': return 'Row';              default: return 'Auto Collection';          }        }        getRowsLimit() {          if (this.rowsSelect && this.rowsSelect.value) return parseInt(this.rowsSelect.value, 10);          let configSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {             configSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {             configSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(configSource);          if (params.has('rows')) return parseInt(params.get('rows'), 10) || 12;          return 12;        }        getAreaCode() {          if (this.regionSelect && this.regionSelect.value) {            if (this.regionSelect.value === 'auto') return null;            return this.regionSelect.value;          }          let area = null;          try {            const locale = window.navigator.language || window.navigator.userLanguage;            if (locale && locale.includes('-')) {              area = locale.split('-')[1].toUpperCase();            } else if (locale && locale.length === 2) {              if (locale.toUpperCase() === 'EN') { area = 'US'; }              else { area = locale.toUpperCase(); }            }          } catch (e) { /* Ignore */ }                    // Map to known valid options or fallback to US          const valid = ['US', 'GB', 'CA', 'AU', 'DE', 'FR', 'IT'];          if (area === 'UK') area = 'GB';          if (valid.includes(area)) {             return area;          }          return 'US';        }        async 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 = this.decodeHTML(description.replace(/<br\s*\/?>/gi, ' ').replace(/<\/?(p|div)[^>]*>/gi, ' ').replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').replace(/View Deal$/i, '').trim());                summaryTitle = this.decodeHTML(summaryTitle);                                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.getFilteredDeals().slice(0, this.displayLimit), this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        isBroadQuery(query) {          const q = query.toLowerCase();          const intentModifiers = ['deals', 'best', 'sale', 'under', 'cheap', 'offers', 'discount'];          return intentModifiers.some(term => q.includes(term));        }        async fetchHawkDeals(query) {          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.getFilteredDeals().slice(0, this.displayLimit), this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        async fetchAdviserDeals(query) {          // ======================================================================          // TODO: ADVISER API REPLACEMENT          // The code below simulates the Adviser API response using mock data.          // Once the real endpoint is ready, remove getAdviserMockData() and           // perform an actual fetch() request similar to fetchHawkDeals().          // Example:          // const area = this.getAreaCode();          // let apiUrl = `https://your-adviser-api.com/search?q=${query}&area=${area}`;          // if (this.priceFilter && this.priceFilter.value !== 'all') {          //   const val = this.priceFilter.value;          //   if (val === 'under50') apiUrl += '&filter_max_price=50';          //   else if (val === '50_100') apiUrl += '&filter_max_price=100';          //   else if (val === '100_200') apiUrl += '&filter_max_price=200';          //   else if (val === '200_500') apiUrl += '&filter_max_price=500';          // }          // const res = await fetch(apiUrl);          // const rawData = await res.json();          // ======================================================================          // Simulating network latency          await new Promise(resolve => setTimeout(resolve, 400));                    const rawData = this.getAdviserMockData();          let offers = [];                    if (rawData && rawData.data && rawData.data.Get && Array.isArray(rawData.data.Get.Deal)) {            offers = rawData.data.Get.Deal;          }                    // Basic client-side filtering for the mock if we want it to react to the query          const q = query.toLowerCase();          const selectedRetailer = (this.retailerSelect && this.retailerSelect.value) ? this.retailerSelect.value.toLowerCase() : null;                    offers.forEach(item => {            const dataObj = item;                        // Apply retailer filter            const itemRetailer = (dataObj.dataRetailer || '').toLowerCase();            if (selectedRetailer && itemRetailer !== selectedRetailer && !itemRetailer.includes(selectedRetailer)) {              return;            }                        // Apply mock price filter            let price = dataObj.dataDiscountedPrice || 0;            if (typeof price === 'string') {              price = parseFloat(price.replace(/[^0-9.]/g, ''));            }            let priceVal = null;            const min = this.customPriceMin ? this.customPriceMin.value : '';            const max = this.customPriceMax ? this.customPriceMax.value : '';            if (min || max) {               priceVal = `${min}_${max}`;            } else if (this.priceFilter && this.priceFilter.value !== 'all') {               priceVal = this.priceFilter.value;            }            if (priceVal) {              if (priceVal === 'under50' && price >= 50) return;              if (priceVal === 'over50' && price <= 50) return;              if (priceVal === 'over30' && price <= 30) return;              if (priceVal === 'over500' && price <= 500) return;              if (priceVal.includes('_')) {                 const parts = priceVal.split('_');                 if (parts[0] && price < parseFloat(parts[0])) return;                 if (parts[1] && price > parseFloat(parts[1])) return;              }            }                        // Map Adviser schema to our widget's expected schema            const mappedData = {              url: dataObj.linkHREF || dataObj.dataLink || '#',              image: dataObj.imageURL || (dataObj.image && dataObj.image.src) || '',              title: dataObj.dataProduct || (dataObj.product && dataObj.product.name) || 'Product Deal',              merchant: dataObj.dataRetailer || 'Retailer',              price: dataObj.dataDiscountedPrice || 0,              currency: dataObj.dataCurrency === 'USD' ? '$' : (dataObj.dataCurrency || '$'),              msrp: dataObj.dataOriginalPrice || null            };                        const titleLow = mappedData.title.toLowerCase();            const merchLow = mappedData.merchant.toLowerCase();                        // Smarter mock filtering            let isMatch = false;            if (q === '' || this.isBroadQuery(q)) {              isMatch = true;            } else if (titleLow.includes(q) || merchLow.includes(q)) {              isMatch = true;            } else if ((q.includes('laptop') || q.includes('mac') || q.includes('pc')) && (titleLow.includes('macbook') || titleLow.includes('laptop'))) {              isMatch = true;            } else if ((q.includes('tv') || q.includes('television')) && (titleLow.includes('tv') || titleLow.includes('oled') || titleLow.includes('qled'))) {              isMatch = true;            } else if ((q.includes('phone') || q.includes('smartphone')) && (titleLow.includes('galaxy') || titleLow.includes('phone'))) {              isMatch = true;            } else if ((q.match(/watch|fitness|run|shoe/)) && (titleLow.includes('forerunner') || titleLow.includes('saucony') || titleLow.includes('watch'))) {              isMatch = true;            }                        if (isMatch) {               this.deals.push(this.extractDealData(mappedData));            }          });                    let rowLimit = this.getRowsLimit();          // Intentionally omitting the slice here to allow "Load More" to work if the API returns more                    this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.getFilteredDeals().slice(0, this.displayLimit), this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        getAdviserMockData() {          return {            "data": {              "Get": {                "Deal": [                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 300,                    "dataOriginalPrice": 399,                    "dataProduct": "Samsung Galaxy A36",                    "dataRetailer": "Samsung",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/MqDYsukV3JBG54te6dEs7j.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 14,                    "dataOriginalPrice": 24,                    "dataProduct": "Blink Mini",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/3JurmAjHsDa5tPdaHAwEV8.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 59,                    "dataOriginalPrice": 99,                    "dataProduct": "Ring Video Doorbell",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/rAh4uR7AsAsALCCLTXnLNJ.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 10,                    "dataOriginalPrice": 599,                    "dataProduct": "MacBook Neo",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/Lg4Dvg68j9SbB5CPNrTEpH.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 749,                    "dataOriginalPrice": 849,                    "dataProduct": "65\\\" Fire TV Omni 4K QLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/SG34ZWodUkLTxJvMTbjPYR.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 71,                    "dataOriginalPrice": 160,                    "dataProduct": "Saucony Hurricane 24",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/vxf7UD5T2Am7guVzFoFcZ4.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 649,                    "dataOriginalPrice": 749,                    "dataProduct": "Garmin Forerunner 970",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/3GKnEu7CdhtxPMfnPCMCiA.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1049,                    "dataOriginalPrice": 1499,                    "dataProduct": "LG 48\\\" C4 4K OLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/imvwZV9zoMD6fn9Afuge35.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1499,                    "dataOriginalPrice": 2199,                    "dataProduct": "Samsung 49\\\" Odyssey Neo G9 4K Gaming Monitor",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/XWDEJ5dUAE2nhK8k3Jk7k7.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 299,                    "dataOriginalPrice": 699,                    "dataProduct": "EGOHOME Black Memory Foam Mattress (queen)",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/hMUemtAejNETLVYxNrktzm.jpg"                  }                ]              }            }          };        }        decodeHTML(html) {          if (!html) return '';          const txt = document.createElement("textarea");          txt.innerHTML = String(html);          return txt.value;        }        extractDealData(item) {          const priceRawStr = String(item.price || item.current_price || '0');          const msrpRawStr = String(item.was_price || item.msrp || item.original_price || '0');          const rawPrice = parseFloat(priceRawStr.replace(/[^\d.]/g, '')) || 0;          const rawMsrp = parseFloat(msrpRawStr.replace(/[^\d.]/g, '')) || 0;          const isCheckPrice = rawPrice === 0 || priceRawStr === '0.00' || priceRawStr === '0';                    let originalImageUrl = item.image || item.image_url || item.product_image || '';          let imageUrl = originalImageUrl;          if ((!imageUrl || isCheckPrice) && item.model_image_url) {             imageUrl = item.model_image_url;             originalImageUrl = imageUrl;          } else if ((!imageUrl || isCheckPrice) && item.model_image) {             imageUrl = item.model_image;             originalImageUrl = imageUrl;          }                    if (imageUrl) {            imageUrl = imageUrl.replace(/-(\d+)-(\d+)(\.[a-z.]+)$/i, '$3');          }                    let fallbackImage = '';          if (originalImageUrl && originalImageUrl !== imageUrl) {             fallbackImage = originalImageUrl;          } else if (item.model_image && item.model_image !== imageUrl) {             fallbackImage = item.model_image;          } else if (item.model_image_url && item.model_image_url !== imageUrl) {             fallbackImage = item.model_image_url;          }                    const rawCurrency = item.currency || item.currency_symbol || '$';                    let savingLabel = item.percentage_saving_label || '';          if (!savingLabel && rawMsrp > rawPrice && rawPrice > 0) {            const pct = Math.round(((rawMsrp - rawPrice) / rawMsrp) * 100);            if (pct > 0) {              savingLabel = `${pct}% OFF`;            }          }                    const isPrime = item.shipping && item.shipping.prime === true;                    let scoreRaw = (item.review_score !== undefined && item.review_score !== null && item.review_score > 0) ? parseFloat(item.review_score) : null;          let starRating = 0;          if (scoreRaw !== null) {            starRating = Math.round((scoreRaw > 10 ? scoreRaw / 20 : scoreRaw / 2) * 2) / 2;          }                    return {            id: item.offer_id || item.link || item.url || item.offer_link || Math.random().toString(),            url: item.link || item.url || item.offer_link || '#',            image: imageUrl,            fallbackImage: fallbackImage,            title: this.decodeHTML(item.name || item.title || item.model_name || item.product_name || 'Unknown Product'),            brand: this.decodeHTML(item.brand || ''),            productName: this.decodeHTML(item.model_name || item.product_name || item.name || ''),            merchant: this.decodeHTML(item.merchant_name || item.merchant || item.retailer || 'Retailer'),            price: item.price !== undefined ? String(item.price) : '0.00',            currency: this.decodeHTML(rawCurrency),            msrp: item.was_price || item.msrp || item.original_price || null,            rawPrice: rawPrice,            rawMsrp: rawMsrp,            hasWasPrice: (item.was_price !== undefined && item.was_price !== null),            isCheckPrice: isCheckPrice,            savingLabel: savingLabel,            isPrime: isPrime,            starRating: starRating > 0 ? starRating : null,            modelId: item.model_id || '',            productKey: item.product_key || '',            merchantId: (item.merchant && typeof item.merchant === 'object') ? item.merchant.id || '' : '',            matchId: item.match_id || '',            merchantNetwork: (item.merchant && typeof item.merchant === 'object') ? item.merchant.an || '' : '',            merchantUrl: (item.merchant && typeof item.merchant === 'object') ? item.merchant.url || '' : '',            modelBrand: item.model_brand || item.brand || '',            modelParent: item.model_parent || ''          };        }        sortData() {          const sortVal = this.sortSelect ? this.sortSelect.value : '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 finalHref = btn.href || btn.getAttribute('href') || '';                let actualRevenueId = btn.getAttribute('data-revenue-id');                const revMatch = finalHref.match(/(?:subId1|xcust|clickref|ascsubtag)=[^&]*?(\d{18,20})(?:&|$)/i);                if (revMatch && revMatch[1]) {                  actualRevenueId = revMatch[1];                }                const rewrittenLink = finalHref;                const revenueId = actualRevenueId;                const index = parseInt(btn.getAttribute('data-index'), 10) || 0;                const inStock = btn.getAttribute('data-in-stock') === 'true';                const totalText = btn.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: btn.getAttribute('data-model-id') || null,                    matchId: btn.getAttribute('data-match-id') || null,                    brand: btn.getAttribute('data-model-brand') || null,                    parent: btn.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: btn.getAttribute('data-merchant-id') || null,                    network: btn.getAttribute('data-merchant-network') || null,                    url: btn.getAttribute('data-merchant-url') || null,                    name: merchantNameAttr                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: btn.getAttribute('data-currency') || 'USD'                };                if (typeof trackDealClick === 'function') {                  trackDealClick(trackingParams);                }              });            });                                  } catch (e) {            console.warn(e);            content.innerHTML = `\x3Cdiv class="tg-df-message">Failed to load vouchers.${_div}`;          }        }        render() {          try {            if (this.getViewMode() === 'savings_squad' && this.airedaleTags.length > 0) {              if (this.categoryFilterWrapper) {                 this.categoryFilterWrapper.style.display = 'flex';              }              if (this.categoryFilter) {                 const _option = '<' + '/option>';                 let optionsHtml = `\x3Coption value="all">All Categories${_option}`;                 this.airedaleTags.forEach(tag => {                    const isSelected = this.activeDealTag === tag ? 'selected' : '';                    optionsHtml += `\x3Coption value="${this.escapeHTML(tag)}" ${isSelected}>${this.escapeHTML(tag)}${_option}`;                 });                 this.categoryFilter.innerHTML = optionsHtml;                 this.categoryFilter.value = this.activeDealTag || 'all';              }            } else {               if (this.categoryFilterWrapper) {                  this.categoryFilterWrapper.style.display = 'none';               }            }            const displayDeals = this.getFilteredDeals();          // HACK: Hide closing tags from the CMS HTML sanitizer so it doesn't strip them during in-page injection          const _div = '<' + '/div>';          const _span = '<' + '/span>';          const _a = '<' + '/a>';          const _h3 = '<' + '/h3>';          const _p = '<' + '/p>';          const _strong = '<' + '/strong>';          const _sup = '<' + '/sup>';          const _button = '<' + '/button>';          if (displayDeals.length === 0) {            if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {              if (this.deals.length > 0) {                 this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                  No deals match your selected filters.                ${_div}`;              } else if (this.getViewMode() === 'savings_squad' && this.currentQuery.length <= 2) {                 // Do not show "no exact matches" if query is empty for savings_squad                 this.grid.innerHTML = '';              } else {                 this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                  No exact matches found for "\x3Cstrong>${this.escapeHTML(this.currentQuery)}${_strong}". Try adjusting your search term.                ${_div}`;              }            } else {              this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                Search product or category names to discover the best deals from across the web.              ${_div}`;            }            return;          }          let dealsHtml = displayDeals.slice(0, this.displayLimit).map((deal, index) => {            try {               const currencySym = this.escapeHTML(deal.currency);               const isoCurrencyCode = normalizeCurrency(currencySym);               const escapedPrice = this.escapeHTML(deal.price);               const escapedMsrp = this.escapeHTML(deal.msrp);               const areaCode = this.getAreaCode();                              const revenueId = generateRevenueId(deal.url, deal.title, deal.merchant, null);               const originalLink = deal.url;               const rewrittenLink = rewriteAffiliateLink(deal.url, areaCode, revenueId);                        const productCategoryName = 'deals';            const dataAttr = `              data-action="${deal.isCheckPrice ? 'view-similar-click' : 'deal-click'}"              data-analytics-id="${this.escapeHTML(deal.externalProductId || deal.id || '')}"              data-product-name="${this.escapeHTML(deal.title)}"              data-merchant-name="${this.escapeHTML(deal.merchant)}"              data-price="${deal.rawPrice || ''}"              data-previous-price="${deal.rawMsrp || ''}"              data-original-link="${this.escapeHTML(originalLink)}"              data-revenue-id="${revenueId}"              data-index="${index}"              data-total="${displayDeals.length}"              data-in-stock="${deal.inStock !== false}"              data-currency="${this.escapeHTML(isoCurrencyCode)}"              data-model-id="${this.escapeHTML(deal.modelId || '')}"              data-product-key="${this.escapeHTML(deal.productKey || '')}"              data-merchant-id="${this.escapeHTML(deal.merchantId || '')}"            `;                        let priceGroupHtml = '';            let isSavingsSquadMode = this.getViewMode() === 'savings_squad';            let ctaText = 'View Deal';            let formattedPrice = '';            let msrpHtml = '';                        if (deal.isCheckPrice) {              ctaText = 'View Deal';              if (isSavingsSquadMode) {                priceGroupHtml = ``;              } else {                priceGroupHtml = `                  \x3Cdiv class="tg-df-card-price-group">                    \x3Cspan class="tg-df-card-price" style="font-size: 15px; font-weight: 500; font-style: italic;">See price at retailer${_span}                  ${_div}                `;              }            } else {              // Format Price              formattedPrice = escapedPrice.includes(currencySym)                 ? escapedPrice                 : `${currencySym}${escapedPrice}`;                              // Format MSRP              msrpHtml = deal.msrp && deal.rawMsrp > deal.rawPrice                ? `\x3Cspan class="tg-df-card-msrp">${escapedMsrp.includes(currencySym) ? escapedMsrp : currencySym + escapedMsrp}${_span}`                : '';                              priceGroupHtml = isSavingsSquadMode ? `` : `                \x3Cdiv class="tg-df-card-price-group">                  \x3Cspan class="tg-df-card-price">${formattedPrice}${_span}                  ${msrpHtml}                ${_div}              `;            }                        const discountBadgeHtml = deal.savingLabel && !deal.isCheckPrice              ? `\x3Cspan class="tg-df-card-discount-badge">${this.escapeHTML(deal.savingLabel)}${_span}`              : '';                          // HACK for CMS            const _button = '<' + '/button>';            const _svg = '<' + '/svg>';            const _path = '<' + '/path>';            const _rect = '<' + '/rect>';            const _circle = '<' + '/circle>';            const _polyline = '<' + '/polyline>';            const _line = '<' + '/line>';                        let badgesHtml = '';            const primeBadge = deal.isPrime ? `              \x3Cspan class="tg-df-tag tg-df-tag-prime">                \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">                  \x3Cpath d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z">${_path}                ${_svg} Prime              ${_span}            ` : '';                        const couponsBadge = deal.merchant && deal.merchant.toLowerCase().includes('amazon') ? '' : `              \x3Cdiv class="tg-df-coupon-wrapper" data-merchant="${this.escapeHTML(deal.merchant)}" style="display:inline-flex; align-items:center;">                \x3Cdiv class="tg-df-coupon-spinner">${_div}                \x3Cbutton type="button" class="tg-df-tag tg-df-tag-coupons" data-action="coupons-click" data-merchant="${this.escapeHTML(deal.merchant)}" style="display:none;">                  \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">                    \x3Cpath d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z">${_path}                    \x3Cline x1="7" y1="7" x2="7.01" y2="7">${_line}                  ${_svg} Coupons                ${_button}              ${_div}            `;                        // Note: We always add coupons badge if there's a chance, but to allow 3-line titles we check wrapper display state            badgesHtml = `              \x3Cdiv class="tg-df-card-badges">                ${primeBadge}                ${couponsBadge}              ${_div}            `;            const _linearGradient = '<' + '/linearGradient>';            const _polygon = '<' + '/polygon>';            const _stop = '<' + '/stop>';            const _defs = '<' + '/defs>';                        let starHtml = '';            if (deal.starRating) {              let rating = deal.starRating;                            if (rating > 0) {                const fullStars = Math.floor(rating);                const halfStar = (rating - fullStars) >= 0.5 ? 1 : 0;                const emptyStars = Math.max(0, 5 - fullStars - halfStar);                const blue = '#1f69ff'; // Tom's guide brand color from VIEW DEAL button                const gray = '#cbd5e1';                                const starSvgFull = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="${blue}" stroke="${blue}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26">${_polygon}${_svg}`;                                const gradId = 'half_grad_' + Math.floor(Math.random()*1000000);                const starSvgHalf = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" stroke="${blue}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cdefs>\x3ClinearGradient id="${gradId}" x1="0" x2="1" y1="0" y2="0">\x3Cstop offset="50%" stop-color="${blue}">${_stop}\x3Cstop offset="50%" stop-color="transparent">${_stop}${_linearGradient}${_defs}                  \x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26" fill="url(#${gradId})">${_polygon}${_svg}`;                                  const starSvgEmpty = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="${gray}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26">${_polygon}${_svg}`;                                let stars = [];                for (let i=0; i<fullStars; i++) stars.push(starSvgFull);                if (halfStar) stars.push(starSvgHalf);                for (let i=0; i<emptyStars; i++) stars.push(starSvgEmpty);                                starHtml = `\x3Cdiv class="tg-df-card-stars" style="display:flex;align-items:center;margin-bottom:8px;font-size:13px;font-weight:600;color:var(--tg-df-text-muted);">                  \x3Cspan style="margin-right:6px;">Tom's Guide:${_span}                  \x3Cdiv style="display:flex;gap:2px;">                    ${stars.join('')}                  ${_div}                ${_div}`;              }            }            let htmlOutput = '';            if (isSavingsSquadMode) {              htmlOutput += `              \x3Cdiv class="hawk-deal-widget-container tg-df-mobile-only" data-collapsible="true">                ${this.editorMode ? `\x3Cinput type="checkbox" class="tg-df-deal-checkbox" data-id="${this.escapeHTML(deal.id)}" ${this.selectedDeals.has(deal.id) ? 'checked' : ''} style="margin-bottom: 10px;">` : ''}                \x3Cdiv class="hawk-deal-widget-wrap">                  \x3Cdiv class="hawk-deal-widget-image-container">                    \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" rel="sponsored noopener" target="_blank" class="hawk-affiliate-link-deal-widget" ${dataAttr}>                      \x3Cimg ${deal.image ? `src="${this.escapeHTML(deal.image)}"` : ''} alt="${this.escapeHTML(deal.title)}" class="hawk-lazy-image-deal-widget" loading="lazy" width="140" height="160" onerror="${deal.fallbackImage ? `if(!this.dataset.fb) { this.dataset.fb='1'; this.src='${this.escapeHTML(deal.fallbackImage)}'; } else { this.style.opacity='0'; }` : `this.style.opacity='0';`}">                    ${_a}                  ${_div}                  \x3Cdiv class="hawk-deal-widget-text-cta-container">                    \x3Cdiv class="hawk-deal-widget-text-body-container">                      \x3Cdiv class="hawk-deal-widget-text-body-main">                        \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                          ${deal.isCheckPrice ? `                            \x3Cspan class="hawk-deal-widget-title-product-title">${this.escapeHTML(deal.title)}${_span}                          ` : `                            \x3Cspan class="hawk-deal-widget-title-product-title">${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_span}                          `}                        ${_a}                        ${!deal.isCheckPrice && deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `                          \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                            \x3Cspan class="hawk-deal-widget-title-was-price">was ${currencySym}${escapedMsrp}${_span}                          ${_a}                        ` : ''}                        \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                          \x3Cspan class="hawk-deal-widget-title-retailer-price">                            ${!deal.isCheckPrice ? `                              \x3Cspan class="hawk-deal-widget-title-price">now ${formattedPrice}${_span}                              \x3Cspan class="hawk-deal-widget-title-retailer"> at ${this.escapeHTML(deal.merchant)}${_span}                            ` : `                              \x3Cspan class="hawk-deal-widget-title-price">See price at ${this.escapeHTML(deal.merchant)}${_span}                            `}                          ${_span}                        ${_a}                        ${deal.description ? `\x3Cdiv class="hawk-deal-widget-text-body-description tg-df-card-desc-container" style="margin-bottom: 12px; position: relative;">                          \x3Cp class="tg-df-card-desc-content" style="font-size: 13px; color: var(--tg-df-text-muted); margin-bottom: 0; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;">${this.escapeHTML(deal.description)}${_p}                          \x3Cbutton type="button" class="tg-df-card-desc-btn" style="display: none; appearance: none; border: none; color: #000000; font-size: 11px; font-weight: 700; text-transform: uppercase; cursor: pointer; font-family: inherit; position: absolute; bottom: 2px; right: 0; background: linear-gradient(to right, transparent, #fff 20%, #fff); padding: 0 0 0 16px;" onclick="                            var c = this.parentNode;                            if (this.dataset.expanded === 'true') {                              var pd = (c.tagName === 'P') ? c : this.previousElementSibling;                              if (c.tagName === 'P') { c.parentNode.appendChild(this); pd = c; }                              pd.style.display = '-webkit-box';                              pd.style.webkitLineClamp = '3';                              this.textContent = 'READ MORE';                              this.style.position = 'absolute';                              this.style.background = 'linear-gradient(to right, transparent, #fff 20%, #fff)';                              this.style.paddingLeft = '16px';                              this.dataset.expanded = 'false';                            } else {                              var pd = this.previousElementSibling;                              pd.style.display = 'inline';                              pd.style.webkitLineClamp = 'unset';                              this.textContent = 'READ LESS';                              this.style.position = 'static';                              this.style.background = 'transparent';                              this.style.paddingLeft = '4px';                              this.dataset.expanded = 'true';                              pd.appendChild(this);                            }                          ">READ MORE${_button}                        \x3C/div>` : ''}                      ${_div}                    ${_div}                    ${deal.authorName ? `                      \x3Cdiv class="tg-df-author-line-mobile" style="padding: 0 0 12px 0; background: transparent;">                         \x3Cdiv style="display: flex; align-items: center; gap: 12px;">                            ${deal.authorImage ? `\x3Cimg src="${this.escapeHTML(deal.authorImage)}" alt="${this.escapeHTML(deal.authorName)}" class="tg-df-author-img" width="40" height="40" style="border-radius: 50%; object-fit: cover; flex-shrink: 0; aspect-ratio: 1 / 1; min-width: 40px; min-height: 40px;">` : ''}                            \x3Cdiv style="display: flex; flex-direction: column;">                               \x3Cdiv style="font-size: 10px; color: var(--tg-df-text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 2px; font-weight: 600;">\x3Cspan style="color: #FF6600;">${this.escapeHTML(deal.merchant)}${_span} deal recommended by:${_div}                               \x3Cdiv style="font-size: 11px; color: var(--tg-df-text); line-height: 1.3;">                                  \x3Cstrong>\x3Ca href="https://www.tomsguide.com/${this.escapeHTML(deal.documentUrl || '').replace(/^\/+/, '')}" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit; border-bottom: 1px dotted var(--tg-df-text-muted);">${this.escapeHTML(deal.authorName)}${_a}${_strong}                                  ${deal.authorRole && !['null', 'nul', 'undefined'].includes(String(deal.authorRole).toLowerCase()) ? ` • ${this.escapeHTML(deal.authorRole)}` : ''}                                  ${deal.modifiedDate ? `\x3Cdiv style="color: var(--tg-df-text-muted); margin-top: 2px;">${getTimeAgo(deal.modifiedDate)}${_div}` : ''}                               ${_div}                            ${_div}                         ${_div}                      ${_div}                    ` : ''}                    \x3Cdiv class="hawk-deal-widget-footer">                      \x3Cdiv class="hawk-deal-widget-button-wrapper">                        \x3Cdiv class="hawk-deal-widget-preferred-partner-wrapper">                          \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-deal-button" rel="sponsored noopener" target="_blank" ${dataAttr}>                            \x3Cspan>View Deal${_span}                          ${_a}                        ${_div}                      ${_div}                    ${_div}                  ${_div}                ${_div}              ${_div}              `;            }            htmlOutput += `              \x3Cdiv class="tg-df-card ${isSavingsSquadMode ? 'tg-df-desktop-only' : ''}">                ${this.editorMode ? `\x3Cinput type="checkbox" class="tg-df-deal-checkbox" data-id="${this.escapeHTML(deal.id)}" ${this.selectedDeals.has(deal.id) ? 'checked' : ''}>` : ''}                \x3Cdiv class="tg-df-card-image-box">                  ${discountBadgeHtml}                  \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" style="display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;">                    \x3Cimg ${deal.image ? `src="${this.escapeHTML(deal.image)}"` : ''} alt="${this.escapeHTML(deal.title)}" class="tg-df-card-image" loading="lazy" onerror="${deal.fallbackImage ? `if(!this.dataset.fb) { this.dataset.fb='1'; this.src='${this.escapeHTML(deal.fallbackImage)}'; } else { this.style.opacity='0'; }` : `this.style.opacity='0';`}">                  ${_a}                  \x3Cdiv class="tg-df-card-merchant-wrapper" style="position: absolute; bottom: 0; right: 0; background: transparent; padding: 8px 12px; z-index: 10;">                     \x3Cspan class="tg-df-card-merchant-pill" style="text-align: right; margin-bottom: 0;" title="${this.escapeHTML(deal.merchant)}">${this.escapeHTML(deal.merchant)}${_span}                  ${_div}                ${_div}                \x3Cdiv class="tg-df-card-body">                  ${starHtml}                  ${badgesHtml}                  \x3Ch3 class="tg-df-card-title tg-df-custom-savings-squad-title" title="${this.escapeHTML(deal.title)}">                    \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit;">                      ${isSavingsSquadMode                         ? (deal.isCheckPrice                             ? (deal.title && deal.title.includes(':')                                 ? `\x3Cstrong>${this.escapeHTML(deal.title.substring(0, deal.title.indexOf(':') + 1))}${_strong}\x3Cspan style="color: #1f69ff; font-weight: normal;">${this.escapeHTML(deal.title.substring(deal.title.indexOf(':') + 1))}${_span}`                                : this.escapeHTML(deal.title)                              )                             : `\x3Cstrong>${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_strong} ${deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `\x3Cspan style="color: #d0021b; text-decoration: line-through; font-weight: normal; margin-right: 4px;">was ${currencySym}${escapedMsrp}${_span} ` : ''}\x3Cspan style="color: #1f69ff; font-weight: normal;">now ${formattedPrice} at ${this.escapeHTML(deal.merchant)}${_span}`                          )                        : this.escapeHTML(deal.title)                      }                    ${_a}                  ${_h3}                  ${deal.description ? `\x3Cdiv class="tg-df-card-desc-container" style="margin-bottom: 12px; position: relative;">                    \x3Cp class="tg-df-card-desc-content" style="font-size: 13px; color: var(--tg-df-text-muted); margin-bottom: 0; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;">${this.escapeHTML(deal.description)}${_p}                    \x3Cbutton type="button" class="tg-df-card-desc-btn" style="display: none; appearance: none; border: none; color: #000000; font-size: 11px; font-weight: 700; text-transform: uppercase; cursor: pointer; font-family: inherit; position: absolute; bottom: 2px; right: 0; background: linear-gradient(to right, transparent, #fff 20%, #fff); padding: 0 0 0 16px;" onclick="                      var c = this.parentNode;                      if (this.dataset.expanded === 'true') {                        var pd = (c.tagName === 'P') ? c : this.previousElementSibling;                        if (c.tagName === 'P') { c.parentNode.appendChild(this); pd = c; }                        pd.style.display = '-webkit-box';                        pd.style.webkitLineClamp = '3';                        this.textContent = 'READ MORE';                        this.style.position = 'absolute';                        this.style.background = 'linear-gradient(to right, transparent, #fff 20%, #fff)';                        this.style.paddingLeft = '16px';                        this.dataset.expanded = 'false';                      } else {                        var pd = this.previousElementSibling;                        pd.style.display = 'inline';                        pd.style.webkitLineClamp = 'unset';                        this.textContent = 'READ LESS';                        this.style.position = 'static';                        this.style.background = 'transparent';                        this.style.paddingLeft = '4px';                        this.dataset.expanded = 'true';                        pd.appendChild(this);                      }                    ">READ MORE${_button}                  \x3C/div>` : ''}                  \x3Cdiv class="tg-df-card-footer">                    ${deal.authorName ? `                    \x3Cdiv class="tg-df-author-line-desktop" style="padding: 0 0 ${isSavingsSquadMode ? 0 : 12}px 0;">                       \x3Cdiv style="display: flex; align-items: center; gap: 10px;">                          ${deal.authorImage ? `\x3Cimg src="${this.escapeHTML(deal.authorImage)}" alt="${this.escapeHTML(deal.authorName)}" class="tg-df-author-img" width="36" height="36" style="border-radius: 50%; object-fit: cover; flex-shrink: 0; aspect-ratio: 1 / 1; min-width: 36px; min-height: 36px;">` : ''}                          \x3Cdiv style="display: flex; flex-direction: column;">                             \x3Cdiv style="font-size: 10px; color: var(--tg-df-text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 2px; font-weight: 600;">Recommended by:${_div}                             \x3Cdiv style="font-size: 11px; color: var(--tg-df-text); line-height: 1.2;">                                \x3Cstrong>\x3Ca href="https://www.tomsguide.com/${this.escapeHTML(deal.documentUrl || '').replace(/^\/+/, '')}" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit; border-bottom: 1px dotted var(--tg-df-text-muted);">${this.escapeHTML(deal.authorName)}${_a}${_strong}                                ${deal.authorRole && !['null', 'nul', 'undefined'].includes(String(deal.authorRole).toLowerCase()) ? ` • ${this.escapeHTML(deal.authorRole)}` : ''}                                ${deal.modifiedDate ? `\x3Cspan style="color: var(--tg-df-text-muted);"> • ${getTimeAgo(deal.modifiedDate)}${_span}` : ''}                             ${_div}                          ${_div}                       ${_div}                    ${_div}                    ` : ''}                    ${priceGroupHtml}                  ${_div}                ${_div}                \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" class="tg-df-card-cta" style="text-decoration: none; border-radius: 0;">${ctaText}${_a}              ${_div}            `;                        return htmlOutput;            } catch (e) {               console.log("Error rendering deal in map for index", index, typeof deal === 'object' ? JSON.stringify(deal) : deal, "MSG:", e.message);               return '';            }          }).join('');                    if (displayDeals.length > this.displayLimit) {            dealsHtml += `              \x3Cdiv style="width: 100%; display: flex; justify-content: center; margin-top: 16px; grid-column: 1 / -1;">                \x3Cbutton type="button" class="tg-df-tag-outline tg-df-load-more" style="padding: 8px 24px; border-radius: 100px; font-weight: 600; font-size: 14px; cursor: pointer;">Load More${_button}              ${_div}            `;          }                    this.grid.innerHTML = dealsHtml;          // Inject JSON-LD          try {            let targetNode = this.hostContainer || document.head;            let jsonLdScript = targetNode.querySelector('#tg-df-json-ld-' + this.widgetId);            if (!jsonLdScript) {                jsonLdScript = document.createElement('script');                jsonLdScript.type = 'application/ld+json';                jsonLdScript.id = 'tg-df-json-ld-' + this.widgetId;                targetNode.appendChild(jsonLdScript);            }            const jsonLdData = {              "@context": "https://schema.org",              "@type": "ItemList",              "itemListElement": displayDeals.slice(0, this.displayLimit).map((deal, index) => {                 let isoCurrency = "USD";                 if (deal.currency === '£') isoCurrency = "GBP";                 else if (deal.currency === '€') isoCurrency = "EUR";                 else if (deal.currency === 'A$') isoCurrency = "AUD";                 else if (deal.currency === 'CA$') isoCurrency = "CAD";                 const areaCode = typeof this.getAreaCode === 'function' ? this.getAreaCode() : 'US';                 const revenueId = typeof generateRevenueId === 'function' ? generateRevenueId(deal.url, deal.title, deal.merchant, null) : '';                 const rewrittenLink = typeof rewriteAffiliateLink === 'function' ? rewriteAffiliateLink(deal.url, areaCode, revenueId) : deal.url;                 return {                   "@type": "ListItem",                   "position": index + 1,                   "item": {                     "@type": "Product",                     "name": deal.title,                     "image": deal.image || "",                     "description": deal.description || "",                     "brand": {                       "@type": "Brand",                       "name": deal.brand || ""                     },                     "offers": {                       "@type": "Offer",                       "priceCurrency": isoCurrency,                       "price": deal.rawPrice || 0,                       "url": rewrittenLink,                       "seller": {                         "@type": "Organization",                         "name": deal.merchant || ""                       }                     }                   }                 };              }).filter(item => item.item.name)            };            jsonLdScript.textContent = JSON.stringify(jsonLdData);          } catch(e) { console.warn("JSON-LD generation failed", e); }          setTimeout(() => {            const contents = this.root.querySelectorAll('.tg-df-card-desc-content');            contents.forEach(p => {              if (p.scrollHeight > p.clientHeight || p.scrollHeight > 60) {                if (p.nextElementSibling) {                  p.nextElementSibling.style.display = 'block';                }              }            });                        // Allow hawklinks.js to discover and rewrite our widget links             // by appending the .article-body class and manually triggering processArticle.            let container = this.root.classList.contains('tg-df-container') ? this.root : this.root.querySelector('.tg-df-container');            if (container && !container.classList.contains('article-body')) {               container.classList.add('article-body');            }            if (this.grid && !this.grid.classList.contains('article-body')) this.grid.classList.add('article-body');            document.dispatchEvent(new CustomEvent('processArticle', { detail: { element: this.root } }));          }, 50);          const loadMoreBtn = this.grid.querySelector('.tg-df-load-more');          if (loadMoreBtn) {            loadMoreBtn.addEventListener('click', () => {              if (typeof trackElementInteraction === 'function') {                trackElementInteraction({ id: 'load-more', name: 'Load more', label: 'Load More Results' });              }              this.displayLimit += this.getRowsLimit();              this.render();            });          }                      this.bindCouponButtons();            this.checkAndUpdateCoupons();          } catch(e) {            console.warn("Widget render error", e);          }        }                async checkAndUpdateCoupons() {          const wrappers = Array.from(this.root.querySelectorAll('.tg-df-coupon-wrapper'));          if (wrappers.length === 0) return;                    const merchants = [...new Set(wrappers.map(w => w.getAttribute('data-merchant')).filter(Boolean))];          if (merchants.length === 0) return;          const couponResultsMap = await this.checkMerchantsCouponsBulk(merchants);                    for (const merchant of merchants) {            const hasCoupons = !!couponResultsMap[merchant];            const merchantWrappers = wrappers.filter(w => w.getAttribute('data-merchant') === merchant);            merchantWrappers.forEach(wrapper => {              const spinner = wrapper.querySelector('.tg-df-coupon-spinner');              const btn = wrapper.querySelector('.tg-df-tag-coupons');                            if (spinner) spinner.style.display = 'none';                            if (hasCoupons && btn) {                btn.style.display = 'inline-flex';              } else if (!hasCoupons) {                wrapper.style.display = 'none';              }            });          }        }        updateFloatingCopyBar() {          if (!this.editorBar || !this.editorSelectedCount) return;          if (this.editorMode && this.selectedDeals.size > 0) {            this.editorBar.style.display = 'flex';            this.editorSelectedCount.innerText = this.selectedDeals.size;          } else {            this.editorBar.style.display = 'none';          }        }        async copySelectedDealsToCMS() {           function htmlToSlate(htmlString) {              if (!htmlString) return [{ type: 'paragraph', children: [{ text: '' }] }];              let doc;              if (typeof window !== 'undefined' && window.DOMParser) {                 doc = new DOMParser().parseFromString(htmlString, 'text/html');              } else {                 doc = document.implementation.createHTMLDocument('');                 doc.body.innerHTML = htmlString;              }                            function parseNode(node, marks = {}) {                  if (node.nodeType === 3) {                      const text = node.textContent;                      if (!text) return null;                      return { text: text, ...marks };                  }                  if (node.nodeType === 1) {                      const tagName = node.tagName.toLowerCase();                      if (tagName === 'br') {                          return { type: 'line-break', children: [{ text: '' }] };                      }                      if (tagName === 'p') {                          let children = Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                          if (children.length === 0) children.push({ text: "" });                          return { type: 'paragraph', children };                      }                      if (tagName === 'strong' || tagName === 'b') {                          const newMarks = { ...marks, bold: true };                          return Array.from(node.childNodes).map(child => parseNode(child, newMarks)).flat().filter(Boolean);                      }                      if (tagName === 'em' || tagName === 'i') {                          const newMarks = { ...marks, italic: true };                          return Array.from(node.childNodes).map(child => parseNode(child, newMarks)).flat().filter(Boolean);                      }                      if (tagName === 'a') {                          const href = node.getAttribute('href') || '';                          let children = Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                          if (children.length === 0) children.push({ text: "" });                          return {                              type: 'link',                              url: href,                              isNoFollow: (node.getAttribute('rel') || '').includes('nofollow'),                              isSponsored: (node.getAttribute('rel') || '').includes('sponsored'),                              isOpenNewTab: node.getAttribute('target') === '_blank',                              isPreventDataRewrite: false,                              children: children                          };                      }                      return Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                  }                  return null;              }                            let blocksArray = [];              let currentParagraphChildren = [];              function flushParagraph() {                  if (currentParagraphChildren.length > 0) {                      blocksArray.push({ type: 'paragraph', children: currentParagraphChildren });                      currentParagraphChildren = [];                  }              }              Array.from(doc.body.childNodes).forEach(node => {                  const parsed = parseNode(node, {});                  const parsedItems = Array.isArray(parsed) ? parsed : (parsed ? [parsed] : []);                  parsedItems.forEach(item => {                      if (item.type === 'paragraph') {                          flushParagraph();                          blocksArray.push(item);                      } else {                          currentParagraphChildren.push(item);                      }                  });              });              flushParagraph();              if (blocksArray.length === 0) {                  blocksArray = [{ type: 'paragraph', children: [{ text: '' }] }];              }              return blocksArray;           }           const blocks = [];                      this.editorCopyBtn.innerHTML = '\x3Cspan class="tg-df-coupon-spinner" style="display:inline-block; margin-right:8px; border-top-color:#fff;">' + '<' + '/span> Copying...';           for (const deal of Array.from(this.selectedDeals.values())) {              const url = deal.url;              const merchant = deal.merchant;              const title = deal.title;              const image = deal.image;              const currentPrice = deal.currency + deal.rawPrice;              const wasPrice = deal.hasWasPrice && deal.rawMsrp > deal.rawPrice ? deal.currency + deal.rawMsrp : '';                            let couponsChildren = [];              try {                  const area = this.getAreaCode();                  const apiUrl = new URL('https://search-api.fie.future.net.uk/widget.php');                  apiUrl.searchParams.append('model_name', 'Everything');                  apiUrl.searchParams.append('language', 'en-GB');                  apiUrl.searchParams.append('area', area);                  apiUrl.searchParams.append('combine_product_types', '1');                  apiUrl.searchParams.append('filter_merchant_name', merchant);                  apiUrl.searchParams.append('all_filters', 'false');                  apiUrl.searchParams.append('exclude_unlabelled', 'false');                  apiUrl.searchParams.append('include_specs', 'false');                  apiUrl.searchParams.append('sort', 'voucher');                  apiUrl.searchParams.append('distinct_merchants', 'natural');                  apiUrl.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');                  apiUrl.searchParams.append('rows', '3');                  apiUrl.searchParams.append('origin', 'widgets-clientside');                                    let res; try { res = await fetch(apiUrl.toString()); } catch (e) { return; }                  if (res.ok) {                      const data = await res.json();                      let offers = [];                      if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {                        offers = data.widget.data.offers;                      } else if (data && data.data && Array.isArray(data.data.offers)) {                        offers = data.data.offers;                      }                                            if (offers.length > 0) {                          couponsChildren.push({ text: "Also check out these coupons: ", bold: true });                          offers.slice(0, 3).forEach((offer, idx) => {                              const actualOffer = offer.offer || offer;                              const offerName = actualOffer.name || actualOffer.title || offer.model_name || offer.title || offer.name || 'Coupon';                              const linkUrl = actualOffer.link || actualOffer.url || actualOffer.offer_link || '#';                              couponsChildren.push({ type: "line-break", children: [{ text: "" }] });                              couponsChildren.push({ text: "🎟️ " });                              couponsChildren.push({                                  type: "link",                                  url: linkUrl,                                  isNoFollow: true,                                  isSponsored: false,                                  isOpenNewTab: true,                                  isPreventDataRewrite: false,                                  children: [{ text: offerName, bold: true }]                              });                          });                      }                  }              } catch (err) {                  console.warn('Failed to fetch coupons for', merchant, err);              }              let descriptionValue = [];              if (deal.text) {                 descriptionValue = htmlToSlate(deal.text);              } else {                 const dealDescriptions = [                   `Don't miss out on this fantastic deal for the ${title}. It is currently available at ${merchant} for a highly competitive price.`,                   `We've spotted an excellent price drop on the ${title}. Grab it now at ${merchant} before it's gone.`,                   `The ${title} is currently seeing a generous discount over at ${merchant}. This is a perfect time to buy if you've been holding out.`,                   `If you're in the market for the ${title}, ${merchant} has just the deal for you.`,                   `Score the ${title} for less at ${merchant} right now. This is a rare chance to save big.`,                   `Upgrade your setup with the ${title}, now available at a stellar price via ${merchant}.`                 ];                 const randomDescription = dealDescriptions[Math.floor(Math.random() * dealDescriptions.length)];                 descriptionValue = [                    { type: "paragraph", children: [{ text: randomDescription }] }                 ];              }                            if (couponsChildren.length > 0) {                 let lastBlock = descriptionValue[descriptionValue.length - 1];                 if (lastBlock && lastBlock.type === 'paragraph') {                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children.push({ text: "Also check out these coupons: ", bold: true });                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children = lastBlock.children.concat(couponsChildren);                 } else {                     descriptionValue.push({                         type: "paragraph",                         children: [                             { type: "line-break", children: [{ text: "" }] },                             { type: "line-break", children: [{ text: "" }] },                             { text: "Also check out these coupons: ", bold: true },                             { type: "line-break", children: [{ text: "" }] },                             ...couponsChildren                         ]                     });                 }              }              function normalizeCurrencyToISO(symbol) {                const map = { '£': 'GBP', '$': 'USD', 'A$': 'AUD', 'CA$': 'CAD', '€': 'EUR' };                return map[symbol] || symbol;              }              const isoCurrency = normalizeCurrencyToISO(deal.currency);              blocks.push({                 id: (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : 'cms-' + Date.now() + Math.random(),                 blockTypeName: "deal",                 excludeFrom: [],                 collapsible: false,                 props: {                    description: {                       value: descriptionValue,                       touched: false,                       validationMessage: ""                    },                    image: {                       value: {                          credit: [{ type: "paragraph", children: [{ text: merchant }] }],                          dateCreated: Date.now(),                          dateModified: Date.now(),                          distribution: [],                          fileSize: 0,                          height: 1000,                          id: deal.id,                          imageRights: "",                          src: image,                          name: title + ".jpg",                          tags: [],                          width: 1000                       },                       touched: false,                       validationMessage: ""                    },                    showDealButton: { value: true, touched: false, validationMessage: "" },                    isPreferredPartner: { value: false, touched: false, validationMessage: "" },                    linkHref: { value: url, touched: false, validationMessage: "" },                    linkLabel: { value: "", touched: false, validationMessage: "" },                    linkIsNoFollow: { value: true, touched: false, validationMessage: "" },                    linkIsSponsored: { value: false, touched: false, validationMessage: "" },                    linkIsOpenNewWindow: { value: true, touched: false, validationMessage: "" },                    customPromoFlags: { value: [], touched: false, validationMessage: "" },                    showStarDeal: { value: false, touched: false, validationMessage: "" },                    savingType: { value: "none", touched: false, validationMessage: "" },                    starDealPromoFlag: { value: "", touched: false, validationMessage: "" },                    showEditorsChoice: { value: false, touched: false, validationMessage: "" },                    editorsChoiceTitle: { value: "", touched: false, validationMessage: "" },                    hawkPriceCurrency: { value: { value: isoCurrency, label: isoCurrency }, touched: false, validationMessage: "" },                    hawkPrice: { value: deal.hasWasPrice ? String(deal.rawMsrp) : String(deal.rawPrice), touched: false, validationMessage: "" },                    hawkSalePrice: { value: String(deal.rawPrice), touched: false, validationMessage: "" },                    lastCheckedPriceDate: { value: "", touched: false, validationMessage: "" },                    hawkModel: { touched: false, validationMessage: "" },                    productId: { value: "", touched: false, validationMessage: "" },                    voucherId: { value: "", touched: false, validationMessage: "" },                    brand: { value: deal.brand || merchant, touched: false, validationMessage: "" },                    productName: { value: title, touched: false, validationMessage: "" },                    label: { value: "", touched: false, validationMessage: "" },                    retailer: { value: merchant, touched: false, validationMessage: "" },                    priceCheckError: false                 },                 failedFetchError: ""              });           }           const payload = {              type: "articleBuilderPages",              data: blocks           };           const jsonStr = JSON.stringify(payload);                      if (navigator.clipboard && navigator.clipboard.writeText) {              navigator.clipboard.writeText(jsonStr).then(() => {                 this.editorCopyBtn.innerHTML = 'Copied!';                 setTimeout(() => {                    this.editorCopyBtn.innerHTML = '\x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2"><' + '/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"><' + '/path><' + '/svg> Copy to CMS';                 }, 2000);              }).catch(err => {                 console.warn('Failed to copy text: ', err);                 alert('Failed to copy deals to clipboard. See console.');              });           } else {              // Fallback              const textArea = document.createElement("textarea");              textArea.value = jsonStr;              document.body.appendChild(textArea);              textArea.focus();              textArea.select();              try {                 document.execCommand('copy');                 this.editorCopyBtn.innerHTML = 'Copied!';                 setTimeout(() => {                    this.editorCopyBtn.innerHTML = '\x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2"><' + '/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"><' + '/path><' + '/svg> Copy to CMS';                 }, 2000);              } catch (err) {                 console.warn('Fallback: Oops, unable to copy', err);                 alert('Fallback: Failed to copy deals to clipboard.');              }              document.body.removeChild(textArea);           }        }      }      // Initialize the Widget      if (document.readyState === 'loading') {        document.addEventListener('DOMContentLoaded', () => new DealsFinderWidget({ rootId: 'signal-deals-finder-root', rootNode: shadowRoot, hostContainer: hostContainer }));      } else {        new DealsFinderWidget({ rootId: 'signal-deals-finder-root', rootNode: shadowRoot, hostContainer: hostContainer });      }    })();  </script></div> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/t-mobile-has-the-best-iphone-18-pro-freebie-deals-heres-how-to-get-one</link>
                                                                            <description>
                            <![CDATA[ T-Mobile is offering the iPhone 18 Pro and iPhone 18 Pro Max for free with select unlimited data plans. Here's how to get yours and avoid paying the new higher price tag. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">n3MbdGGCc5yHCpQg9NHnSP</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/Uvr7LfkURByTozP6jQPBaM-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 21 Sep 2026 21:36:23 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ louis.ramirez@futurenet.com (Louis Ramirez) ]]></author>                    <dc:creator><![CDATA[ Louis Ramirez ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oYF2xVwCb4pTGhAJi8Yqr5-320-70.jpeg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;As deals editor-in-chief at Tom’s Guide, Louis refuses to pay full price for anything. He has over 10 years of experience finding the best deals and coupons to bring readers. Louis price checks against multiple retailers and searches high and low for sales on 4K TVs, Apple devices, streaming services, mattresses, kitchen appliances, and more. He&#039;s also always looking for the the best coupon codes to turn good deals into stellar buys.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;He has covered major retail events like Amazon Prime Day, Black Friday, and Cyber Monday for more than a decade and knows how to spot an epic deal from a fake discount. He&#039;s also great at helping people negotiate better prices on everything from gym memberships to their home internet service. Louis&#039; work has also helped readers find PS5 restock, baby formula, Clorox wipes, and everything in between. For his next major purchase, Louis is hoping to find a killer deal on an M3-based Mac. &lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;A born-and-bred New Yorker, Louis is always in search of the perfect cup of coffee. On his free time, he enjoys swimming, running, and any workout that pushes his Apple Watch to the max. He&#039;s also a big fan of international films, horror movies, and K-dramas. His work has appeared on Gizmodo, CNET, Digital Trends, Dealnews, and Time Out New York.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/Uvr7LfkURByTozP6jQPBaM-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 18 Pro and iPhone 18 Pro Max side by side]]></media:description>                                                            <media:text><![CDATA[iPhone 18 Pro and iPhone 18 Pro Max side by side]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 18 Pro and iPhone 18 Pro Max side by side]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/Uvr7LfkURByTozP6jQPBaM-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Apple's new iPhones are officially on sale and there are dozens of <a href="https://www.tomsguide.com/phones/iphones/best-iphone-18-pro-and-pro-max-deals">iPhone 18 Pro deals</a> to choose from. However, my favorite freebie deals come from T-Mobile. </p><p>Right now, <a href="https://tmobilepostpaid.pxf.io/c/1943169/4032247/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow">T-Mobile is offering the iPhone 18 Pro for free</a> when you bring your number and open an Experience Beyond plan. Or you can get it for free with trade-in and an Experience Beyond plan. Meanwhile, <a href="https://tmobilepostpaid.pxf.io/c/1943169/4032248/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow">T-Mobile is also taking up to $1,200 off the iPhone 18 Pro Max</a> with trade-in and Experience Beyond plan. Here's how you can get yours. </p><h3 class="article-body__section" id="section-quick-links"><span>Quick Links</span></h3><ul><li><strong>iPhone 18 Pro: </strong><a href="https://tmobilepostpaid.pxf.io/c/1943169/4032247/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow"><strong>free w/ new line + unlimited </strong></a><strong></strong></li><li><strong>iPhone 18 Pro Max: </strong><a href="https://tmobilepostpaid.pxf.io/c/1943169/4032248/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow"><strong>up to $1,200 off w/ unlimited</strong></a><strong></strong></li></ul><h3 class="article-body__section" id="section-iphone-18-pro"><span>iPhone 18 Pro</span></h3><div class="product"><a data-dimension112="7875e560-b604-11f1-ac18-09499ce3e148" data-action="Deal Block" data-label="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" href="https://tmobilepostpaid.pxf.io/c/1943169/4032247/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:50.00%;"><img id="Y26QJd7Ff7aeQmTHuW8nCP" name="NEW T-Mobile Logo" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Y26QJd7Ff7aeQmTHuW8nCP-1920-80.png" mos="" align="middle" fullscreen="" width="600" height="300" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro: </strong><a href="https://tmobilepostpaid.pxf.io/c/1943169/4032247/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow" data-dimension112="7875e560-b604-11f1-ac18-09499ce3e148" data-action="Deal Block" data-label="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension25=""><strong>free w/ trade-in + unlimited @ T-Mobile</strong></a><br>T-Mobile is offering the iPhone 18 Pro for free when you switch and bring your number or when you trade-in an eligible phone and sign up for T-Mobile's Experience Beyond plan. The iPhone 18 Pro features a 6.3-inch OLED 120Hz display (2622 x 1206), A20 Pro chipset, and 256GB of storage. You also get a 48MP main, 48MP ultrawide, and 48MP telephoto lens w/ 4x zoom. The front camera is 18MP. <a class="view-deal button" href="https://tmobilepostpaid.pxf.io/c/1943169/4032247/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow" data-dimension112="7875e560-b604-11f1-ac18-09499ce3e148" data-action="Deal Block" data-label="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension25="">View Deal</a></p></div><h3 class="article-body__section" id="section-iphone-18-pro-max"><span>iPhone 18 Pro Max</span></h3><div class="product"><a data-dimension112="7875e6be-b604-11f1-87af-3f845dce4e6c" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" href="https://tmobilepostpaid.pxf.io/c/1943169/4032248/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:50.00%;"><img id="Y26QJd7Ff7aeQmTHuW8nCP" name="NEW T-Mobile Logo" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Y26QJd7Ff7aeQmTHuW8nCP-1920-80.png" mos="" align="middle" fullscreen="" width="600" height="300" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro Max: </strong><a href="https://tmobilepostpaid.pxf.io/c/1943169/4032248/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow" data-dimension112="7875e6be-b604-11f1-87af-3f845dce4e6c" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension25=""><strong>up to $1,200 off w/ trade-in + unlimited @ T-Mobile</strong></a><br>T-Mobile is taking up to $1,200 off the iPhone 18 Pro Max when you trade-in an old device and sign up for an eligible unlimited data plan. The iPhone 18 Pro Max features a 6.9-inch OLED 120Hz display (2868 x 1320), A20 Pro chipset, and 256GB of storage. You also get a 48MP main, 48MP ultrawide, and 48MP telephoto lens w/ 4x zoom. The front camera is 18MP.<a class="view-deal button" href="https://tmobilepostpaid.pxf.io/c/1943169/4032248/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow" data-dimension112="7875e6be-b604-11f1-87af-3f845dce4e6c" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension25="">View Deal</a></p></div><h3 class="article-body__section" id="section-what-s-new"><span>What's new</span></h3><p>The 6.3-inch <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro</a> and 6.9-inch <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max</a> cost $1,199 and $1,299, respectively. Yes, that's $100 pricier than their predecessors, which is why T-Mobile's deals are so great. The carrier is offering various ways to save on your new iPhone. </p><p>As for the phones, they generally stick to Apple's familiar playbook. They feature rigid enclosures, proven water resistance, and toughened glass surfaces that have repeatedly demonstrated they can take real-world abuse. Both phones offer rock solid reliability, so which phone you get depends on how big of a screen you want and how much battery life you require. </p><p>The former packs a 6.3-inch OLED display, whereas the iPhone 18 Pro Max sports a larger 6.9-inch OLED screen. No matter which phone you get, you'll be in for a treat as they are Apple's flagship Pro devices. Stay tuned to Tom's Guide for all of the best Apple deals. </p><h3 class="article-body__section" id="section-shop-more-deals"><span>Shop more deals</span></h3><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?search=Everything&rows=8&view_mode=savings_squad&widget_title=Top+Deals+Handpicked+by+Our+Editors&widget_subtitle=Discover+the+best+discounts+currently+available%2C+curated+daily+by+the+Tom%27s+Guide+Savings+Squad.&bg_color=transparent" data-vizualizer-embed="true"></div>    <script>    /**     * Tom's Guide Deals Finder - Vanilla JS Encapsulated Engine     */    (function() {      // --- Freyr Analytics Adapter ---      function initAnalytics() {        window.dataLayer = window.dataLayer || [];        window.googletag = window.googletag || {};        window.googletag.cmd = window.googletag.cmd || [];        window.hawk = window.hawk || { analytics: { freyr: [] } };        window.hawk.analytics = window.hawk.analytics || { freyr: [] };        window.hawk.analytics.freyr = window.hawk.analytics.freyr || [];        window.freyr = window.freyr || { cmd: [] };        const scriptSrc = 'https://freyr.futurecdn.net/freyr.js';        const hostname = typeof window !== 'undefined' ? window.location.hostname : '';        const isTestEnv = typeof window.navigator !== 'undefined' && (window.navigator.webdriver || window.navigator.userAgent.includes('Headless'));        const shouldSendRealAnalytics = !isTestEnv && hostname && hostname !== 'localhost' && hostname !== '127.0.0.1' && !hostname.includes('run.app');        if (shouldSendRealAnalytics && !document.querySelector(`script[src="${scriptSrc}"]`)) {          const script = document.createElement('script');          script.src = scriptSrc;          script.async = true;          document.head.appendChild(script);        }      }      function storeEventForDebug(name, data) {        if (!window.hawk || !window.hawk.analytics || !window.hawk.analytics.freyr) return;        window.hawk.analytics.freyr.push({ name, data });        try {          if (typeof window !== 'undefined' && window.localStorage) {            window.localStorage.setItem("hawk", JSON.stringify(window.hawk));          }        } catch (e) {          // Ignore storage issues        }        try {          window.dispatchEvent(new CustomEvent("hawk-analytics-update"));        } catch (e) {}      }      function sendToFreyr(eventName, data) {        if (typeof window === 'undefined') return;        window.freyr = window.freyr || { cmd: [] };        window.freyr.cmd.push(() => {          if (window.freyr && window.freyr.pushAndUpdate) {            window.freyr.pushAndUpdate(eventName, data);          }        });      }      function sendEvent(event, skip = false) {        try {          storeEventForDebug(event.name, event.data);          if (!skip) {            sendToFreyr(event.name, event.data);          }        } catch (e) {          // Ensure tracking errors don't surface to the user        }      }      function getCookie(name) {        try {          const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));          return match ? match[2] : null;        } catch (e) {          return null;        }      }      function getTimeAgo(dateString) {        if (!dateString) return '';        const date = new Date(dateString);        const now = new Date();        const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);        if (diffInSeconds < 60) return 'Just now';        const diffInMinutes = Math.floor(diffInSeconds / 60);        if (diffInMinutes < 60) return `${diffInMinutes} min${diffInMinutes > 1 ? 's' : ''} ago`;        const diffInHours = Math.floor(diffInMinutes / 60);        if (diffInHours < 24) return `${diffInHours} hr${diffInHours > 1 ? 's' : ''} ago`;        const diffInDays = Math.floor(diffInHours / 24);        if (diffInDays < 30) return `${diffInDays} day${diffInDays > 1 ? 's' : ''} ago`;        const diffInMonths = Math.floor(diffInDays / 30);        if (diffInMonths < 12) return `${diffInMonths} mo${diffInMonths > 1 ? 's' : ''} ago`;        const diffInYears = Math.floor(diffInDays / 365);        return `${diffInYears} yr${diffInYears > 1 ? 's' : ''} ago`;      }      function normalizeCurrency(symbol) {        const map = {          '£': 'GBP',          '$': 'USD',          'A$': 'AUD',          'CA$': 'CAD',          '€': 'EUR'        };        return map[symbol] || symbol;      }      function trackElementInteraction(props) {        sendEvent({          name: 'elementInteraction',          data: {            element: {              action: props.action || "click",              id: props.id || undefined,              class: props.class || undefined,              name: props.name || undefined,              text: props.text || undefined,              label: props.label || undefined,              container: props.container || undefined,              url: props.url || undefined,              articleId: props.articleId || undefined            }          }        });      }      function generateRevenueId(url, productName, merchantName, modelId) {        const str = `${window.location.href}|${productName}|${merchantName}|${modelId || ''}|${new Date().toDateString()}|tomsguide`;        let hash = 0;        for (let i = 0; i < str.length; i++) {          const char = str.charCodeAt(i);          hash = ((hash << 5) - hash) + char;          hash = hash & hash;        }        let numericStr = Math.abs(hash).toString();        while (numericStr.length < 19) {          numericStr += Math.floor(Math.random() * 10).toString();        }        return numericStr.substring(0, 19);      }      function rewriteAffiliateLink(url, territory, revenueId) {        if (!url) return url;        const t = (territory || 'gb').toLowerCase();        return url.replace(/hawk-custom-tracking/g, `tomsguide-${t}-${revenueId}`);      }      function trackHawkEvent(params) {        const { clickType, widgetId, productCategoryName, product, productsArray, zeroBasedProductIndexOrNull, totalDealsOrProducts, areaClicked, merchant, revenueId, isoCurrencyCode, queryName, widgetTypeName } = params;        const data = {          event: "hawkEvent",          category: "Affiliates",          affiliate: {            action: {              type: clickType,              id: widgetId,              event: clickType === "appeared" ? "viewed" : "Click from",              timestamp: Date.now()            },            component: {              flag: "Editor",              product: productCategoryName || "deals",              category: `Signal Deal Finder ${widgetTypeName || "Carousel"} widget`,              type: clickType === "appeared" ? "review" : "signal product",              label: queryName || (product ? (product.name || "") : ""),              index: zeroBasedProductIndexOrNull === null || zeroBasedProductIndexOrNull === undefined ? -1 : zeroBasedProductIndexOrNull,              linkCount: totalDealsOrProducts || 0,              blockLayout: "",              areaClicked: areaClicked || ""            }          },          products: productsArray || (product && merchant ? [            {              product: {                primary: {                  id: product.id || product.matchId || null,                  name: product.name,                  type: "deal",                  price: product.price,                  previousPrice: product.previousPrice || null,                  currency: isoCurrencyCode || "USD",                  preorder: false,                  labels: [],                  link: product.link,                  originalLink: product.originalLink || null,                  revenueId: revenueId || null,                  startTime: null,                  endTime: null,                  voucherCode: null,                  voucherAudience: null,                  voucherPercentageSaving: null,                  voucherMoneySaving: null,                  voucherType: null,                  offerExclusive: false,                  offerScope: null,                  globalId: product.globalId || null,                  inStock: product.inStock !== false,                  contractProvider: null,                  contractMinutes: null,                  contractTexts: null,                  contractData: null,                  contractLength: null,                  contractMonthlyPrice: null,                  contractCurrency: isoCurrencyCode || "USD"                }              },              merchant: {                id: merchant.id || null,                name: merchant.name,                url: merchant.url || null,                network: merchant.network || null              },              model: {                id: product.modelId || null,                brand: product.brand || null,                name: product.name,                parent: product.parent || null              }            }          ] : []),          reviews: [],          _clear: true,          "gtm.uniqueEventId": Date.now() % 10000        };        sendEvent({ name: 'hawkEvent', data });      }      function trackDealClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Product Card" });      }      function trackViewSimilarClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Product Card View Similar" });      }      function trackPriceComparisonClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Price Comparison" });      }      function trackReviewClick(params) {        trackHawkEvent({ ...params, clickType: "review", areaClicked: "Signal Product Card Review Link" });      }      function trackShare(params) {        trackHawkEvent({ ...params, clickType: "share", areaClicked: "Signal Product Card Share" });      }      function trackDealsAppeared(widgetId, deals, revenueId, currency, queryName, widgetTypeName) {         if (!deals || deals.length === 0) return;                  const productsArray = deals.slice(0, 50).map((deal) => {            let voucherPct = null;            let rawPrice = parseFloat(deal.rawPrice) || parseFloat(deal.price) || null;            let rawMsrp = parseFloat(deal.rawMsrp) || parseFloat(deal.msrp) || null;            if (rawMsrp > rawPrice && rawPrice > 0) {              voucherPct = Math.round((1 - (rawPrice / rawMsrp)) * 100);            }            let numId = null;            if (deal.externalProductId && !isNaN(parseInt(deal.externalProductId))) {              numId = parseInt(deal.externalProductId);            } else if (deal.id && !isNaN(parseInt(deal.id))) {              numId = parseInt(deal.id);            } else {              numId = deal.matchId || null;            }            return {              product: {                primary: {                  id: numId,                  name: deal.productName || deal.title || "",                  type: "deal",                  price: rawPrice,                  previousPrice: rawMsrp,                  currency: currency || 'USD',                  preorder: false,                  labels: deal.modelBrand || deal.brand ? [                     { type: "brand", value: deal.modelBrand || deal.brand }                  ] : [],                  link: deal.url,                  originalLink: deal.url,                  revenueId: revenueId || null,                  startTime: null,                  endTime: null,                  voucherCode: null,                  voucherAudience: null,                  voucherPercentageSaving: voucherPct,                  voucherMoneySaving: null,                  voucherType: null,                  offerExclusive: false,                  offerScope: null,                  globalId: deal.productKey || null,                  inStock: deal.inStock !== false,                  contractProvider: null,                  contractMinutes: null,                  contractTexts: null,                  contractData: null,                  contractLength: null,                  contractMonthlyPrice: null,                  contractCurrency: currency || 'USD'                }              },              merchant: {                id: deal.merchantId ? parseInt(deal.merchantId) : null,                name: deal.merchant || "Retailer",                url: deal.merchantUrl || null,                network: deal.merchantNetwork || null              },              model: {                id: deal.modelId ? parseInt(deal.modelId) : null,                brand: deal.modelBrand || deal.brand || null,                name: deal.productName || deal.title || "",                parent: deal.modelParent || null              }            };         });                  trackHawkEvent({             clickType: "appeared",             widgetId: widgetId,             productCategoryName: "deals",             zeroBasedProductIndexOrNull: null,             totalDealsOrProducts: deals.length,             productsArray: productsArray,             queryName: queryName,             widgetTypeName: widgetTypeName         });      }      // 1. Setup Shadow DOM Sandbox      const currentScript = document.currentScript;      let hostContainer = null;      let template = null;            if (currentScript) {        let prev = currentScript.previousElementSibling;        while (prev) {          if (prev.tagName === 'TEMPLATE' && prev.classList.contains('tg-df-widget-template')) {            template = prev;          } else if (prev.tagName === 'DIV' && prev.classList.contains('tg-df-widget-host') && !prev.hasAttribute('data-initialized')) {            hostContainer = prev;            break;          }          prev = prev.previousElementSibling;        }      }            // Fallbacks in case script is deferred      if (!hostContainer) {        const hosts = document.querySelectorAll('.tg-df-widget-host:not([data-initialized])');        if (hosts.length > 0) hostContainer = hosts[0];      }            // Safely embedded template for CMS environments      const rawTemplate = `  \x3Cstyle>    /* --- Shadow DOM Base Reset --- */    *, *::before, *::after {      box-sizing: border-box;    }    img, picture, svg, video {      max-width: 100%;      height: auto;      display: block;    }    /*       1. Scoped CSS for Tom's Guide Deals Widget       All classes are prefixed with \`tg-df-\` to prevent CMS style leakage.    */    .tg-df-container {      container-type: inline-size;      container-name: tg-df;      --tg-df-blue: #1F69FF;      --tg-df-blue-hover: #004d8c;      --tg-df-text: #222222;      --tg-df-text-muted: #555555;      --tg-df-bg: #ffffff;      --tg-df-bg-secondary: #f4f4f4;      --tg-df-border: #e2e8f0;      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;      color: var(--tg-df-text);      background-color: transparent;       width: 100%;      max-width: 1200px;      margin: 0 auto;      padding-bottom: 24px;    }    .tg-df-container *, .tg-df-container *::before, .tg-df-container *::after {      margin: 0;      padding: 0;      box-sizing: border-box;    }    .tg-df-container img {      border: none;      margin: 0;      padding: 0;    }    .tg-df-container a {      text-decoration: none;      color: inherit;    }    /*       2. Search & Filter Bar    */    .tg-df-controls {      display: flex;      flex-direction: column;      align-items: center;      gap: 20px;      margin-bottom: 32px;      width: 100%;      position: relative;      z-index: 20;    }    .tg-df-top-bar {      display: flex;      width: 100%;      max-width: 760px;      gap: 12px;      margin: 0 auto;      align-items: center;    }    .tg-df-search-wrapper {      position: relative;      flex: 1;      width: 100%;      box-shadow: 0 8px 24px rgba(0,0,0,0.06);      border-radius: 40px;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      z-index: 100;    }    .tg-df-autocomplete-dropdown {      position: absolute;      top: calc(100% + 4px);      left: 0;      right: 0;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 12px;      box-shadow: 0 8px 32px rgba(0,0,0,0.12);      max-height: 300px;      overflow-y: auto;      z-index: 200;      display: none;    }    .tg-df-autocomplete-dropdown.active {      display: block;    }    .tg-df-autocomplete-item {      padding: 12px 24px;      cursor: pointer;      font-size: 14px;      color: var(--tg-df-text);      transition: background 0.1s ease;    }    .tg-df-autocomplete-item:hover {      background: var(--tg-df-bg-secondary);    }    .tg-df-search-input {      width: 100%;      padding: 16px 64px 16px 24px;      font-size: 16px;      border: 2px solid transparent;      border-radius: 40px;      outline: none;      transition: border-color 0.2s ease, box-shadow 0.2s ease;      color: var(--tg-df-text);      background: transparent;    }    .tg-df-search-input:focus {      border-color: transparent;      box-shadow: 0 0 0 3px rgba(0, 108, 196, 0.15);    }    .tg-df-search-input::placeholder {      color: #999999;    }        .tg-df-search-btn {      position: absolute;      right: 8px;      top: 50%;      transform: translateY(-50%);      width: 40px;      height: 40px;      border-radius: 50%;      background: #222;      border: none;      display: flex;      align-items: center;      justify-content: center;      cursor: pointer;      transition: background 0.2s ease;    }        .tg-df-search-btn:hover {      background: #000;    }    .tg-df-search-icon {      width: 16px;      height: 16px;      fill: #fff;    }    .tg-df-settings-wrapper {      position: relative;    }        .tg-df-settings-btn {      width: 48px;      height: 48px;      border-radius: 50%;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      box-shadow: 0 4px 12px rgba(0,0,0,0.04);      display: flex;      align-items: center;      justify-content: center;      cursor: pointer;      transition: all 0.2s ease;      color: var(--tg-df-text-muted);      flex-shrink: 0;    }    .tg-df-settings-btn:hover {      background: var(--tg-df-bg-secondary);      border-color: #0000ff;      color: var(--tg-df-text);    }    .tg-df-settings-btn svg {      width: 24px;      height: 24px;      fill: currentColor;    }    .tg-df-settings-dropdown {      position: absolute;      top: calc(100% + 8px);      right: 0;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 12px;      box-shadow: 0 8px 32px rgba(0,0,0,0.12);      width: 280px;      padding: 20px;      display: none;      z-index: 100;      flex-direction: column;      gap: 20px;    }    .tg-df-settings-dropdown.active {      display: flex;    }        .tg-df-settings-dropdown-backdrop {      display: none;      position: fixed;      inset: 0;      z-index: 99;    }        .tg-df-settings-dropdown-backdrop.active {      display: block;    }    .tg-df-setting-item {      display: flex;      flex-direction: column;      gap: 10px;    }    .tg-df-setting-label {      font-size: 11px;      font-weight: 700;      color: var(--tg-df-text-muted);      text-transform: uppercase;      letter-spacing: 0.5px;    }        .tg-df-region-select {        padding: 10px 12px;        border-radius: 8px;        border: 1px solid var(--tg-df-border);        font-size: 15px;        outline: none;        background: var(--tg-df-bg-secondary);        color: var(--tg-df-text);        cursor: pointer;        width: 100%;    }    .tg-df-toggle {        position: relative;        display: inline-block;        width: 44px;        height: 24px;        flex-shrink: 0;    }    .tg-df-toggle input {        opacity: 0;        width: 0;        height: 0;    }    .tg-df-slider {        position: absolute;        cursor: pointer;        top: 0; left: 0; right: 0; bottom: 0;        background-color: #ccc;        transition: .2s;        border-radius: 24px;    }    .tg-df-slider:before {        position: absolute;        content: "";        height: 18px;        width: 18px;        left: 3px;        bottom: 3px;        background-color: white;        transition: .2s;        border-radius: 50%;    }    .tg-df-toggle input:checked + .tg-df-slider {        background-color: #1F69FF;    }    .tg-df-toggle input:checked + .tg-df-slider:before {        transform: translateX(20px);    }    .tg-df-dl-row {        flex-direction: row;        align-items: center;        justify-content: space-between;    }    .tg-df-dl-row-text {        font-size: 14px;        font-weight: 600;        color: var(--tg-df-text);    }    .tg-df-dl-row-subtext {        font-size: 12px;        font-weight: 400;        line-height: 1.3;        color: var(--tg-df-text-muted);        margin-top: 4px;        display: block;    }    .tg-df-filters-container {      position: relative;      width: 100%;      max-width: 800px;    }    .tg-df-scroll-btn {      display: none;      position: absolute;      top: 50%;      transform: translateY(-50%);      width: 32px;      height: 32px;      background: white;      border: 1px solid var(--tg-df-border);      border-radius: 50%;      align-items: center;      justify-content: center;      cursor: pointer;      z-index: 10;      box-shadow: 0 2px 8px rgba(0,0,0,0.1);      color: var(--tg-df-text-primary);      padding: 0;    }    .tg-df-scroll-btn svg {      width: 16px;      height: 16px;    }    .tg-df-scroll-btn:hover {      background: #f4f4f4;    }    .tg-df-scroll-btn.left {      left: 0px;    }    .tg-df-scroll-btn.right {      right: 0px;    }    @container tg-df (max-width: 768px) {      .tg-df-scroll-btn {        display: flex;        top: 22px; /* vertically center within the 44px high filter buttons */      }    }    .tg-df-filters {      display: grid;      width: 100%;      grid-template-columns: repeat(4, 1fr);      gap: 12px;      margin: 0 auto;      max-width: 800px;    }                 .tg-df-sort-wrapper {      position: relative;      display: flex;      align-items: center;      width: 100%;    }        .tg-df-sort-icon {      position: absolute;      left: 14px;      width: 14px;      height: 14px;      fill: var(--tg-df-text-muted);      pointer-events: none;    }    .tg-df-sort-select, .tg-df-filter-select {      width: 100%;      padding: 10px 36px 10px 38px;      font-size: 14px;      border: 1px solid var(--tg-df-border);      border-radius: 100px;      outline: none;      appearance: none;      background-color: var(--tg-df-bg-secondary);      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12'%3E%3Cpath fill='%23555555' d='M6 8L1 3h10z'/%3E%3C/svg%3E");      background-repeat: no-repeat;      background-position: right 14px center;      color: var(--tg-df-text);      cursor: pointer;      font-weight: 500;      transition: all 0.2s ease;    }        .tg-df-price-input::-webkit-outer-spin-button,    .tg-df-price-input::-webkit-inner-spin-button {      -webkit-appearance: none;      margin: 0;    }    .tg-df-price-input {      -moz-appearance: textfield;    }    .tg-df-sort-select:hover, .tg-df-filter-select:hover {      background-color: #e2e8f0;    }    .tg-df-multiselect-container {      position: relative;    }    @container tg-df (max-width: 768px) {      .tg-df-filters-container {      position: relative;      width: 100%;      max-width: 800px;    }    .tg-df-scroll-btn {      display: none;      position: absolute;      top: 50%;      transform: translateY(-50%);      width: 32px;      height: 32px;      background: white;      border: 1px solid var(--tg-df-border);      border-radius: 50%;      align-items: center;      justify-content: center;      cursor: pointer;      z-index: 10;      box-shadow: 0 2px 8px rgba(0,0,0,0.1);      color: var(--tg-df-text-primary);      padding: 0;    }    .tg-df-scroll-btn svg {      width: 16px;      height: 16px;    }    .tg-df-scroll-btn:hover {      background: #f4f4f4;    }    .tg-df-scroll-btn.left {      left: 0px;    }    .tg-df-scroll-btn.right {      right: 0px;    }    @container tg-df (max-width: 768px) {      .tg-df-scroll-btn {        display: flex;        top: 22px; /* vertically center within the 44px high filter buttons */      }    }    .tg-df-filters {        width: 100%;        margin: 0;        margin-bottom: -320px;        padding: 0 16px 320px 16px;        display: flex;        flex-wrap: nowrap;        gap: 8px;        overflow-x: auto;        overflow-y: hidden;        pointer-events: none;        scrollbar-width: none;        -webkit-overflow-scrolling: touch;      }      .tg-df-filters::-webkit-scrollbar {        display: none;      }      .tg-df-sort-wrapper {        pointer-events: auto;        flex: 0 0 auto;        width: 175px;        min-width: 175px;      }    }        .tg-df-multiselect-trigger {      display: block;      background: #fff;      user-select: none;      width: 100%;      overflow: hidden;      white-space: nowrap;      text-overflow: ellipsis;    }        .tg-df-multiselect-dropdown {      display: none;      position: absolute;      top: calc(100% + 4px);      left: 0;      width: 100%;      min-width: 220px;      max-height: 300px;      overflow-y: auto;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 8px;      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);      z-index: 100;      padding: 8px 0;    }    .tg-df-multiselect-dropdown.active {      display: block;    }    .tg-df-ms-option {      padding: 8px 16px;      display: flex;      align-items: center;      gap: 8px;      cursor: pointer;      font-size: 14px;    }    .tg-df-ms-option:hover {      background-color: var(--tg-df-bg-secondary);    }        .tg-df-ms-option input {      cursor: pointer;      accent-color: #1f69ff;    }    .tg-df-sort-select:focus, .tg-df-filter-select:focus {      border-color: #0000ff;      box-shadow: 0 0 0 3px rgba(0, 0, 255, 0.2);      background-color: var(--tg-df-bg);    }    /*       3. Deal Grid Layout    */    .tg-df-grid.tg-df-grid-auto {      padding-top: 24px;    }    .tg-df-grid, .tg-df-grid.layout-grid {      display: grid;      grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));      gap: 10px;    }    .tg-df-grid.layout-row {      grid-template-columns: 1fr;      gap: 16px;    }        .tg-df-grid.layout-row .tg-df-card {      flex-direction: row;      align-items: stretch;      height: auto;      box-shadow: none;      border-bottom: 1px solid var(--tg-df-border);    }    .tg-df-grid.layout-row .tg-df-card:hover {      box-shadow: none;    }    .tg-df-grid.layout-row .tg-df-card-image-box {      width: 140px;      min-width: 140px;      aspect-ratio: 3/4;      border-right: none;      padding: 16px 16px 16px 32px;    }    .tg-df-grid.layout-row .tg-df-card-body {      padding: 16px;      justify-content: space-between;    }    .tg-df-grid.layout-row .tg-df-card-title {      font-size: 15px;      margin-bottom: 16px;    }    .tg-df-grid.layout-row .tg-df-card-stars { margin-bottom: 8px; }    .tg-df-grid.layout-row .tg-df-card-footer {      flex-direction: column;      align-items: flex-start;      gap: 0;    }    .tg-df-grid.layout-row .tg-df-card-merchant-pill {      margin-bottom: 4px;    }    .tg-df-grid.layout-row .tg-df-card-price-group {      margin-bottom: 8px;    }    .tg-df-grid.layout-row .tg-df-price-group {      width: auto;    }    .tg-df-grid.layout-row .tg-df-card-cta {      width: 100%;      max-width: 200px;      padding: 10px 24px;      font-size: 13px;      flex-shrink: 0;      text-align: center;      justify-content: center;    }    /*       4. Deal Card Design    */    .tg-df-card {      position: relative;      display: flex;      flex-direction: column;      background-color: #ffffff;      border-radius: 0;      overflow: hidden;      transition: transform 0.2s ease, box-shadow 0.2s ease;      text-decoration: none;      color: inherit;      height: 100%;      box-shadow: 0 0 16px rgba(0, 0, 0, 0.08);      border: 1px solid var(--tg-df-border);    }    .tg-df-card:hover {      box-shadow: 0 0 24px rgba(0, 0, 0, 0.12);    }    .tg-df-card-image-box {      width: 100%;      aspect-ratio: 3/4;      background-color: #f8f8f8;      display: flex;      align-items: center;      justify-content: center;      position: relative;      overflow: hidden;      padding: 32px;      flex: 0 0 auto;    }    .tg-df-card-image {      max-width: 100%;      max-height: 100%;      width: auto;      height: auto;      object-fit: contain;      mix-blend-mode: multiply; /* Helps white background images blend into secondary bg */      transition: transform 0.3s ease;    }    .tg-df-card:hover .tg-df-card-image {      transform: scale(1.05); /* Zoom in on hover */    }    .tg-df-card-discount-badge {      position: absolute;      top: 12px;      left: 12px;      background: #dc2626; /* Red */      color: #ffffff;      padding: 6px 8px;      font-size: 11px;      font-weight: 500;      text-transform: uppercase;      letter-spacing: 0.5px;      border-radius: 0;      z-index: 10;    }        .tg-df-card-merchant-pill {      display: block;      padding: 0;      font-size: 11px;      font-weight: 600;      text-transform: uppercase;      letter-spacing: 0.5px;      border-radius: 0;      color: var(--tg-df-text-muted);      margin-bottom: 8px;      white-space: nowrap;      overflow: hidden;      text-overflow: ellipsis;    }    .tg-df-card-body {      padding: 16px;      display: flex;      flex-direction: column;      flex-grow: 1;      min-width: 0;    }    .tg-df-card-badges {      display: flex;      flex-wrap: wrap;      gap: 6px;      margin-bottom: 8px;    }    .tg-df-tag {      display: inline-flex;      align-items: center;      padding: 4px 6px;      font-size: 11px;      font-weight: 700;      text-transform: uppercase;      border-radius: 4px;      gap: 4px;    }    .tg-df-tag-prime {      background-color: #00A8E1;      color: #fff;    }    .tg-df-tag-coupons {      background-color: #f1f5f9;      color: #334155;      border: 1px solid #cbd5e1;      cursor: pointer;      transition: background-color 0.2s;    }    .tg-df-tag-coupons:hover {      background-color: #e2e8f0;    }        .tg-df-tag-outline {      background-color: #f1f5f9;      color: #334155;      border: 1px solid #cbd5e1;      cursor: pointer;      transition: background-color 0.2s;    }    .tg-df-tag-outline:hover {      background-color: #e2e8f0;    }        @keyframes tg-df-spin {      0% { transform: rotate(0deg); }      100% { transform: rotate(360deg); }    }    .tg-df-coupon-spinner {      border: 2px solid #e2e8f0;      border-top: 2px solid #3b82f6;      border-radius: 50%;      width: 14px;      height: 14px;      animation: tg-df-spin 1s linear infinite;      margin: 4px 8px;      display: inline-block;    }        /* Vouchers Modal */    .tg-df-modal-backdrop {      position: fixed;      top: 0; left: 0; right: 0; bottom: 0;      background: rgba(0,0,0,0.5);      z-index: 10000;      display: flex;      align-items: center;      justify-content: center;      opacity: 0;      pointer-events: none;      transition: opacity 0.3s;    }    .tg-df-modal-backdrop.active {      opacity: 1;      pointer-events: auto;    }    .tg-df-modal {      background: #fff;      border-radius: 12px;      width: 90%;      max-width: 400px;      max-height: 80vh;      display: flex;      flex-direction: column;      box-shadow: 0 10px 40px rgba(0,0,0,0.2);      transform: translateY(20px);      transition: transform 0.3s;    }    .tg-df-modal-backdrop.active .tg-df-modal {      transform: translateY(0);    }    .tg-df-modal-header {      padding: 16px;      border-bottom: 1px solid #e2e8f0;      display: flex;      align-items: center;      justify-content: space-between;    }    .tg-df-modal-title {      font-size: 16px;      font-weight: 600;      margin: 0;    }    .tg-df-modal-close {      background: none;      border: none;      cursor: pointer;      padding: 4px;      color: #64748b;    }    .tg-df-modal-body {      padding: 16px;      overflow-y: auto;    }    .tg-df-voucher-item {      padding: 12px;      border: 1px dashed #cbd5e1;      border-radius: 8px;      margin-bottom: 10px;      background: #f8fafc;      display: flex;      align-items: center;      gap: 12px;      text-decoration: none;      color: inherit;      transition: background-color 0.2s, border-color 0.2s;    }    .tg-df-voucher-item:hover {      background: #f1f5f9;      border-color: #94a3b8;    }    .tg-df-voucher-item:last-child {      margin-bottom: 0;    }    .tg-df-voucher-logo {      width: 48px;      height: 48px;      object-fit: contain;      border-radius: 4px;      background: #fff;      border: 1px solid #e2e8f0;      flex-shrink: 0;    }    .tg-df-voucher-content {      flex: 1;      min-width: 0;    }    .tg-df-voucher-title {      font-size: 14px;      font-weight: 600;      margin: 0 0 4px 0;      line-height: 1.3;      color: #0f172a;    }    .tg-df-voucher-expiry {      font-size: 12px;      color: #64748b;      display: flex;      align-items: center;      gap: 4px;      margin-top: 6px;    }    .tg-df-voucher-code {      display: inline-flex;      align-items: center;      background: #f1f5f9;      border: 1px dashed #cbd5e1;      padding: 6px 10px;      font-family: monospace;      font-weight: 700;      font-size: 14px;      color: #0f172a;      border-radius: 4px;      margin-top: 8px;      cursor: pointer;      transition: all 0.2s ease;    }    .tg-df-voucher-code:hover {      background: #e2e8f0;      border-color: #94a3b8;    }    .tg-df-voucher-code.copied {      background: #ecfdf5;      border-color: #10b981;      color: #10b981;    }    .tg-df-voucher-cta {      display: inline-block;      margin-top: 8px;      font-size: 13px;      font-weight: 600;      color: #2563eb;      text-decoration: none;    }    .tg-df-card-title {      font-size: 15px;      font-weight: 400;      line-height: 1.4;      margin: 0 0 12px 0;      color: var(--tg-df-text);    }    .tg-df-card-footer {      margin-top: auto;      display: flex;      flex-direction: column;      width: 100%;    }    .tg-df-card-price-group {      display: flex;      flex-direction: row;      align-items: center;      gap: 8px;      margin-bottom: 12px;    }    .tg-df-card-price {      font-size: 16px;      font-weight: 700;      color: #dc2626; /* Red price */      line-height: 1;    }        .tg-df-card-msrp {      font-size: 13px;      color: var(--tg-df-text-muted);      text-decoration: line-through;    }    .tg-df-container .tg-df-card-cta {      display: flex;      align-items: center;      justify-content: center;      width: 100%;      box-sizing: border-box;      background-color: #1f69ff;      color: #ffffff;      font-size: 12px;      font-weight: 700;      text-transform: uppercase;      letter-spacing: 0.5px;      padding: 12px 16px;      border-radius: 0;      border: none;      cursor: pointer;      transition: background-color 0.2s ease;    }    .tg-df-card:hover .tg-df-card-cta,    .tg-df-card-cta:hover {      background-color: #1555cc;    }    /*       5. State & Skeleton Styles    */    .tg-df-message {      grid-column: 1 / -1;      text-align: center;      padding: 48px 24px;      color: var(--tg-df-text-muted);      font-size: 16px;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 8px;    }    @keyframes tg-df-shimmer {      0% { background-position: -200% 0; }      100% { background-position: 200% 0; }    }    .tg-df-skeleton {      background: linear-gradient(90deg, var(--tg-df-bg-secondary) 25%, #e2e8f0 50%, var(--tg-df-bg-secondary) 75%);      background-size: 200% 100%;      animation: tg-df-shimmer 1.5s infinite;      border-radius: 4px;    }    .tg-df-skeleton-img {      width: 100%;      height: 100%;      position: absolute;      top: 0; left: 0;    }        .tg-df-skeleton-text {      height: 16px;      margin-bottom: 8px;      width: 100%;    }    .tg-df-skeleton-text.short { width: 40%; }    .tg-df-skeleton-text.title { height: 20px; margin-bottom: 16px; }    /* Editor Floating Bar & Elements */    .tg-df-editor-bar {      position: sticky;      top: 120px;      z-index: 1000;      background: #111827;      color: #fff;      padding: 12px 16px;      border-radius: 8px;      margin-bottom: 16px;      display: flex;      align-items: center;      justify-content: space-between;      box-shadow: 0 4px 12px rgba(0,0,0,0.15);    }    .tg-df-editor-bar-text {      font-weight: 600;      font-size: 14px;    }    .tg-df-editor-copy-btn {      background: #10b981;      color: #fff;      padding: 6px 16px;      border: none;      border-radius: 4px;      font-weight: 600;      cursor: pointer;      display: flex;      align-items: center;      font-size: 13px;    }    .tg-df-editor-copy-btn:hover { background: #059669; }        .tg-df-deal-checkbox {      position: absolute;      top: 12px;      right: 12px;      z-index: 10;      width: 20px;      height: 20px;      cursor: pointer;      pointer-events: auto;    }    /*       6. Mobile List View (Stacks into a cleaner horizontal row/list)    */    @container tg-df (max-width: 599px) {      .tg-df-controls {        padding: 16px 16px 8px;      }            .tg-df-top-bar {        width: 100%;      }            .tg-df-settings-dropdown {        position: fixed;        top: auto;        bottom: 0;        left: 0;        right: 0;        width: 100%;        border-radius: 20px 20px 0 0;        padding: 24px;        box-shadow: 0 -8px 32px rgba(0,0,0,0.15);        z-index: 1000;        border: none;        border-top: 1px solid var(--tg-df-border);      }            .tg-df-settings-dropdown-backdrop.active {        background: rgba(0,0,0,0.4);      }            .tg-df-search-wrapper {        box-shadow: 0 0 16px rgba(0,0,0,0.08);      }                  .tg-df-sort-wrapper.tg-df-price-range-wrapper {        flex: 0 0 auto;        min-width: max-content;        width: auto;      }            .tg-df-sort-select, .tg-df-filter-select {        width: 100%;        text-align: left;        padding: 10px 24px 10px 32px;        background-position: right 8px center;        text-overflow: ellipsis;        white-space: nowrap;        overflow: hidden;      }      .tg-df-sort-icon {        left: 10px;      }      .tg-df-grid:not(.layout-grid):not(.layout-row),      .tg-df-grid.layout-row {        grid-template-columns: 1fr;        gap: 16px;      }            .tg-df-grid.tg-df-grid-auto {        padding-top: 24px;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card,      .tg-df-grid.layout-row .tg-df-card {        flex-direction: row;        align-items: stretch;        height: auto;        box-shadow: none; /* simple line on mobile if preferred, or keep */        border-bottom: 1px solid var(--tg-df-border);      }      .tg-df-grid.tg-df-grid-auto .tg-df-card:hover,      .tg-df-grid.layout-row .tg-df-card:hover {        box-shadow: none;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-image-box,      .tg-df-grid.layout-row .tg-df-card-image-box {        width: 120px;        min-width: 120px;        aspect-ratio: 3/4;        border-right: none;        padding: 12px;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-body,      .tg-df-grid.layout-row .tg-df-card-body {        padding: 12px;        justify-content: space-between;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-title,      .tg-df-grid.layout-row .tg-df-card-title {        font-size: 14px;        margin-bottom: 12px;      }      /* Single column mobile grid override */      .tg-df-grid.layout-grid {        grid-template-columns: 1fr;        gap: 16px;      }      .tg-df-grid.layout-grid .tg-df-card-image-box {        padding: 12px;      }      .tg-df-grid.layout-grid .tg-df-card-body {        padding: 10px;      }      .tg-df-grid.layout-grid .tg-df-card-title {        font-size: 13px;        margin-bottom: 8px;      }      .tg-df-grid.layout-grid .tg-df-card-price {        font-size: 14px;      }            .tg-df-card-footer {        flex-direction: column;        align-items: stretch;        gap: 0;        width: 100%;        min-width: 0;      }      .tg-df-card-merchant-pill {        margin-bottom: 4px;      }      .tg-df-card-price-group {        flex: 1 1 auto;        margin-bottom: 8px;      }      .tg-df-card-price {        font-size: 16px;      }      .tg-df-card-msrp {        display: block;       }      .tg-df-grid.layout-row .tg-df-card-cta,      .tg-df-container .tg-df-card-cta {        width: 100%;        max-width: none;        min-width: 0;        box-sizing: border-box;        padding: 8px 16px;        font-size: 12px;        flex: 0 0 auto;        text-align: center;        white-space: normal;        line-height: 1.2;      }    }    .tg-df-container.is-carousel {      min-height: 760px;      background-color: #E7F0FF;      padding: 0 0 24px 0;      border-radius: 24px;      width: 100vw;      max-width: 1200px;      position: relative;      left: 50%;      transform: translateX(-50%);    }    .tg-df-container.is-carousel.hide-header-details {      min-height: 480px;    }    /*       7. Carousel View Mode    */    .tg-df-container .tg-df-carousel-host {      /* Layout is now handled by container wrapper */    }    .tg-df-container .tg-df-carousel-eyebrow {      color: #1F69FF;      font-weight: 700;      font-size: 14px;      text-transform: uppercase;      letter-spacing: 1px;      padding: 24px 16px 0 16px;      display: none;    }    .tg-df-container .tg-df-carousel-query-title {      color: #011535;      font-size: 28px;      font-weight: 600;      padding: 0 16px 24px 16px;      line-height: 1.2;      display: none;    }    .tg-df-container .tg-df-carousel-blue-box {      background-color: transparent;      border-radius: 0;      padding: 24px 24px 0 24px;      margin: 0;      color: #1F69FF;          position: relative;      overflow: hidden;    }    .tg-df-container .tg-df-carousel-bg-circle-1 {      display: none;    }    .tg-df-container .tg-df-carousel-bg-circle-2 {      display: none;    }    .tg-df-container .tg-df-carousel-bg-circle-3 {      display: none;    }    .tg-df-container .tg-df-carousel-box-content {      position: relative;      z-index: 10;    }    .tg-df-container .tg-df-carousel-box-eyebrow {      background-color: transparent;      color: #1F69FF;      font-weight: 700;      font-size: 14px;      text-transform: uppercase;      letter-spacing: 1px;      display: inline-block;      padding: 0;      border-radius: 0;    }    .tg-df-container .tg-df-carousel-box-title {      font-size: 28px;      font-weight: 600;      line-height: 1.2;      margin-top: 8px;      color: #1e293b;    }    .tg-df-container .tg-df-countdown-wrapper {      position: absolute;      top: 0;      right: 0;      display: flex;      flex-direction: column;      align-items: flex-end;      gap: 12px;      transform: scale(0.67);      transform-origin: top right;    }    .tg-df-container .tg-df-countdown-title {      font-size: 14px;      font-weight: 600;      color: #011535;      margin: 0;    }    .tg-df-container .tg-df-countdown-blocks {      display: flex;      gap: 16px;    }    .tg-df-container .tg-df-countdown-item {      display: flex;      flex-direction: column;      align-items: center;      gap: 4px;    }    .tg-df-container .tg-df-countdown-box {      width: 59px;      height: 59px;      background: #03FE9E;      border-radius: 15px;      display: flex;      align-items: center;      justify-content: center;    }    .tg-df-container .tg-df-countdown-num {      font-family: 'Inter', sans-serif;      font-weight: 700;      font-size: 20px;      line-height: normal;      color: #011535;    }    .tg-df-container .tg-df-countdown-label {      font-family: 'Inter', sans-serif;      font-weight: 500;      font-size: 16px;      line-height: normal;      color: #1e293b;      text-transform: uppercase;    }    .tg-df-container .tg-df-carousel-box-subtitle {      font-size: 16px;      margin-top: 8px;      font-weight: 300;      color: #1e293b;      line-height: 24px;    }    .tg-df-container .tg-df-carousel-roundels-wrapper {      position: relative;      margin-top: 24px;      margin-left: -24px;      margin-right: -24px;    }    .tg-df-container .tg-df-carousel-roundels {      display: flex;      gap: 16px;      overflow-x: auto;            scrollbar-width: none;      padding-top: 12px;      padding-bottom: 24px;      padding-left: 24px;      padding-right: 24px;      margin-left: 0;      margin-right: 0;    }        .tg-df-container .tg-df-carousel-scroll-left,    .tg-df-container .tg-df-carousel-scroll-right {      position: absolute;      top: 50%;      transform: translateY(-50%);      height: 36px;      width: 36px;      display: flex;      align-items: center;      justify-content: center;      border-radius: 50%;      background-color: #ffffff;      border: 1px solid #e2e8f0;      box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);      color: #1F69FF;      cursor: pointer;      transition: all 0.2s;      margin-top: -4px;      z-index: 20;    }    .tg-df-container .tg-df-carousel-scroll-left { left: 8px; }    .tg-df-container .tg-df-carousel-scroll-right { right: 8px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-left { left: 0px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-right { right: 0px; }    .tg-df-carousel-filters-outer { margin-left: -24px; margin-right: -24px; padding-left: 24px; padding-right: 24px; }    .tg-df-grid-wrapper { position: relative; }    @container tg-df (max-width: 599px) { .tg-df-carousel-filters-outer { margin-left: -16px; margin-right: -16px; padding-left: 16px; padding-right: 16px; } }        .tg-df-container .tg-df-carousel-scroll-left:hover,    .tg-df-container .tg-df-carousel-scroll-right:hover {      background-color: rgba(255, 255, 255, 0.6);    }    .tg-df-container .tg-df-carousel-roundels::-webkit-scrollbar {      display: none;    }    .tg-df-container .tg-df-roundel {      display: flex;      flex-direction: column;      align-items: center;      gap: 8px;      cursor: pointer;      min-width: 120px;      flex-shrink: 0;    }    .tg-df-container .tg-df-roundel-img-box {      width: 120px;      height: 120px;      border-radius: 50%;      background: white;      display: flex;      align-items: center;      justify-content: center;      overflow: hidden;      box-shadow: 0px 3px 14px 0px rgba(30, 41, 59, 0.08);      transition: box-shadow 0.2s;    }    .tg-df-container .tg-df-roundel:hover .tg-df-roundel-img-box {      box-shadow: 0 0 0 2px #E7F0FF, 0 0 0 4px #1F69FF;    }    .tg-df-container .tg-df-roundel.active .tg-df-roundel-img-box {      box-shadow: 0 0 0 2px #E7F0FF, 0 0 0 4px #1F69FF;    }    .tg-df-container .tg-df-roundel:hover .tg-df-roundel-img-box img {      transform: scale(1.08);    }    .tg-df-container .tg-df-roundel-img-box img {      width: 100%;      height: 100%;      object-fit: contain;      padding: 10px;      box-sizing: border-box;      transition: transform 0.3s ease;    }    .tg-df-container .tg-df-roundel-label {      font-size: 13px;      font-weight: 400;      color: #1e293b;      text-align: center;    }    .tg-df-container .tg-df-carousel-filters-label {      font-size: 16px;      font-weight: 400;      color: #1e293b;      white-space: nowrap;      margin-right: 4px;    }    .tg-df-container .tg-df-carousel-filters-wrap {      display: flex;      align-items: center;      flex-wrap: nowrap;      gap: 8px;      margin-top: 8px;      overflow-x: auto;      scrollbar-width: none;      -webkit-overflow-scrolling: touch;      padding-bottom: 8px;      margin-left: -24px;      margin-right: -24px;      padding-left: 24px;      padding-right: 24px;    }    .tg-df-container .tg-df-carousel-filters-wrap::-webkit-scrollbar {      display: none;    }        .tg-df-container .tg-df-carousel-filter-btn img,    .tg-df-container .tg-df-carousel-filter-btn picture {      height: 20px;      width: 20px;      object-fit: contain;      object-position: center;      display: inline-flex;      align-items: center;      justify-content: center;      margin-right: 6px;    }    .tg-df-container .tg-df-carousel-filter-btn picture img {      margin-right: 0;      height: 100%;      width: 100%;    }    .tg-df-container .tg-df-carousel-filter-btn img.active-img,    .tg-df-container .tg-df-carousel-filter-btn picture:has(.active-img) {      display: none;    }    .tg-df-container .tg-df-carousel-filter-btn:hover img.inactive-img,    .tg-df-container .tg-df-carousel-filter-btn.active img.inactive-img,    .tg-df-container .tg-df-carousel-filter-btn:hover picture:has(.inactive-img),    .tg-df-container .tg-df-carousel-filter-btn.active picture:has(.inactive-img) {      display: none;    }    .tg-df-container .tg-df-carousel-filter-btn:hover img.active-img,    .tg-df-container .tg-df-carousel-filter-btn.active img.active-img,    .tg-df-container .tg-df-carousel-filter-btn:hover picture:has(.active-img),    .tg-df-container .tg-df-carousel-filter-btn.active picture:has(.active-img) {      display: inline-flex;    }    .tg-df-container .tg-df-carousel-filter-btn {      background: #ffffff;      border: 2px solid #1e293b;      color: #1e293b;      border-radius: 24px;      padding: 6px 16px;      font-size: 14px;      font-weight: 600;      cursor: pointer;      transition: all 0.2s;      flex-shrink: 0;      white-space: nowrap;    }    .tg-df-container .tg-df-carousel-filter-btn svg {      margin-right: 6px;    }    .tg-df-container .tg-df-carousel-filter-btn {      display: inline-flex;      align-items: center;    }    .tg-df-container .tg-df-carousel-filter-btn:hover {      background: #1e293b;      color: white;      border-color: #1e293b;    }    .tg-df-container .tg-df-carousel-filter-btn.active {      background: #1e293b;      color: white;      border-color: #1e293b;    }        .tg-df-grid.carousel-compact {      display: flex;      flex-wrap: nowrap;      overflow-x: auto;      gap: 16px;      padding: 16px 24px;      align-items: stretch;      scrollbar-width: none;    }    .tg-df-grid.carousel-compact::-webkit-scrollbar {      display: none;    }    .tg-df-grid.carousel-compact .tg-df-card {      flex: 0 0 auto;      width: 200px;      min-height: auto;      height: auto;      display: flex;      flex-direction: column;      border-radius: 15px;      border: none;      box-shadow: 0 0 16px rgba(0,0,0,0.08);      overflow: visible;    }    .tg-df-grid.carousel-compact .tg-df-card-image-box {      padding: 12px;      background-color: transparent;      border-radius: 15px 15px 0 0;      height: 130px;    }    .tg-df-grid.carousel-compact .tg-df-card-image {      mix-blend-mode: normal;    }    .tg-df-grid.carousel-compact .tg-df-card-discount-badge {      border-radius: 0;      top: 0px;      left: 0px;      padding: 4px 8px;      font-size: 11px;    }    .tg-df-grid.carousel-compact .tg-df-card-body {      padding: 8px 12px 12px 12px;    }    .tg-df-grid.carousel-compact .tg-df-card-title {      font-size: 14px;      font-weight: 400;      margin-bottom: 8px;      color: #011535;    }    .tg-df-grid.carousel-compact .tg-df-card-body:not(:has(.tg-df-card-stars)):not(:has(.tg-df-tag-prime)):not(:has(.tg-df-coupon-wrapper:not([style*="none"]))) > .tg-df-card-title,    .tg-df-grid.carousel-compact .tg-df-card-body:not(:has(.tg-df-card-stars)):has(> .tg-df-card-title:first-child) > .tg-df-card-title {    }    .tg-df-grid.carousel-compact .tg-df-card-cta {      border-radius: 5px;      padding: 8px 10px;      margin-top: 4px;      background-color: #1F69FF;    }    .tg-df-grid.carousel-compact .tg-df-card-price-group {      margin-bottom: 2px;    }    .tg-df-grid.carousel-compact .tg-df-card-merchant-pill {      margin-bottom: 2px;    }    @container tg-df (max-width: 599px) {      .tg-df-container .tg-df-carousel-blue-box-title {        font-size: 24px;      }      .tg-df-container .tg-df-countdown-title {        display: none;      }      .tg-df-container .tg-df-countdown-wrapper {        position: absolute;        top: 0;        right: 0;        align-items: flex-end;        transform: scale(0.40);        transform-origin: top right;      }      .tg-df-container .tg-df-roundel {        min-width: 88px;      }      .tg-df-container .tg-df-roundel-img-box {        width: 88px;        height: 88px;      }    }    /* REPLICA BLOCK STYLES */    .tg-df-grid.layout-replica-2 { grid-template-columns: repeat(2, 1fr) !important; gap: 20px; }    .tg-df-grid.layout-replica-1 { grid-template-columns: 1fr !important; gap: 20px; }        .tg-df-container .hawk-deal-widget-container { border-bottom: 1px solid #e5e7eb; display: flex; flex-direction: column; margin: 0; padding: 20px 0; box-sizing: border-box; font-family: inherit; }    .tg-df-container .hawk-deal-widget-wrap { display: flex; flex-direction: row; align-items: flex-start; width: 100%; gap: 24px; }    .tg-df-container .hawk-deal-widget-image-container { display: flex; flex-shrink: 0; justify-content: center; width: 160px; height: 160px; align-items: center; background: white; margin-bottom: 0px; }    .tg-df-container .hawk-deal-widget-title-product-title { color: #111827; font-size: 18px; font-weight: 700; line-height: 1.4; display: inline; }    .tg-df-container .hawk-deal-widget-title-price { font-size: 18px; font-weight: 700; line-height: 1.4; white-space: nowrap; color: #2563eb; }    .tg-df-container .hawk-deal-widget-title-price-now { font-weight: 700; }    .tg-df-container .hawk-deal-widget-title-retailer-price:hover { text-decoration: underline; }    .tg-df-container .hawk-deal-widget-title-retailer { font-size: 18px; font-weight: 700; line-height: 1.4; color: #2563eb; }    .tg-df-container .hawk-deal-widget-title-was-price { color: #dc2626; font-size: 16px; font-weight: 500; line-height: 1.4; text-decoration: line-through; white-space: nowrap; margin-left: 8px; margin-right: 8px; }    .tg-df-container .hawk-deal-widget-text-body-container { position: relative; width: 100%; box-sizing: border-box; }    .tg-df-container .hawk-deal-widget-text-body-main { font-size: 16px; width: 100%; margin-bottom: 12px; }    .tg-df-container .hawk-deal-widget-text-body-description { display: block; font-size: 15px; margin-top: 12px; color: #4b5563; line-height: 1.6; }    .tg-df-container .hawk-deal-widget-text-body-description p { margin: 0; line-height: 1.6; }    .tg-df-container .hawk-deal-widget-text-cta-container { display: flex; flex-direction: column; gap: 12px; width: 100%; flex: 1; min-width: 0; box-sizing: border-box; }    .tg-df-container .hawk-deal-widget-footer { display: flex; justify-content: flex-end; width: 100%; margin-top: auto; }    .tg-df-container .hawk-deal-widget-button-wrapper { display: flex; flex-direction: column; align-items: flex-end; justify-content: flex-end; width: 100%; }    .tg-df-container .hawk-deal-widget-preferred-partner-wrapper { display: flex; flex-direction: row; }        @container tg-df (min-width: 600px) {      .tg-df-mobile-only { display: none !important; }    }    @container tg-df (max-width: 599px) {      .tg-df-desktop-only { display: none !important; }      .tg-df-grid.layout-replica-2 { grid-template-columns: 1fr !important; }      .tg-df-grid.savings-squad-cards { grid-template-columns: 1fr !important; display: flex; flex-direction: column; }    }    .tg-df-grid.savings-squad-cards .tg-df-card-title {      -webkit-line-clamp: unset !important;      display: block !important;      overflow: visible !important;    }    @container tg-df (max-width: 500px) {      .tg-df-container .hawk-deal-widget-wrap { display: block; }      .tg-df-container .hawk-deal-widget-image-container { display: block; float: left; margin: 0 16px 8px 0; width: 120px; max-width: 120px; height: auto; align-items: normal; justify-content: normal; }      .tg-df-container .hawk-deal-widget-text-cta-container { display: block; text-align: left; }      .tg-df-container .hawk-deal-widget-footer { display: block; margin-top: 16px; clear: both; width: 100%; }      .tg-df-container .hawk-deal-widget-button-wrapper { display: block; width: 100%; }      .tg-df-container .hawk-deal-widget-button-wrapper .hawk-deal-widget-preferred-partner-wrapper { display: block; width: 100%; }      .tg-df-container .hawk-affiliate-link-deal-button { box-sizing: border-box !important; display: flex !important; max-width: none !important; width: 100% !important; margin: 0 !important; }    }        .tg-df-container .hawk-affiliate-link-deal-button {       align-items: center; background-color: #1f69ff; box-sizing: border-box; color: #ffffff !important; display: flex; font-size: 14px; font-weight: 700; justify-content: center; letter-spacing: 0.5px; line-height: 1; min-width: 160px; padding: 14px 24px; text-align: center; text-decoration: none; text-transform: uppercase; width: 100%; word-break: normal; border-radius: 4px; border: 0; transition: background-color 0.2s;     }    .tg-df-container .hawk-affiliate-link-deal-button:hover { background-color: #0056e0; text-decoration: none; }    .tg-df-container .hawk-lazy-image-deal-widget { display: block; height: auto; margin: auto; max-height: 160px; max-width: 100%; mix-blend-mode: multiply; object-fit: contain; }    .tg-df-container .hawk-deal-widget-text-cta-container a { color: #2563eb; text-decoration: none; display: inline; }    .tg-df-container .hawk-deal-widget-text-cta-container a:hover { text-decoration: underline; }    .tg-df-container .hawk-deal-widget-text-cta-container a:has(.hawk-deal-widget-title-product-title) { color: #111827; }    .tg-df-container .hawk-deal-widget-text-cta-container a:hover .hawk-deal-widget-title-product-title,    .tg-df-container .hawk-deal-widget-text-cta-container a:hover .hawk-deal-widget-title-retailer-price { text-decoration: underline; }    .tg-df-savings-squad-header { margin-bottom: 24px; text-align: center; display: none; }    .tg-df-banner-img-desktop { display: block; width: 100%; height: auto; margin-bottom: 32px; }    .tg-df-banner-img-mobile { display: none; width: 100%; height: auto; margin-bottom: 32px; }    @container tg-df (max-width: 600px) {      .tg-df-banner-img-desktop { display: none; }      .tg-df-banner-img-mobile { display: block; }    }    .tg-df-header-title { font-size: 28px; font-weight: 700; color: var(--tg-df-text); margin: 32px 0 12px 0; line-height: 1.3; }    .tg-df-header-subtitle { font-size: 16px; color: var(--tg-df-text-muted); margin: 0 0 32px 0; line-height: 1.5; }  \x3C/style>  \x3C!-- Widget Container --\x3E  \x3Cdiv class="tg-df-container" id="signal-deals-finder-root">    \x3Cdiv class="tg-df-savings-squad-header" id="tg-df-savings-squad-header">      \x3Cpicture>        \x3Cimg src="https://cdn.mos.cms.futurecdn.net/flexiimages/xkh2og7m3d1778189998.png" alt="Deals Banner" class="tg-df-banner-img-desktop" />        \x3Cimg src="https://cdn.mos.cms.futurecdn.net/flexiimages/gmak6rtdf41778245089.png" alt="Deals Banner Mobile" class="tg-df-banner-img-mobile" />      \x3C/picture>      \x3Cdiv class="tg-df-header-text">        \x3Ch2 class="tg-df-header-title" id="tg-df-header-title">Editor's Choice Deals\x3C/h2>        \x3Cp class="tg-df-header-subtitle" id="tg-df-header-subtitle">Discover the best discounts currently available, curated daily by the Tom's Guide Savings Squad.\x3C/p>      \x3C/div>    \x3C/div>    \x3C!-- Editor Floating Bar --\x3E    \x3Cdiv class="tg-df-editor-bar" id="tg-df-editor-bar" style="display:none;">      \x3Cdiv class="tg-df-editor-bar-text" style="display: flex; align-items: center;">        \x3Cspan id="tg-df-selected-count">0\x3C/span>\x26nbsp;Deals Selected        \x3Cbutton class="tg-df-editor-clear-btn" id="tg-df-editor-clear" type="button" style="margin-left: 12px; font-size: 13px; color: #9ca3af; background: none; border: none; cursor: pointer; text-decoration: underline;">Clear All\x3C/button>      \x3C/div>      \x3Cbutton class="tg-df-editor-copy-btn" id="tg-df-editor-copy" type="button">        \x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2">\x3C/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">\x3C/path>\x3C/svg>        Copy to CMS      \x3C/button>    \x3C/div>    \x3Cdiv class="tg-df-carousel-host" id="tg-df-carousel-host" style="display: none;">      \x3Cdiv class="tg-df-carousel-eyebrow">DEAL FINDER\x3C/div>      \x3Cdiv class="tg-df-carousel-query-title" id="tg-df-carousel-title-label">Best Deals\x3C/div>            \x3Cdiv class="tg-df-carousel-blue-box">        \x3Cdiv class="tg-df-carousel-bg-circle-1" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-bg-circle-2" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-bg-circle-3" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-box-content">          \x3Cdiv class="tg-df-countdown-wrapper" id="tg-df-countdown-wrapper" style="display:none;">            \x3Cdiv class="tg-df-countdown-title" id="tg-df-countdown-title">Prime Day starts in\x3C/div>            \x3Cdiv class="tg-df-countdown-blocks">              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-days">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">DAYS\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-hrs">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">HRS\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-min">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">MIN\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-sec">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">SEC\x3C/div>\x3C/div>            \x3C/div>          \x3C/div>          \x3Cdiv class="tg-df-carousel-box-eyebrow">DEAL FINDER\x3C/div>          \x3Cdiv class="tg-df-carousel-box-title">Find Deals Fast\x3C/div>          \x3Cdiv class="tg-df-carousel-box-subtitle">The latest deals from the biggest retailers, all in one place\x3C/div>                    \x3Cdiv class="tg-df-carousel-roundels-wrapper">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-roundels').scrollBy({left: -200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \x3Cdiv class="tg-df-carousel-roundels">                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Televisions" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/wcMxTsHgqu3roMbAx7RLnT-132-100.png" alt="TVs" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">TVs\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Phones" data-pr="over50">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/G3KGaRGzj24F6PUsw4bWpT-132-100.png" alt="Phones" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Phones\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Computing" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/znNvsLzx8NEgNkD9HSFSnT-132-100.png" alt="Computing" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Computing\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Gaming" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/Pgew8yaRQeZFHqHjTzvBnT-132-100.png" alt="Gaming" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Gaming\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Mattresses" data-pr="over500">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/cW7xsaLyesxkHFVSiC4kmT-132-100.png" alt="Mattresses" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Mattresses\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Audio" data-pr="over30">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/pCvBVHuhaQVjKt3VgCjbqT-132-100.png" alt="Audio" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Audio\x3C/span>            \x3C/div>                  \x3C/div>        \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" onclick="this.parentElement.querySelector('.tg-df-carousel-roundels').scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>        \x3C/div>        \x3C/div>        \x3Cdiv class="tg-df-carousel-filters-outer" style="position: relative;">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').scrollBy({left: -200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \x3Cdiv class="tg-df-carousel-filters-wrap">                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="0">All\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-ot="amazon_lightning">              \x3Cimg src="https://cdn.mos.cms.futurecdn.net/HqAui7w97ft2NPqBtQ5r38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/yWPQ5yyQRhUwVKzGwYbh38-600-100.png" class="active-img" alt="" /> Lightning deals\x3C/button>            \x3Cbutton class="tg-df-carousel-filter-btn" data-ot="amazon_prime">              \x3Cimg src="https://cdn.mos.cms.futurecdn.net/fwoVXvL79turN3Ph535m38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/u75QjVpt3w2EsMimJiRo38-600-100.png" class="active-img" alt="" /> Prime deals\x3C/button>            \x3Cbutton class="tg-df-carousel-filter-btn" data-d="10">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 10% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="15">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 15% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="25">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 25% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-pr="under50">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-badge-dollar-sign">\x3Cpath d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z">\x3C/path>\x3Cpath d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8">\x3C/path>\x3Cpath d="M12 18V6">\x3C/path>\x3C/svg>            Under $50\x3C/button>        \x3C/div>        \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>      \x3C/div>    \x3C/div>    \x3C/div>      \x3C!-- Search & Filter Controls --\x3E      \x3Cdiv class="tg-df-top-bar" id="tg-df-top-bar" style="position: relative; z-index: 100; margin: 0 auto 20px;">        \x3Cdiv class="tg-df-search-wrapper">          \x3Cinput type="text" class="tg-df-search-input" placeholder="Search for deals, products, or brands...">          \x3Cbutton type="button" class="tg-df-search-btn" aria-label="Search">              \x3Csvg class="tg-df-search-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">                \x3Cpath d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>              \x3C/svg>          \x3C/button>          \x3Cdiv class="tg-df-autocomplete-dropdown" id="tg-df-autocomplete">\x3C/div>        \x3C/div>      \x3C/div>    \x3Cdiv class="tg-df-controls" id="tg-df-controls" style="display:flex;">              \x3Cdiv class="tg-df-filters-container" style="position: relative; width: 100%; max-width: 800px; margin: 0 auto;">          \x3Cbutton class="tg-df-scroll-btn left" style="display: none;" onclick="this.parentElement.querySelector('.tg-df-filters').scrollBy({left: -200, behavior: 'smooth'})">            \x3Csvg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\x3Cpath d="M15 18l-6-6 6-6"/>\x3C/svg>          \x3C/button>          \x3Cbutton class="tg-df-scroll-btn right" style="display: none;" onclick="this.parentElement.querySelector('.tg-df-filters').scrollBy({left: 200, behavior: 'smooth'})">            \x3Csvg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\x3Cpath d="M9 18l6-6-6-6"/>\x3C/svg>          \x3C/button>          \x3Cdiv class="tg-df-filters">          \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-category-filter-wrapper" style="display: none;">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-category-filter" aria-label="Category">            \x3Coption value="all">All Categories\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper tg-df-multiselect-container" id="tg-df-brand-filter-wrapper" style="display:none;">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M4.25 5.61C6.27 8.2 10 13 10 13v6c0 .55.45 1 1 1h2c.55 0 1-.45 1-1v-6s3.72-4.8 5.74-7.39A.998.998 0 0 0 18.95 4H5.04c-.83 0-1.3.95-.79 1.61z"/>          \x3C/svg>          \x3Cdiv class="tg-df-filter-select tg-df-multiselect-trigger" id="tg-df-brand-trigger" tabindex="0">            Any Brand          \x3C/div>          \x3Cdiv class="tg-df-multiselect-dropdown" id="tg-df-brand-dropdown">            \x3C!-- Populated via script --\x3E          \x3C/div>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper tg-df-price-range-wrapper" id="tg-df-custom-price-wrapper" style="display: flex; align-items:center; justify-content:center; padding: 10px 20px; gap: 8px; border: 1px solid var(--tg-df-border); border-radius: 100px; background-color: var(--tg-df-bg);">          \x3Cspan style="font-size:14px; font-weight:500; color:var(--tg-df-text-primary);">Price\x3C/span>          \x3Cinput type="number" class="tg-df-price-input" id="tg-df-custom-price-min" placeholder="Min" style="width: 48px; background: transparent; border: none; color: var(--tg-df-text-primary); outline: none; font-size: 14px; text-align: center; padding: 0;">          \x3Cspan style="color:var(--tg-df-text-muted)">-\x3C/span>          \x3Cinput type="number" class="tg-df-price-input" id="tg-df-custom-price-max" placeholder="Max" style="width: 48px; background: transparent; border: none; color: var(--tg-df-text-primary); outline: none; font-size: 14px; text-align: center; padding: 0;">        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-legacy-price-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-price-filter" aria-label="Filter Prices">            \x3Coption value="all">All Prices\x3C/option>            \x3Coption value="under50">Under $50\x3C/option>            \x3Coption value="50_100">$50 - $100\x3C/option>            \x3Coption value="100_200">$100 - $200\x3C/option>            \x3Coption value="200_500">$200 - $500\x3C/option>            \x3Coption value="over500">Over $500\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-discount-filter-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">            \x3Cpath d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-discount-filter" aria-label="Discount Amount">            \x3Coption value="all">Any discount\x3C/option>            \x3Coption value="5">Min 5%\x3C/option>            \x3Coption value="10">Min 10%\x3C/option>            \x3Coption value="15">Min 15%\x3C/option>            \x3Coption value="20">Min 20%\x3C/option>            \x3Coption value="25">Min 25%\x3C/option>            \x3Coption value="30">Min 30%\x3C/option>            \x3Coption value="40">Min 40%\x3C/option>            \x3Coption value="50">Min 50%\x3C/option>            \x3Coption value="60">Min 60%\x3C/option>            \x3Coption value="70">Min 70%\x3C/option>          \x3C/select>          \x3C/div>        \x3C/div>        \x3C/div>      \x3C/div>    \x3C!-- Deals Grid Wrapper --\x3E    \x3Cdiv class="tg-df-grid-wrapper tg-df-carousel-cards-wrapper" id="tg-df-grid-wrapper">      \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').scrollBy({left: -200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>      \x3Cdiv class="tg-df-grid" id="tg-df-grid">        \x3C!-- Content populated by JavaScript --\x3E      \x3C/div>      \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>    \x3C/div>        \x3C!-- Vouchers Modal --\x3E    \x3Cdiv class="tg-df-modal-backdrop" id="tg-df-vouchers-modal">      \x3Cdiv class="tg-df-modal">        \x3Cdiv class="tg-df-modal-header">          \x3Ch3 class="tg-df-modal-title" id="tg-df-vouchers-title">Available Coupons & Deals\x3C/h3>          \x3Cbutton class="tg-df-modal-close" id="tg-df-vouchers-close">            \x3Csvg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">              \x3Cline x1="18" y1="6" x2="6" y2="18">\x3C/line>              \x3Cline x1="6" y1="6" x2="18" y2="18">\x3C/line>            \x3C/svg>          \x3C/button>        \x3C/div>        \x3Cdiv class="tg-df-modal-body" id="tg-df-vouchers-content">          \x3C!-- Vouchers injected here --\x3E        \x3C/div>      \x3C/div>    \x3C/div>  \x3C/div>`;      if (!template) {        template = document.createElement('template');        template.innerHTML = rawTemplate;      }      let shadowRoot = null;      if (hostContainer && template) {        hostContainer.setAttribute('data-initialized', 'true');        shadowRoot = hostContainer.attachShadow({ mode: 'open' });        shadowRoot.appendChild(template.content.cloneNode(true));      }      class DealsFinderWidget {        constructor(config) {          this.rootNode = config.rootNode || document;          this.hostContainer = config.hostContainer || null;          this.rootId = config.rootId || 'signal-deals-finder-root';          this.root = this.rootNode.querySelector('#' + this.rootId);          if (!this.root) return;          this.widgetId = (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : 'widget-' + Date.now() + '-' + Math.random().toString(36).slice(2);          this.grid = this.root.querySelector('#tg-df-grid');          this.tagsContainer = this.root.querySelector('#tg-df-tags-container');          this.categoryFilter = this.root.querySelector('#tg-df-category-filter');          this.categoryFilterWrapper = this.root.querySelector('#tg-df-category-filter-wrapper');          this.searchInput = this.root.querySelector('.tg-df-search-input');          this.autocompleteDropdown = this.root.querySelector('#tg-df-autocomplete');          this.sortSelect = this.root.querySelector('.tg-df-sort-select');          this.searchBtn = this.root.querySelector('.tg-df-search-btn');                    this.settingsToggle = this.root.querySelector('#tg-df-settings-toggle');          this.settingsPanel = this.root.querySelector('#tg-df-settings-panel');          this.settingsBackdrop = this.root.querySelector('#tg-df-settings-backdrop');          this.regionSelect = this.root.querySelector('#tg-df-region-select');          this.retailerSelect = this.root.querySelector('#tg-df-retailer-select');          this.offerTypeSelect = this.root.querySelector('#tg-df-offer-type-select');          this.viewModeSelect = this.root.querySelector('#tg-df-view-mode-select');          this.rowsSelect = this.root.querySelector('#tg-df-rows-select');          this.dealModeToggle = this.root.querySelector('#tg-df-deal-mode');          this.editorModeToggle = this.root.querySelector('#tg-df-editor-mode');          this.priceFilter = this.root.querySelector('#tg-df-price-filter');          this.discountFilter = this.root.querySelector('#tg-df-discount-filter');                    this.editorBar = this.root.querySelector('#tg-df-editor-bar');          this.editorSelectedCount = this.root.querySelector('#tg-df-selected-count');          this.editorCopyBtn = this.root.querySelector('#tg-df-editor-copy');          this.editorClearBtn = this.root.querySelector('#tg-df-editor-clear');                    this.apiUrl = 'https://search-api.fie.future.net.uk/widget.php';          this.deals = [];          this.displayLimit = 12;          this.airedaleArticles = null;          this.airedaleTags = [];          this.airedaleTagCounts = {};          this.activeDealTag = null;          this.selectedBrands = [];          this.currentQuery = '';          this.editorMode = this.hostContainer ? this.hostContainer.hasAttribute('data-editor-mode') : false;          this.viewModeOverride = this.hostContainer ? this.hostContainer.getAttribute('data-view-mode') : null;          this.selectedDeals = new Map();                    this.brandFilterWrapper = this.root.querySelector('#tg-df-brand-filter-wrapper');          this.brandTrigger = this.root.querySelector('#tg-df-brand-trigger');          this.brandDropdown = this.root.querySelector('#tg-df-brand-dropdown');                    this.customPriceWrapper = this.root.querySelector('#tg-df-custom-price-wrapper');          this.customPriceMin = this.root.querySelector('#tg-df-custom-price-min');          this.customPriceMax = this.root.querySelector('#tg-df-custom-price-max');          this.legacyPriceWrapper = this.root.querySelector('#tg-df-legacy-price-wrapper');          this.discountFilterWrapper = this.root.querySelector('#tg-df-discount-filter-wrapper');          this.initResizeObserver();          this.init();        }        getViewMode() {          console.log("DEBUG getViewMode -> override:", this.viewModeOverride, "editorMode:", this.editorMode);          if (this.viewModeOverride && (!this.editorMode || !this.viewModeSelect)) {            return this.viewModeOverride;          }          return (this.viewModeSelect && this.viewModeSelect.value) ? this.viewModeSelect.value : (this.viewModeOverride || 'auto');        }        applyLayoutMode() {          if (!this.grid) return;          const mode = this.getViewMode();          console.log("[DEBUG] applyLayoutMode CALLED! mode=", mode);          this.grid.classList.remove('layout-row', 'layout-grid', 'tg-df-grid-auto', 'carousel-compact', 'layout-replica-1', 'layout-replica-2');                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          const showHeaderDetails = params.get('show_header_details') !== 'false';          const carouselHost = this.root.querySelector('#tg-df-carousel-host');          const controlsDiv = this.root.querySelector('#tg-df-controls');          const topBarDiv = this.root.querySelector('#tg-df-top-bar');          const headerElement = this.root.querySelector('#tg-df-savings-squad-header');          if (headerElement) {             headerElement.style.display = (mode === 'savings_squad' && showHeaderDetails) ? 'block' : 'none';          }          if (mode === 'carousel') {             this.grid.classList.add('carousel-compact');             if (carouselHost) carouselHost.style.display = 'block';             if (controlsDiv) controlsDiv.style.display = 'none';             if (topBarDiv) topBarDiv.style.display = 'none';             if (this.root.classList.contains('tg-df-container')) {               this.root.classList.add('is-carousel');             }          } else {             if (carouselHost) carouselHost.style.display = 'none';             if (controlsDiv) controlsDiv.style.display = 'flex';             if (topBarDiv) topBarDiv.style.display = 'block';             if (this.root.classList.contains('tg-df-container')) {               this.root.classList.remove('is-carousel');             }          }          if (mode === 'grid') {            this.grid.classList.add('layout-grid');          } else if (mode === 'row') {            this.grid.classList.add('layout-row');          } else if (mode === 'savings_squad') {            this.grid.classList.add('tg-df-grid-auto', 'savings-squad-cards');          } else if (mode !== 'carousel') {            this.grid.classList.add('tg-df-grid-auto');          }                    const settingsWrapper = this.root.querySelector('.tg-df-settings-wrapper');          if (settingsWrapper) {            settingsWrapper.style.display = mode === 'auto' ? 'none' : 'block';          }          if (this.customPriceWrapper) {             this.customPriceWrapper.style.display = mode === 'auto' ? 'flex' : 'none';          }          if (this.legacyPriceWrapper) {             this.legacyPriceWrapper.style.display = mode === 'auto' ? 'none' : 'flex';          }          if (this.discountFilterWrapper) {             this.discountFilterWrapper.style.display = mode === 'auto' ? 'none' : 'flex';          }        }        initResizeObserver() {          try {            if (window.parent === window) return;          } catch (e) {            // cross origin frame check threw          }          const emitHeight = () => {            try {              const height = document.documentElement.scrollHeight || document.body.scrollHeight;              const msg = { type: 'embed-size', height: height };              if (window.parent && window.parent !== window) {                window.parent.postMessage(msg, '*');                window.parent.postMessage(JSON.stringify({ ...msg, sentinel: 'amp' }), '*');              }            } catch (e) {}          };                    if (window.ResizeObserver) {            try {              const ro = new ResizeObserver(() => emitHeight());              ro.observe(document.body);              if (this.root) ro.observe(this.root);            } catch(e){ console.warn(e); }          }          window.addEventListener('resize', emitHeight);          setTimeout(emitHeight, 300);        }        initCountdown() {          this.cdWrapper = this.root.querySelector('#tg-df-countdown-wrapper');                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          this.showCountdown = params.get('show_countdown') === 'true';          const showHeaderDetails = params.get('show_header_details') !== 'false';          const eyebrow = this.root.querySelector('.tg-df-carousel-box-eyebrow');          const title = this.root.querySelector('.tg-df-carousel-box-title');          const subtitle = this.root.querySelector('.tg-df-carousel-box-subtitle');          if (!showHeaderDetails) {            let containerElement = this.root.classList.contains('tg-df-container') ? this.root : this.root.querySelector('.tg-df-container');            if (containerElement) containerElement.classList.add('hide-header-details');            if (eyebrow) eyebrow.style.display = 'none';            if (title) title.style.display = 'none';            if (subtitle) subtitle.style.display = 'none';          }          if (!this.cdWrapper) return;          this.cdTitle = this.root.querySelector('#tg-df-countdown-title');          this.cdDays = this.root.querySelector('#tg-df-cd-days');          this.cdHrs = this.root.querySelector('#tg-df-cd-hrs');          this.cdMin = this.root.querySelector('#tg-df-cd-min');          this.cdSec = this.root.querySelector('#tg-df-cd-sec');          this.updateCountdown();          this.cdInterval = setInterval(() => this.updateCountdown(), 1000);        }        updateCountdown() {          if (!this.cdWrapper) return;          if (!this.showCountdown) {            this.cdWrapper.style.display = 'none';            return;          }          const area = this.getAreaCode();          let offset = '-04:00';          if (['DE', 'FR', 'IT', 'ES', 'NL'].includes(area)) {             offset = '+02:00';          } else if (['GB', 'IE', 'UK'].includes(area)) {             offset = '+01:00';          }          const startTime = new Date('2026-06-23T00:00:00' + offset).getTime();          const endTime = new Date('2026-06-26T00:00:00' + offset).getTime();          const now = Date.now();          let targetTime = 0;          if (now < startTime) {             targetTime = startTime;             if (this.cdTitle) this.cdTitle.textContent = 'Prime Day starts in';             this.cdWrapper.style.display = 'flex';          } else if (now < endTime) {             targetTime = endTime;             if (this.cdTitle) this.cdTitle.textContent = 'Prime Day ends in';             this.cdWrapper.style.display = 'flex';          } else {             this.cdWrapper.style.display = 'none';             if (this.cdInterval) clearInterval(this.cdInterval);             return;          }          const diff = Math.max(0, targetTime - now);          const d = Math.floor(diff / (1000 * 60 * 60 * 24));          const h = Math.floor((diff / (1000 * 60 * 60)) % 24);          const m = Math.floor((diff / 1000 / 60) % 60);          const s = Math.floor((diff / 1000) % 60);          if (this.cdDays) this.cdDays.textContent = d;          if (this.cdHrs) this.cdHrs.textContent = h;          if (this.cdMin) this.cdMin.textContent = m;          if (this.cdSec) this.cdSec.textContent = s;        }        init() {          this.initCountdown();          try {            initAnalytics();          } catch (e) {            console.warn('Deals Widget Analytics Error:', e);          }                    this.bindEvents();                    let initialQuery = '';                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          let initialViewMode = params.get('view_mode');          if (!this.viewModeOverride && initialViewMode) {            this.viewModeOverride = initialViewMode;          }          if (!params.has('search') && !params.has('q') && !params.has('query') && initialViewMode !== 'savings_squad') {             initialQuery = 'Gaming laptops';          }          const website = params.get('website') || 'tomsguide';          this.website = website;          if (website === 'techradar') {            const squadHeader = this.root.querySelector('.tg-df-savings-squad-header');            if (squadHeader) {               const pic = squadHeader.querySelector('picture');               if (pic) pic.style.display = 'none';            }            const style = document.createElement('style');            style.innerHTML = `              .tg-df-container .hawk-affiliate-link-deal-button, .tg-df-container .tg-df-card-cta { background-color: #5DAF08 !important; }              .tg-df-container .hawk-affiliate-link-deal-button:hover, .tg-df-container .tg-df-card-cta:hover { background-color: #4a8c06 !important; }            `;            this.root.appendChild(style);          }                    if (this.regionSelect) {            this.regionSelect.value = params.get('region') || 'auto';            this.updatePriceDropdownCurrency();          }                    if (this.retailerSelect && params.has('retailer')) {            this.retailerSelect.value = params.get('retailer');          }                    if (params.has('brands')) {            const b = params.get('brands');            if (b) {              this.selectedBrands = b.split(',');            }          }                    if (this.offerTypeSelect && params.has('offer_type')) {            this.offerTypeSelect.value = params.get('offer_type');          }          if (this.viewModeSelect && params.has('view_mode')) {            this.viewModeSelect.value = params.get('view_mode');          }          if (this.rowsSelect && params.has('rows')) {            this.rowsSelect.value = params.get('rows');          }          if (params.has('price')) {            const priceVal = params.get('price');            if (this.priceFilter) {               // Try assigning it directly to select. If it's not present implicitly ignores               this.priceFilter.value = priceVal;            }            if (priceVal.includes('_')) {               const parts = priceVal.split('_');               if (this.customPriceMin && parts[0]) this.customPriceMin.value = parts[0];               if (this.customPriceMax && parts[1]) this.customPriceMax.value = parts[1];            }          }          if (this.discountFilter && params.has('min_discount_ratio')) {            // Need to convert back from ratio (e.g. 0.8) to select value (e.g. "20")            const ratioStr = params.get('min_discount_ratio');            const ratioFloat = parseFloat(ratioStr);            if (!isNaN(ratioFloat)) {               const percentage = Math.round((1 - ratioFloat) * 100);               this.discountFilter.value = percentage.toString();            }          }          if (this.sortSelect) {            this.sortSelect.value = params.get('sort') || 'date_desc';          }          if (this.dealModeToggle && params.has('deal_mode')) {            this.dealModeToggle.checked = params.get('deal_mode') === 'true' || params.get('deal_mode') === '1';          }          const headerTitleEl = this.root.querySelector('#tg-df-header-title');          const headerSubtitleEl = this.root.querySelector('#tg-df-header-subtitle');          if (params.has('widget_title') && headerTitleEl) {             headerTitleEl.textContent = params.get('widget_title');          }          if (params.has('widget_subtitle') && headerSubtitleEl) {             headerSubtitleEl.textContent = params.get('widget_subtitle');          }                    // Re-apply layout after params have updated control values          this.applyLayoutMode();                    if (params.get('search')) {            initialQuery = params.get('search');          } else if (params.get('q')) {            initialQuery = params.get('q');          } else if (params.get('query')) {            initialQuery = params.get('query');          }                    this.currentQuery = initialQuery;          if (this.searchInput) {            if (this.getViewMode() === 'savings_squad') {              this.searchInput.value = '';            } else {              this.searchInput.value = this.currentQuery;            }          }                    if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {            this.fetchDeals(this.currentQuery);          } else {            this.render();          }        }        updatePriceDropdownCurrency() {          if (!this.priceFilter || !this.regionSelect) return;          const currencySymbols = {            'US': '$',            'GB': '£',            'CA': '$CA',            'AU': '$AU',            'DE': '€',            'FR': '€',            'IT': '€',          };          const area = this.getAreaCode();          const cur = currencySymbols[area || 'US'] || '$';                    const options = this.priceFilter.options;          for (let i = 0; i < options.length; i++) {            const opt = options[i];            if (opt.value === 'all') {              opt.innerText = 'All Prices';            } else if (opt.value === 'under50') {              opt.innerText = `Under ${cur}50`;            } else if (opt.value === '50_100') {              opt.innerText = `${cur}50 - ${cur}100`;            } else if (opt.value === '100_200') {              opt.innerText = `${cur}100 - ${cur}200`;            } else if (opt.value === '200_500') {              opt.innerText = `${cur}200 - ${cur}500`;            } else if (opt.value === 'over500') {              opt.innerText = `Over ${cur}500`;            }          }        }        populateBrandDropdown(values) {          if (!this.brandDropdown || !this.brandFilterWrapper) return;          this.brandFilterWrapper.style.display = 'flex'; // show the wrapper                    let html = '';          const allChecked = this.selectedBrands.length === 0 ? 'checked' : '';          const _div = '<' + '/div>';          const _span = '<' + '/span>';          html += `\x3Cdiv class="tg-df-ms-option">\x3Cinput type="checkbox" value="" ${allChecked} class="tg-df-brand-chk"> Any Brand${_div}`;                    values.forEach(v => {             if (!v.formatted_value || v.formatted_value === 'Any Brand') return;             const isChecked = this.selectedBrands.includes(v.formatted_value) ? 'checked' : '';             html += `\x3Cdiv class="tg-df-ms-option">\x3Cinput type="checkbox" value="${this.escapeHTML(v.formatted_value)}" ${isChecked} class="tg-df-brand-chk"> ${this.escapeHTML(v.formatted_value)} \x3Cspan style="color:var(--tg-df-text-muted);font-size:12px">(${v.count || 0})${_span}${_div}`;          });                    this.brandDropdown.innerHTML = html;                    // Re-bind listeners          const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');          chks.forEach(chk => {            chk.addEventListener('change', (e) => {              const val = e.target.value;              if (val === '') {                this.selectedBrands = [];              } else {                if (e.target.checked) {                   if (!this.selectedBrands.includes(val)) this.selectedBrands.push(val);                } else {                   this.selectedBrands = this.selectedBrands.filter(b => b !== val);                }              }                            if (this.selectedBrands.length === 0) {                 this.brandTrigger.innerText = 'Any Brand';              } else if (this.selectedBrands.length === 1) {                 this.brandTrigger.innerText = this.selectedBrands[0];              } else {                 this.brandTrigger.innerText = `${this.selectedBrands.length} Brands selected`;              }                            // Only call API if changed from UI interactions              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                 this.updateURLParams();                 this.fetchDeals(this.currentQuery);              }            });          });                    // Update button text on load          if (this.selectedBrands.length === 0) {             this.brandTrigger.innerText = 'Any Brand';          } else if (this.selectedBrands.length === 1) {             this.brandTrigger.innerText = this.selectedBrands[0];          } else {             this.brandTrigger.innerText = `${this.selectedBrands.length} Brands selected`;          }        }        updateURLParams() {          const url = new URL(window.location);          if (this.currentQuery && this.currentQuery !== 'Gaming laptops') {            url.searchParams.set('q', this.currentQuery);          } else {            url.searchParams.delete('q');            url.searchParams.delete('search');            url.searchParams.delete('query');          }                    if (this.regionSelect && this.regionSelect.value !== 'auto') {            url.searchParams.set('region', this.regionSelect.value);          } else {            url.searchParams.delete('region');          }                    if (this.retailerSelect && this.retailerSelect.value) {            url.searchParams.set('retailer', this.retailerSelect.value);          } else {            url.searchParams.delete('retailer');          }                    if (this.selectedBrands && this.selectedBrands.length > 0) {            url.searchParams.set('brands', this.selectedBrands.join(','));          } else {            url.searchParams.delete('brands');          }                    if (this.offerTypeSelect && this.offerTypeSelect.value) {            url.searchParams.set('offer_type', this.offerTypeSelect.value);          } else {            url.searchParams.delete('offer_type');          }                    if (this.viewModeSelect && this.viewModeSelect.value !== 'auto') {            url.searchParams.set('view_mode', this.viewModeSelect.value);          } else {            url.searchParams.delete('view_mode');          }                    if (this.rowsSelect && this.rowsSelect.value !== '12') {            url.searchParams.set('rows', this.rowsSelect.value);          } else {            url.searchParams.delete('rows');          }                    const min = this.customPriceMin ? this.customPriceMin.value : '';          const max = this.customPriceMax ? this.customPriceMax.value : '';          if (min || max) {             url.searchParams.set('price', `${min}_${max}`);          } else if (this.priceFilter && this.priceFilter.value !== 'all') {            url.searchParams.set('price', this.priceFilter.value);          } else {            url.searchParams.delete('price');          }                    if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {            const v = parseInt(this.discountFilter.value);            if (!isNaN(v) && v > 0) {               const ratio = (100 - v) / 100;               url.searchParams.set('min_discount_ratio', ratio.toString());            }          } else {            url.searchParams.delete('min_discount_ratio');          }                    if (this.sortSelect && this.sortSelect.value !== 'date_desc') {            url.searchParams.set('sort', this.sortSelect.value);          } else {            url.searchParams.delete('sort');          }                    if (this.dealModeToggle && this.dealModeToggle.checked) {            url.searchParams.set('deal_mode', 'true');          } else {            url.searchParams.delete('deal_mode');          }                    window.history.replaceState({}, '', url);        }        bindEvents() {          const handleFiltersScroll = () => {            const filters = this.root.querySelector('.tg-df-filters');            const leftBtn = this.root.querySelector('.tg-df-scroll-btn.left');            const rightBtn = this.root.querySelector('.tg-df-scroll-btn.right');            if (filters && leftBtn && rightBtn) {              const { scrollLeft, scrollWidth, clientWidth } = filters;              leftBtn.style.display = scrollLeft > 0 ? 'flex' : 'none';              rightBtn.style.display = Math.ceil(scrollLeft + clientWidth) < scrollWidth - 5 ? 'flex' : 'none';            }          };          const filters = this.root.querySelector('.tg-df-filters');          if (filters) {            filters.addEventListener('scroll', handleFiltersScroll);            window.addEventListener('resize', handleFiltersScroll);            setTimeout(handleFiltersScroll, 100);                        // Also call after rendering dropdowns            const origRenderCategories = this.renderCategories;            if (origRenderCategories) {               this.renderCategories = (...args) => {                 origRenderCategories.apply(this, args);                 setTimeout(handleFiltersScroll, 50);               };            }          }                const roundels = this.root.querySelectorAll('.tg-df-carousel-cat');          roundels.forEach(r => {             r.addEventListener('click', () => {                const q = r.getAttribute('data-query');                const pr = r.getAttribute('data-pr');                if (typeof trackHawkEvent !== 'undefined') {                     trackHawkEvent({                         clickType: "CC",                         widgetId: this.widgetId,                         productCategoryName: "deals",                         zeroBasedProductIndexOrNull: null,                         totalDealsOrProducts: null,                         areaClicked: "Category Roundel",                         revenueId: this.revenueId,                         isoCurrencyCode: typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD',                         queryName: q,                         widgetTypeName: this.widgetTypeName                     });                 }                this.currentQuery = q;                const label = this.root.querySelector('#tg-df-carousel-title-label');                if (label) label.textContent = 'Best ' + q;                if (this.priceFilter) this.priceFilter.value = pr || 'all';                if (this.discountFilter) this.discountFilter.value = '5';                if (this.searchInput) this.searchInput.value = q;                                roundels.forEach(ro => ro.classList.remove('active'));                r.classList.add('active');                this.fetchDeals(this.currentQuery);             });          });          const discBtns = this.root.querySelectorAll('.tg-df-carousel-filter-btn');          discBtns.forEach(b => {             b.addEventListener('click', () => {                const d = b.getAttribute('data-d');                const pr = b.getAttribute('data-pr');                const ot = b.getAttribute('data-ot');                let label = b.innerText ? b.innerText.trim() : '';                let filterType = 'unknown';                let filterVal = 'unknown';                if (d !== null) { filterType = 'discount'; filterVal = d; }                else if (pr !== null) { filterType = 'price'; filterVal = pr; }                else if (ot !== null) { filterType = 'offertype'; filterVal = ot; }                if (typeof trackElementInteraction === 'function') trackElementInteraction({ id: `filter-${filterType}-${filterVal}`, name: 'Filter Button', label: label });                                if (d !== null) {                   if (this.discountFilter) this.discountFilter.value = this.discountFilter.value === d ? '0' : d;                } else if (pr !== null) {                   if (this.priceFilter) this.priceFilter.value = this.priceFilter.value === pr ? 'all' : pr;                } else if (ot !== null) {                   if (this.offerTypeSelect) this.offerTypeSelect.value = this.offerTypeSelect.value === ot ? 'all' : ot;                } else {                   if (this.discountFilter) this.discountFilter.value = '0';                   if (this.priceFilter) this.priceFilter.value = 'all';                   if (this.offerTypeSelect) this.offerTypeSelect.value = 'all';                }                if (d === null && pr === null && ot === null && b.getAttribute("data-type") !== "custom") {                   discBtns.forEach(ro => ro.classList.remove('active'));                   b.classList.add('active');                } else if (b.getAttribute("data-type") !== "custom") {                   // Only operate on hardcoded buttons (those without data-type)                   discBtns.forEach(ro => {                      if (!ro.getAttribute('data-d') && !ro.getAttribute('data-pr') && !ro.getAttribute('data-ot') && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active');                   });                                      let makeActive = true;                   if (d !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-d') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   } else if (pr !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-pr') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   } else if (ot !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-ot') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   }                                      if (makeActive) b.classList.add('active');                                      // Check if anything is active, if not activate "All"                   let anyActive = false;                   discBtns.forEach(ro => { if (ro.classList.contains('active') && ro.getAttribute('data-type') !== 'custom') anyActive = true; });                   if (!anyActive) {                       discBtns.forEach(ro => { if (!ro.getAttribute('data-d') && !ro.getAttribute('data-pr') && !ro.getAttribute('data-ot') && ro.getAttribute('data-type') !== 'custom') ro.classList.add('active'); });                   }                }                                this.fetchDeals(this.currentQuery);             });          });          if (this.brandTrigger && this.brandDropdown) {            this.brandTrigger.addEventListener('click', () => {              this.brandDropdown.classList.toggle('active');            });            document.addEventListener('click', (e) => {              if (this.brandFilterWrapper && !e.composedPath().includes(this.brandFilterWrapper)) {                this.brandDropdown.classList.remove('active');              }            });          }          const showAutocomplete = () => {             if (this.getViewMode() !== 'savings_squad' || !this.autocompleteDropdown || !this.airedaleTags) return;                          let terms = this.airedaleTags;             if (this.airedaleBrands) {                terms = terms.concat(this.airedaleBrands.map(b => b.formatted_value));             }             terms = [...new Set(terms)];                          const query = this.searchInput.value.trim();             let matches = [];             if (query.length > 0) {                 matches = terms.filter(t => t.toLowerCase().includes(query.toLowerCase()) && t.toLowerCase() !== query.toLowerCase());             } else {                 matches = terms;             }                          if (matches.length > 0) {                 this.autocompleteDropdown.innerHTML = matches.map(m => `\x3Cdiv class="tg-df-autocomplete-item" data-tag="${this.escapeHTML(m)}">${this.escapeHTML(m)}<` + `/div>`).join('');                 this.autocompleteDropdown.classList.add('active');             } else {                 this.autocompleteDropdown.classList.remove('active');             }          };          let debounceTimer;          if(this.searchInput) {            this.searchInput.addEventListener('focus', showAutocomplete);            this.searchInput.addEventListener('input', (e) => {              clearTimeout(debounceTimer);              const query = e.target.value.trim();              this.currentQuery = query;              showAutocomplete();              debounceTimer = setTimeout(() => {                this.updateURLParams();                if (query.length > 2) {                  this.fetchDeals(query);                } else if (query.length === 0) {                  if (this.getViewMode() === 'savings_squad') {                    this.activeDealTag = null;                    this.currentQuery = '';                    if (this.categoryFilter) this.categoryFilter.value = 'all';                    this.fetchDeals('');                  } else {                    this.deals = [];                    this.render();                  }                }              }, 400);            });            this.searchInput.addEventListener('keypress', (e) => {              if (e.key === 'Enter') {                if (this.autocompleteDropdown) this.autocompleteDropdown.classList.remove('active');                clearTimeout(debounceTimer);                const query = e.target.value.trim();                this.currentQuery = query;                                let isTag = false;                if (this.airedaleTags && this.airedaleTags.includes(query)) isTag = true;                if (this.airedaleBrands && this.airedaleBrands.some(b => b.formatted_value === query)) isTag = true;                this.activeDealTag = isTag ? query : null;                                trackElementInteraction({ id: 'search-submit', name: 'Ask', label: 'Ask (main search)', text: query });                this.updateURLParams();                if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                   if (query.length === 0 && this.getViewMode() === 'savings_squad') {                       if (this.categoryFilter) this.categoryFilter.value = 'all';                   }                   this.fetchDeals(query);                }              }            });          }          if (this.autocompleteDropdown) {             this.autocompleteDropdown.addEventListener('click', (e) => {                const item = e.target.closest('.tg-df-autocomplete-item');                if (item) {                   const tag = item.getAttribute('data-tag');                   this.currentQuery = tag;                   if (this.searchInput) this.searchInput.value = tag;                   this.activeDealTag = tag;                   if (this.categoryFilter && this.airedaleTags.includes(tag)) {                       this.categoryFilter.value = tag;                   }                   this.autocompleteDropdown.classList.remove('active');                   this.updateURLParams();                   this.fetchDeals(tag);                }             });             document.addEventListener('click', (e) => {               if (this.autocompleteDropdown && this.searchInput && !e.composedPath().includes(this.searchInput) && !e.composedPath().includes(this.autocompleteDropdown)) {                 this.autocompleteDropdown.classList.remove('active');               }             });          }          if (this.searchBtn) {            this.searchBtn.addEventListener('click', () => {              if (this.autocompleteDropdown) this.autocompleteDropdown.classList.remove('active');              clearTimeout(debounceTimer);              const query = this.searchInput.value.trim();              trackElementInteraction({ id: 'search-submit', name: 'Ask', label: 'Ask (main search)', text: query });                            let isTag = false;              if (this.airedaleTags && this.airedaleTags.includes(query)) isTag = true;              if (this.airedaleBrands && this.airedaleBrands.some(b => b.formatted_value === query)) isTag = true;              this.activeDealTag = isTag ? query : null;                            this.currentQuery = query;              this.updateURLParams();              if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                 if (query.length === 0 && this.getViewMode() === 'savings_squad') {                     if (this.categoryFilter) this.categoryFilter.value = 'all';                 }                 this.fetchDeals(query);              }            });          }          if(this.sortSelect && this.sortSelect.querySelector('option[value="date_desc"]') === null) {              const option = document.createElement('option');              option.value = "date_desc";              option.text = "Newest First";              this.sortSelect.insertBefore(option, this.sortSelect.firstChild);          }          if(this.sortSelect) this.sortSelect.addEventListener('change', () => {            trackElementInteraction({ id: `sort-option-${this.sortSelect.value}`, name: 'Sort', label: `Sort: ${this.sortSelect.options[this.sortSelect.selectedIndex].text}` });            this.updateURLParams();            if (this.deals.length > 0) {              this.sortData();              this.render();            }          });                    const priceFilter = this.root.querySelector('#tg-df-price-filter');          if (priceFilter) {            this.priceFilter = priceFilter;            this.priceFilter.addEventListener('change', () => {              trackElementInteraction({ id: `filter-price-${this.priceFilter.value}`, name: 'Price', label: this.priceFilter.options[this.priceFilter.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }            });          }          const updateCustomPrice = () => {             this.updateURLParams();             if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);             } else {                this.render();             }          };          if (this.customPriceMin) {             this.customPriceMin.addEventListener('change', updateCustomPrice);             this.customPriceMin.addEventListener('keypress', (e) => {                if (e.key === 'Enter') updateCustomPrice();             });          }          if (this.customPriceMax) {             this.customPriceMax.addEventListener('change', updateCustomPrice);             this.customPriceMax.addEventListener('keypress', (e) => {                if (e.key === 'Enter') updateCustomPrice();             });          }          const discountFilter = this.root.querySelector('#tg-df-discount-filter');          if (discountFilter) {            this.discountFilter = discountFilter;            this.discountFilter.addEventListener('change', () => {              trackElementInteraction({ id: `filter-discount-${this.discountFilter.value}`, name: 'Discount', label: this.discountFilter.options[this.discountFilter.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }            });          }          if (this.categoryFilter) {            this.categoryFilter.addEventListener('change', (e) => {               const val = e.target.value === 'all' ? null : e.target.value;               this.activeDealTag = val;               if (val) {                 this.currentQuery = val;               } else {                 if (this.searchInput && this.currentQuery === document.querySelector('#tg-df-brand-trigger')?.getAttribute('data-active-brand')) {                     // don't clear current query if a brand is selected                 } else if (this.searchInput) {                     this.currentQuery = '';                     this.searchInput.value = '';                 }               }               this.fetchSavingsSquad();            });          }                    if (this.settingsToggle) {            this.settingsToggle.addEventListener('click', () => {              const o = this.settingsPanel.classList.toggle('active');              this.settingsBackdrop.classList.toggle('active');              if (o) trackElementInteraction({ id: 'filter-open', name: 'Filters', label: 'Open filters' });            });          }                    if (this.settingsBackdrop) {            this.settingsBackdrop.addEventListener('click', () => {              this.settingsPanel.classList.remove('active');              this.settingsBackdrop.classList.remove('active');            });          }                    if (this.regionSelect) {            this.regionSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-region-${this.regionSelect.value}`, name: 'Region', label: this.regionSelect.options[this.regionSelect.selectedIndex].text });              this.updateURLParams();              this.updatePriceDropdownCurrency();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.retailerSelect) {            this.retailerSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-merchant-${this.retailerSelect.value}`, name: 'Retailer', label: this.retailerSelect.options[this.retailerSelect.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.offerTypeSelect) {            this.offerTypeSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-offertype-${this.offerTypeSelect.value}`, name: 'Offer Type', label: this.offerTypeSelect.options[this.offerTypeSelect.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.viewModeSelect) {            this._prevViewMode = this.viewModeSelect.value;            this.viewModeSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-viewmode-${this.viewModeSelect.value}`, name: 'View Mode', label: this.viewModeSelect.options[this.viewModeSelect.selectedIndex].text });                            // Reset all active toggles and filters to prevent config carry-over              this.selectedBrands = [];              if (this.brandTrigger) this.brandTrigger.innerText = 'Select Brands';              if (this.brandDropdown) {                const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                chks.forEach(chk => { chk.checked = false; });              }              if (this.priceFilter) this.priceFilter.value = 'all';              if (this.customPriceMin) this.customPriceMin.value = '';              if (this.customPriceMax) this.customPriceMax.value = '';              if (this.sortSelect) this.sortSelect.value = 'date_desc';              if (this.discountFilter) this.discountFilter.value = '0';              if (this.retailerSelect) this.retailerSelect.value = '';              if (this.offerTypeSelect) this.offerTypeSelect.value = '';              if (this.rowsSelect) this.rowsSelect.value = '12';              if (this.categoryFilter) this.categoryFilter.value = 'all';              this.activeDealTag = null;              this.updateURLParams();              this.applyLayoutMode();                            if (this.getViewMode() === 'savings_squad' || this._prevViewMode === 'savings_squad') {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }              this._prevViewMode = this.viewModeSelect.value;            });          }                    if (this.rowsSelect) {            this.rowsSelect.addEventListener('change', () => {              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.dealModeToggle) {            this.dealModeToggle.addEventListener('change', () => {              this.updateURLParams();              this.render();            });          }          if (this.editorModeToggle) {             this.editorModeToggle.addEventListener('change', (e) => {                this.editorMode = e.target.checked;                this.render();                this.updateFloatingCopyBar();             });          }          if (this.editorCopyBtn) {             this.editorCopyBtn.addEventListener('click', () => {                this.copySelectedDealsToCMS();             });          }          if (this.editorClearBtn) {             this.editorClearBtn.addEventListener('click', () => {                this.selectedDeals.clear();                this.render();                this.updateFloatingCopyBar();             });          }          if (this.grid) {            this.grid.addEventListener('change', (e) => {               if (e.target.classList.contains('tg-df-deal-checkbox')) {                  const dealId = e.target.getAttribute('data-id');                  if (e.target.checked) {                     const dealObj = this.deals.find(d => d.id === dealId);                     if (dealObj) this.selectedDeals.set(dealId, dealObj);                  } else {                     this.selectedDeals.delete(dealId);                  }                  this.updateFloatingCopyBar();               }            });            this.grid.addEventListener('click', (e) => {              const dealCard = e.target.closest('[data-action="deal-click"]');              const similarCard = e.target.closest('[data-action="view-similar-click"]');              const cardLink = dealCard || similarCard;              if (cardLink) {                const productName = cardLink.getAttribute('data-product-name');                const merchantName = cardLink.getAttribute('data-merchant-name');                const productId = cardLink.getAttribute('data-analytics-id');                const price = parseFloat(cardLink.getAttribute('data-price')) || null;                const prevPriceStr = cardLink.getAttribute('data-previous-price');                const previousPrice = prevPriceStr ? parseFloat(prevPriceStr) : null;                const originalLink = cardLink.getAttribute('data-original-link');                const finalHref = cardLink.href || cardLink.getAttribute('href') || '';                let actualRevenueId = cardLink.getAttribute('data-revenue-id');                const revMatch = finalHref.match(/(?:subId1|xcust|clickref|ascsubtag)=[^&]*?(\d{18,20})(?:&|$)/i);                if (revMatch && revMatch[1]) {                  actualRevenueId = revMatch[1];                }                const rewrittenLink = finalHref;                const revenueId = actualRevenueId;                const index = parseInt(cardLink.getAttribute('data-index'), 10) || 0;                const inStock = cardLink.getAttribute('data-in-stock') === 'true';                const totalText = cardLink.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: cardLink.getAttribute('data-model-id') || null,                    matchId: cardLink.getAttribute('data-match-id') || null,                    brand: cardLink.getAttribute('data-model-brand') || null,                    parent: cardLink.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: cardLink.getAttribute('data-merchant-id') || null,                    network: cardLink.getAttribute('data-merchant-network') || null,                    url: cardLink.getAttribute('data-merchant-url') || null,                    name: merchantName                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: normalizeCurrency(this.escapeHTML(cardLink.getAttribute('data-currency') || '$'))                };                if (dealCard) {                  trackDealClick(trackingParams);                } else {                  trackViewSimilarClick(trackingParams);                }              }              const couponsBtn = e.target.closest('[data-action="coupons-click"]');              if (couponsBtn) {                trackElementInteraction({                  id: 'product-card-show-coupons',                  name: 'Coupons',                  label: `Product card coupons: ${couponsBtn.getAttribute('data-merchant')}`                });              }            });          }          this.setupScrollListeners();        }        setupScrollListeners() {          const containers = [             this.root.querySelector('.tg-df-carousel-roundels'),             this.root.querySelector('.tg-df-carousel-filters-wrap'),             this.root.querySelector('#tg-df-grid')          ];                    containers.forEach(container => {             if (!container) return;                          const checkScroll = () => {                if (!container.parentElement) return;                const leftBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-left');                const rightBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-right');                                if (leftBtn) {                   if (container.scrollLeft <= 5) leftBtn.style.display = 'none';                   else leftBtn.style.display = 'flex';                }                                if (rightBtn) {                   if (container.scrollWidth <= container.clientWidth) {                       rightBtn.style.display = 'none';                   } else if (container.scrollLeft >= container.scrollWidth - container.clientWidth - 5) {                       rightBtn.style.display = 'none';                   } else {                       rightBtn.style.display = 'flex';                   }                }             };                          container.addEventListener('scroll', checkScroll);             checkScroll();                          window.addEventListener('resize', checkScroll);                          const observer = new MutationObserver(checkScroll);             observer.observe(container, { childList: true, subtree: true, characterData: false });          });        }        get widgetTypeName() {          const mode = this.viewModeSelect ? this.viewModeSelect.value : (this.viewModeOverride || 'auto');          switch(mode) {              case 'carousel': return 'Carousel';              case 'savings_squad': return 'Savings Squad';              case 'grid': return 'Grid';              case 'row': return 'Row';              default: return 'Auto Collection';          }        }        getRowsLimit() {          if (this.rowsSelect && this.rowsSelect.value) return parseInt(this.rowsSelect.value, 10);          let configSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {             configSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {             configSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(configSource);          if (params.has('rows')) return parseInt(params.get('rows'), 10) || 12;          return 12;        }        getAreaCode() {          if (this.regionSelect && this.regionSelect.value) {            if (this.regionSelect.value === 'auto') return null;            return this.regionSelect.value;          }          let area = null;          try {            const locale = window.navigator.language || window.navigator.userLanguage;            if (locale && locale.includes('-')) {              area = locale.split('-')[1].toUpperCase();            } else if (locale && locale.length === 2) {              if (locale.toUpperCase() === 'EN') { area = 'US'; }              else { area = locale.toUpperCase(); }            }          } catch (e) { /* Ignore */ }                    // Map to known valid options or fallback to US          const valid = ['US', 'GB', 'CA', 'AU', 'DE', 'FR', 'IT'];          if (area === 'UK') area = 'GB';          if (valid.includes(area)) {             return area;          }          return 'US';        }        async 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 = this.decodeHTML(description.replace(/<br\s*\/?>/gi, ' ').replace(/<\/?(p|div)[^>]*>/gi, ' ').replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').replace(/View Deal$/i, '').trim());                summaryTitle = this.decodeHTML(summaryTitle);                                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.getFilteredDeals().slice(0, this.displayLimit), this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        isBroadQuery(query) {          const q = query.toLowerCase();          const intentModifiers = ['deals', 'best', 'sale', 'under', 'cheap', 'offers', 'discount'];          return intentModifiers.some(term => q.includes(term));        }        async fetchHawkDeals(query) {          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.getFilteredDeals().slice(0, this.displayLimit), this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        async fetchAdviserDeals(query) {          // ======================================================================          // TODO: ADVISER API REPLACEMENT          // The code below simulates the Adviser API response using mock data.          // Once the real endpoint is ready, remove getAdviserMockData() and           // perform an actual fetch() request similar to fetchHawkDeals().          // Example:          // const area = this.getAreaCode();          // let apiUrl = `https://your-adviser-api.com/search?q=${query}&area=${area}`;          // if (this.priceFilter && this.priceFilter.value !== 'all') {          //   const val = this.priceFilter.value;          //   if (val === 'under50') apiUrl += '&filter_max_price=50';          //   else if (val === '50_100') apiUrl += '&filter_max_price=100';          //   else if (val === '100_200') apiUrl += '&filter_max_price=200';          //   else if (val === '200_500') apiUrl += '&filter_max_price=500';          // }          // const res = await fetch(apiUrl);          // const rawData = await res.json();          // ======================================================================          // Simulating network latency          await new Promise(resolve => setTimeout(resolve, 400));                    const rawData = this.getAdviserMockData();          let offers = [];                    if (rawData && rawData.data && rawData.data.Get && Array.isArray(rawData.data.Get.Deal)) {            offers = rawData.data.Get.Deal;          }                    // Basic client-side filtering for the mock if we want it to react to the query          const q = query.toLowerCase();          const selectedRetailer = (this.retailerSelect && this.retailerSelect.value) ? this.retailerSelect.value.toLowerCase() : null;                    offers.forEach(item => {            const dataObj = item;                        // Apply retailer filter            const itemRetailer = (dataObj.dataRetailer || '').toLowerCase();            if (selectedRetailer && itemRetailer !== selectedRetailer && !itemRetailer.includes(selectedRetailer)) {              return;            }                        // Apply mock price filter            let price = dataObj.dataDiscountedPrice || 0;            if (typeof price === 'string') {              price = parseFloat(price.replace(/[^0-9.]/g, ''));            }            let priceVal = null;            const min = this.customPriceMin ? this.customPriceMin.value : '';            const max = this.customPriceMax ? this.customPriceMax.value : '';            if (min || max) {               priceVal = `${min}_${max}`;            } else if (this.priceFilter && this.priceFilter.value !== 'all') {               priceVal = this.priceFilter.value;            }            if (priceVal) {              if (priceVal === 'under50' && price >= 50) return;              if (priceVal === 'over50' && price <= 50) return;              if (priceVal === 'over30' && price <= 30) return;              if (priceVal === 'over500' && price <= 500) return;              if (priceVal.includes('_')) {                 const parts = priceVal.split('_');                 if (parts[0] && price < parseFloat(parts[0])) return;                 if (parts[1] && price > parseFloat(parts[1])) return;              }            }                        // Map Adviser schema to our widget's expected schema            const mappedData = {              url: dataObj.linkHREF || dataObj.dataLink || '#',              image: dataObj.imageURL || (dataObj.image && dataObj.image.src) || '',              title: dataObj.dataProduct || (dataObj.product && dataObj.product.name) || 'Product Deal',              merchant: dataObj.dataRetailer || 'Retailer',              price: dataObj.dataDiscountedPrice || 0,              currency: dataObj.dataCurrency === 'USD' ? '$' : (dataObj.dataCurrency || '$'),              msrp: dataObj.dataOriginalPrice || null            };                        const titleLow = mappedData.title.toLowerCase();            const merchLow = mappedData.merchant.toLowerCase();                        // Smarter mock filtering            let isMatch = false;            if (q === '' || this.isBroadQuery(q)) {              isMatch = true;            } else if (titleLow.includes(q) || merchLow.includes(q)) {              isMatch = true;            } else if ((q.includes('laptop') || q.includes('mac') || q.includes('pc')) && (titleLow.includes('macbook') || titleLow.includes('laptop'))) {              isMatch = true;            } else if ((q.includes('tv') || q.includes('television')) && (titleLow.includes('tv') || titleLow.includes('oled') || titleLow.includes('qled'))) {              isMatch = true;            } else if ((q.includes('phone') || q.includes('smartphone')) && (titleLow.includes('galaxy') || titleLow.includes('phone'))) {              isMatch = true;            } else if ((q.match(/watch|fitness|run|shoe/)) && (titleLow.includes('forerunner') || titleLow.includes('saucony') || titleLow.includes('watch'))) {              isMatch = true;            }                        if (isMatch) {               this.deals.push(this.extractDealData(mappedData));            }          });                    let rowLimit = this.getRowsLimit();          // Intentionally omitting the slice here to allow "Load More" to work if the API returns more                    this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.getFilteredDeals().slice(0, this.displayLimit), this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        getAdviserMockData() {          return {            "data": {              "Get": {                "Deal": [                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 300,                    "dataOriginalPrice": 399,                    "dataProduct": "Samsung Galaxy A36",                    "dataRetailer": "Samsung",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/MqDYsukV3JBG54te6dEs7j.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 14,                    "dataOriginalPrice": 24,                    "dataProduct": "Blink Mini",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/3JurmAjHsDa5tPdaHAwEV8.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 59,                    "dataOriginalPrice": 99,                    "dataProduct": "Ring Video Doorbell",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/rAh4uR7AsAsALCCLTXnLNJ.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 10,                    "dataOriginalPrice": 599,                    "dataProduct": "MacBook Neo",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/Lg4Dvg68j9SbB5CPNrTEpH.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 749,                    "dataOriginalPrice": 849,                    "dataProduct": "65\\\" Fire TV Omni 4K QLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/SG34ZWodUkLTxJvMTbjPYR.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 71,                    "dataOriginalPrice": 160,                    "dataProduct": "Saucony Hurricane 24",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/vxf7UD5T2Am7guVzFoFcZ4.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 649,                    "dataOriginalPrice": 749,                    "dataProduct": "Garmin Forerunner 970",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/3GKnEu7CdhtxPMfnPCMCiA.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1049,                    "dataOriginalPrice": 1499,                    "dataProduct": "LG 48\\\" C4 4K OLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/imvwZV9zoMD6fn9Afuge35.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1499,                    "dataOriginalPrice": 2199,                    "dataProduct": "Samsung 49\\\" Odyssey Neo G9 4K Gaming Monitor",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/XWDEJ5dUAE2nhK8k3Jk7k7.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 299,                    "dataOriginalPrice": 699,                    "dataProduct": "EGOHOME Black Memory Foam Mattress (queen)",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/hMUemtAejNETLVYxNrktzm.jpg"                  }                ]              }            }          };        }        decodeHTML(html) {          if (!html) return '';          const txt = document.createElement("textarea");          txt.innerHTML = String(html);          return txt.value;        }        extractDealData(item) {          const priceRawStr = String(item.price || item.current_price || '0');          const msrpRawStr = String(item.was_price || item.msrp || item.original_price || '0');          const rawPrice = parseFloat(priceRawStr.replace(/[^\d.]/g, '')) || 0;          const rawMsrp = parseFloat(msrpRawStr.replace(/[^\d.]/g, '')) || 0;          const isCheckPrice = rawPrice === 0 || priceRawStr === '0.00' || priceRawStr === '0';                    let originalImageUrl = item.image || item.image_url || item.product_image || '';          let imageUrl = originalImageUrl;          if ((!imageUrl || isCheckPrice) && item.model_image_url) {             imageUrl = item.model_image_url;             originalImageUrl = imageUrl;          } else if ((!imageUrl || isCheckPrice) && item.model_image) {             imageUrl = item.model_image;             originalImageUrl = imageUrl;          }                    if (imageUrl) {            imageUrl = imageUrl.replace(/-(\d+)-(\d+)(\.[a-z.]+)$/i, '$3');          }                    let fallbackImage = '';          if (originalImageUrl && originalImageUrl !== imageUrl) {             fallbackImage = originalImageUrl;          } else if (item.model_image && item.model_image !== imageUrl) {             fallbackImage = item.model_image;          } else if (item.model_image_url && item.model_image_url !== imageUrl) {             fallbackImage = item.model_image_url;          }                    const rawCurrency = item.currency || item.currency_symbol || '$';                    let savingLabel = item.percentage_saving_label || '';          if (!savingLabel && rawMsrp > rawPrice && rawPrice > 0) {            const pct = Math.round(((rawMsrp - rawPrice) / rawMsrp) * 100);            if (pct > 0) {              savingLabel = `${pct}% OFF`;            }          }                    const isPrime = item.shipping && item.shipping.prime === true;                    let scoreRaw = (item.review_score !== undefined && item.review_score !== null && item.review_score > 0) ? parseFloat(item.review_score) : null;          let starRating = 0;          if (scoreRaw !== null) {            starRating = Math.round((scoreRaw > 10 ? scoreRaw / 20 : scoreRaw / 2) * 2) / 2;          }                    return {            id: item.offer_id || item.link || item.url || item.offer_link || Math.random().toString(),            url: item.link || item.url || item.offer_link || '#',            image: imageUrl,            fallbackImage: fallbackImage,            title: this.decodeHTML(item.name || item.title || item.model_name || item.product_name || 'Unknown Product'),            brand: this.decodeHTML(item.brand || ''),            productName: this.decodeHTML(item.model_name || item.product_name || item.name || ''),            merchant: this.decodeHTML(item.merchant_name || item.merchant || item.retailer || 'Retailer'),            price: item.price !== undefined ? String(item.price) : '0.00',            currency: this.decodeHTML(rawCurrency),            msrp: item.was_price || item.msrp || item.original_price || null,            rawPrice: rawPrice,            rawMsrp: rawMsrp,            hasWasPrice: (item.was_price !== undefined && item.was_price !== null),            isCheckPrice: isCheckPrice,            savingLabel: savingLabel,            isPrime: isPrime,            starRating: starRating > 0 ? starRating : null,            modelId: item.model_id || '',            productKey: item.product_key || '',            merchantId: (item.merchant && typeof item.merchant === 'object') ? item.merchant.id || '' : '',            matchId: item.match_id || '',            merchantNetwork: (item.merchant && typeof item.merchant === 'object') ? item.merchant.an || '' : '',            merchantUrl: (item.merchant && typeof item.merchant === 'object') ? item.merchant.url || '' : '',            modelBrand: item.model_brand || item.brand || '',            modelParent: item.model_parent || ''          };        }        sortData() {          const sortVal = this.sortSelect ? this.sortSelect.value : '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 finalHref = btn.href || btn.getAttribute('href') || '';                let actualRevenueId = btn.getAttribute('data-revenue-id');                const revMatch = finalHref.match(/(?:subId1|xcust|clickref|ascsubtag)=[^&]*?(\d{18,20})(?:&|$)/i);                if (revMatch && revMatch[1]) {                  actualRevenueId = revMatch[1];                }                const rewrittenLink = finalHref;                const revenueId = actualRevenueId;                const index = parseInt(btn.getAttribute('data-index'), 10) || 0;                const inStock = btn.getAttribute('data-in-stock') === 'true';                const totalText = btn.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: btn.getAttribute('data-model-id') || null,                    matchId: btn.getAttribute('data-match-id') || null,                    brand: btn.getAttribute('data-model-brand') || null,                    parent: btn.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: btn.getAttribute('data-merchant-id') || null,                    network: btn.getAttribute('data-merchant-network') || null,                    url: btn.getAttribute('data-merchant-url') || null,                    name: merchantNameAttr                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: btn.getAttribute('data-currency') || 'USD'                };                if (typeof trackDealClick === 'function') {                  trackDealClick(trackingParams);                }              });            });                                  } catch (e) {            console.warn(e);            content.innerHTML = `\x3Cdiv class="tg-df-message">Failed to load vouchers.${_div}`;          }        }        render() {          try {            if (this.getViewMode() === 'savings_squad' && this.airedaleTags.length > 0) {              if (this.categoryFilterWrapper) {                 this.categoryFilterWrapper.style.display = 'flex';              }              if (this.categoryFilter) {                 const _option = '<' + '/option>';                 let optionsHtml = `\x3Coption value="all">All Categories${_option}`;                 this.airedaleTags.forEach(tag => {                    const isSelected = this.activeDealTag === tag ? 'selected' : '';                    optionsHtml += `\x3Coption value="${this.escapeHTML(tag)}" ${isSelected}>${this.escapeHTML(tag)}${_option}`;                 });                 this.categoryFilter.innerHTML = optionsHtml;                 this.categoryFilter.value = this.activeDealTag || 'all';              }            } else {               if (this.categoryFilterWrapper) {                  this.categoryFilterWrapper.style.display = 'none';               }            }            const displayDeals = this.getFilteredDeals();          // HACK: Hide closing tags from the CMS HTML sanitizer so it doesn't strip them during in-page injection          const _div = '<' + '/div>';          const _span = '<' + '/span>';          const _a = '<' + '/a>';          const _h3 = '<' + '/h3>';          const _p = '<' + '/p>';          const _strong = '<' + '/strong>';          const _sup = '<' + '/sup>';          const _button = '<' + '/button>';          if (displayDeals.length === 0) {            if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {              if (this.deals.length > 0) {                 this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                  No deals match your selected filters.                ${_div}`;              } else if (this.getViewMode() === 'savings_squad' && this.currentQuery.length <= 2) {                 // Do not show "no exact matches" if query is empty for savings_squad                 this.grid.innerHTML = '';              } else {                 this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                  No exact matches found for "\x3Cstrong>${this.escapeHTML(this.currentQuery)}${_strong}". Try adjusting your search term.                ${_div}`;              }            } else {              this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                Search product or category names to discover the best deals from across the web.              ${_div}`;            }            return;          }          let dealsHtml = displayDeals.slice(0, this.displayLimit).map((deal, index) => {            try {               const currencySym = this.escapeHTML(deal.currency);               const isoCurrencyCode = normalizeCurrency(currencySym);               const escapedPrice = this.escapeHTML(deal.price);               const escapedMsrp = this.escapeHTML(deal.msrp);               const areaCode = this.getAreaCode();                              const revenueId = generateRevenueId(deal.url, deal.title, deal.merchant, null);               const originalLink = deal.url;               const rewrittenLink = rewriteAffiliateLink(deal.url, areaCode, revenueId);                        const productCategoryName = 'deals';            const dataAttr = `              data-action="${deal.isCheckPrice ? 'view-similar-click' : 'deal-click'}"              data-analytics-id="${this.escapeHTML(deal.externalProductId || deal.id || '')}"              data-product-name="${this.escapeHTML(deal.title)}"              data-merchant-name="${this.escapeHTML(deal.merchant)}"              data-price="${deal.rawPrice || ''}"              data-previous-price="${deal.rawMsrp || ''}"              data-original-link="${this.escapeHTML(originalLink)}"              data-revenue-id="${revenueId}"              data-index="${index}"              data-total="${displayDeals.length}"              data-in-stock="${deal.inStock !== false}"              data-currency="${this.escapeHTML(isoCurrencyCode)}"              data-model-id="${this.escapeHTML(deal.modelId || '')}"              data-product-key="${this.escapeHTML(deal.productKey || '')}"              data-merchant-id="${this.escapeHTML(deal.merchantId || '')}"            `;                        let priceGroupHtml = '';            let isSavingsSquadMode = this.getViewMode() === 'savings_squad';            let ctaText = 'View Deal';            let formattedPrice = '';            let msrpHtml = '';                        if (deal.isCheckPrice) {              ctaText = 'View Deal';              if (isSavingsSquadMode) {                priceGroupHtml = ``;              } else {                priceGroupHtml = `                  \x3Cdiv class="tg-df-card-price-group">                    \x3Cspan class="tg-df-card-price" style="font-size: 15px; font-weight: 500; font-style: italic;">See price at retailer${_span}                  ${_div}                `;              }            } else {              // Format Price              formattedPrice = escapedPrice.includes(currencySym)                 ? escapedPrice                 : `${currencySym}${escapedPrice}`;                              // Format MSRP              msrpHtml = deal.msrp && deal.rawMsrp > deal.rawPrice                ? `\x3Cspan class="tg-df-card-msrp">${escapedMsrp.includes(currencySym) ? escapedMsrp : currencySym + escapedMsrp}${_span}`                : '';                              priceGroupHtml = isSavingsSquadMode ? `` : `                \x3Cdiv class="tg-df-card-price-group">                  \x3Cspan class="tg-df-card-price">${formattedPrice}${_span}                  ${msrpHtml}                ${_div}              `;            }                        const discountBadgeHtml = deal.savingLabel && !deal.isCheckPrice              ? `\x3Cspan class="tg-df-card-discount-badge">${this.escapeHTML(deal.savingLabel)}${_span}`              : '';                          // HACK for CMS            const _button = '<' + '/button>';            const _svg = '<' + '/svg>';            const _path = '<' + '/path>';            const _rect = '<' + '/rect>';            const _circle = '<' + '/circle>';            const _polyline = '<' + '/polyline>';            const _line = '<' + '/line>';                        let badgesHtml = '';            const primeBadge = deal.isPrime ? `              \x3Cspan class="tg-df-tag tg-df-tag-prime">                \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">                  \x3Cpath d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z">${_path}                ${_svg} Prime              ${_span}            ` : '';                        const couponsBadge = deal.merchant && deal.merchant.toLowerCase().includes('amazon') ? '' : `              \x3Cdiv class="tg-df-coupon-wrapper" data-merchant="${this.escapeHTML(deal.merchant)}" style="display:inline-flex; align-items:center;">                \x3Cdiv class="tg-df-coupon-spinner">${_div}                \x3Cbutton type="button" class="tg-df-tag tg-df-tag-coupons" data-action="coupons-click" data-merchant="${this.escapeHTML(deal.merchant)}" style="display:none;">                  \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">                    \x3Cpath d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z">${_path}                    \x3Cline x1="7" y1="7" x2="7.01" y2="7">${_line}                  ${_svg} Coupons                ${_button}              ${_div}            `;                        // Note: We always add coupons badge if there's a chance, but to allow 3-line titles we check wrapper display state            badgesHtml = `              \x3Cdiv class="tg-df-card-badges">                ${primeBadge}                ${couponsBadge}              ${_div}            `;            const _linearGradient = '<' + '/linearGradient>';            const _polygon = '<' + '/polygon>';            const _stop = '<' + '/stop>';            const _defs = '<' + '/defs>';                        let starHtml = '';            if (deal.starRating) {              let rating = deal.starRating;                            if (rating > 0) {                const fullStars = Math.floor(rating);                const halfStar = (rating - fullStars) >= 0.5 ? 1 : 0;                const emptyStars = Math.max(0, 5 - fullStars - halfStar);                const blue = '#1f69ff'; // Tom's guide brand color from VIEW DEAL button                const gray = '#cbd5e1';                                const starSvgFull = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="${blue}" stroke="${blue}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26">${_polygon}${_svg}`;                                const gradId = 'half_grad_' + Math.floor(Math.random()*1000000);                const starSvgHalf = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" stroke="${blue}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cdefs>\x3ClinearGradient id="${gradId}" x1="0" x2="1" y1="0" y2="0">\x3Cstop offset="50%" stop-color="${blue}">${_stop}\x3Cstop offset="50%" stop-color="transparent">${_stop}${_linearGradient}${_defs}                  \x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26" fill="url(#${gradId})">${_polygon}${_svg}`;                                  const starSvgEmpty = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="${gray}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26">${_polygon}${_svg}`;                                let stars = [];                for (let i=0; i<fullStars; i++) stars.push(starSvgFull);                if (halfStar) stars.push(starSvgHalf);                for (let i=0; i<emptyStars; i++) stars.push(starSvgEmpty);                                starHtml = `\x3Cdiv class="tg-df-card-stars" style="display:flex;align-items:center;margin-bottom:8px;font-size:13px;font-weight:600;color:var(--tg-df-text-muted);">                  \x3Cspan style="margin-right:6px;">Tom's Guide:${_span}                  \x3Cdiv style="display:flex;gap:2px;">                    ${stars.join('')}                  ${_div}                ${_div}`;              }            }            let htmlOutput = '';            if (isSavingsSquadMode) {              htmlOutput += `              \x3Cdiv class="hawk-deal-widget-container tg-df-mobile-only" data-collapsible="true">                ${this.editorMode ? `\x3Cinput type="checkbox" class="tg-df-deal-checkbox" data-id="${this.escapeHTML(deal.id)}" ${this.selectedDeals.has(deal.id) ? 'checked' : ''} style="margin-bottom: 10px;">` : ''}                \x3Cdiv class="hawk-deal-widget-wrap">                  \x3Cdiv class="hawk-deal-widget-image-container">                    \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" rel="sponsored noopener" target="_blank" class="hawk-affiliate-link-deal-widget" ${dataAttr}>                      \x3Cimg ${deal.image ? `src="${this.escapeHTML(deal.image)}"` : ''} alt="${this.escapeHTML(deal.title)}" class="hawk-lazy-image-deal-widget" loading="lazy" width="140" height="160" onerror="${deal.fallbackImage ? `if(!this.dataset.fb) { this.dataset.fb='1'; this.src='${this.escapeHTML(deal.fallbackImage)}'; } else { this.style.opacity='0'; }` : `this.style.opacity='0';`}">                    ${_a}                  ${_div}                  \x3Cdiv class="hawk-deal-widget-text-cta-container">                    \x3Cdiv class="hawk-deal-widget-text-body-container">                      \x3Cdiv class="hawk-deal-widget-text-body-main">                        \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                          ${deal.isCheckPrice ? `                            \x3Cspan class="hawk-deal-widget-title-product-title">${this.escapeHTML(deal.title)}${_span}                          ` : `                            \x3Cspan class="hawk-deal-widget-title-product-title">${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_span}                          `}                        ${_a}                        ${!deal.isCheckPrice && deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `                          \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                            \x3Cspan class="hawk-deal-widget-title-was-price">was ${currencySym}${escapedMsrp}${_span}                          ${_a}                        ` : ''}                        \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                          \x3Cspan class="hawk-deal-widget-title-retailer-price">                            ${!deal.isCheckPrice ? `                              \x3Cspan class="hawk-deal-widget-title-price">now ${formattedPrice}${_span}                              \x3Cspan class="hawk-deal-widget-title-retailer"> at ${this.escapeHTML(deal.merchant)}${_span}                            ` : `                              \x3Cspan class="hawk-deal-widget-title-price">See price at ${this.escapeHTML(deal.merchant)}${_span}                            `}                          ${_span}                        ${_a}                        ${deal.description ? `\x3Cdiv class="hawk-deal-widget-text-body-description tg-df-card-desc-container" style="margin-bottom: 12px; position: relative;">                          \x3Cp class="tg-df-card-desc-content" style="font-size: 13px; color: var(--tg-df-text-muted); margin-bottom: 0; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;">${this.escapeHTML(deal.description)}${_p}                          \x3Cbutton type="button" class="tg-df-card-desc-btn" style="display: none; appearance: none; border: none; color: #000000; font-size: 11px; font-weight: 700; text-transform: uppercase; cursor: pointer; font-family: inherit; position: absolute; bottom: 2px; right: 0; background: linear-gradient(to right, transparent, #fff 20%, #fff); padding: 0 0 0 16px;" onclick="                            var c = this.parentNode;                            if (this.dataset.expanded === 'true') {                              var pd = (c.tagName === 'P') ? c : this.previousElementSibling;                              if (c.tagName === 'P') { c.parentNode.appendChild(this); pd = c; }                              pd.style.display = '-webkit-box';                              pd.style.webkitLineClamp = '3';                              this.textContent = 'READ MORE';                              this.style.position = 'absolute';                              this.style.background = 'linear-gradient(to right, transparent, #fff 20%, #fff)';                              this.style.paddingLeft = '16px';                              this.dataset.expanded = 'false';                            } else {                              var pd = this.previousElementSibling;                              pd.style.display = 'inline';                              pd.style.webkitLineClamp = 'unset';                              this.textContent = 'READ LESS';                              this.style.position = 'static';                              this.style.background = 'transparent';                              this.style.paddingLeft = '4px';                              this.dataset.expanded = 'true';                              pd.appendChild(this);                            }                          ">READ MORE${_button}                        \x3C/div>` : ''}                      ${_div}                    ${_div}                    ${deal.authorName ? `                      \x3Cdiv class="tg-df-author-line-mobile" style="padding: 0 0 12px 0; background: transparent;">                         \x3Cdiv style="display: flex; align-items: center; gap: 12px;">                            ${deal.authorImage ? `\x3Cimg src="${this.escapeHTML(deal.authorImage)}" alt="${this.escapeHTML(deal.authorName)}" class="tg-df-author-img" width="40" height="40" style="border-radius: 50%; object-fit: cover; flex-shrink: 0; aspect-ratio: 1 / 1; min-width: 40px; min-height: 40px;">` : ''}                            \x3Cdiv style="display: flex; flex-direction: column;">                               \x3Cdiv style="font-size: 10px; color: var(--tg-df-text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 2px; font-weight: 600;">\x3Cspan style="color: #FF6600;">${this.escapeHTML(deal.merchant)}${_span} deal recommended by:${_div}                               \x3Cdiv style="font-size: 11px; color: var(--tg-df-text); line-height: 1.3;">                                  \x3Cstrong>\x3Ca href="https://www.tomsguide.com/${this.escapeHTML(deal.documentUrl || '').replace(/^\/+/, '')}" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit; border-bottom: 1px dotted var(--tg-df-text-muted);">${this.escapeHTML(deal.authorName)}${_a}${_strong}                                  ${deal.authorRole && !['null', 'nul', 'undefined'].includes(String(deal.authorRole).toLowerCase()) ? ` • ${this.escapeHTML(deal.authorRole)}` : ''}                                  ${deal.modifiedDate ? `\x3Cdiv style="color: var(--tg-df-text-muted); margin-top: 2px;">${getTimeAgo(deal.modifiedDate)}${_div}` : ''}                               ${_div}                            ${_div}                         ${_div}                      ${_div}                    ` : ''}                    \x3Cdiv class="hawk-deal-widget-footer">                      \x3Cdiv class="hawk-deal-widget-button-wrapper">                        \x3Cdiv class="hawk-deal-widget-preferred-partner-wrapper">                          \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-deal-button" rel="sponsored noopener" target="_blank" ${dataAttr}>                            \x3Cspan>View Deal${_span}                          ${_a}                        ${_div}                      ${_div}                    ${_div}                  ${_div}                ${_div}              ${_div}              `;            }            htmlOutput += `              \x3Cdiv class="tg-df-card ${isSavingsSquadMode ? 'tg-df-desktop-only' : ''}">                ${this.editorMode ? `\x3Cinput type="checkbox" class="tg-df-deal-checkbox" data-id="${this.escapeHTML(deal.id)}" ${this.selectedDeals.has(deal.id) ? 'checked' : ''}>` : ''}                \x3Cdiv class="tg-df-card-image-box">                  ${discountBadgeHtml}                  \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" style="display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;">                    \x3Cimg ${deal.image ? `src="${this.escapeHTML(deal.image)}"` : ''} alt="${this.escapeHTML(deal.title)}" class="tg-df-card-image" loading="lazy" onerror="${deal.fallbackImage ? `if(!this.dataset.fb) { this.dataset.fb='1'; this.src='${this.escapeHTML(deal.fallbackImage)}'; } else { this.style.opacity='0'; }` : `this.style.opacity='0';`}">                  ${_a}                  \x3Cdiv class="tg-df-card-merchant-wrapper" style="position: absolute; bottom: 0; right: 0; background: transparent; padding: 8px 12px; z-index: 10;">                     \x3Cspan class="tg-df-card-merchant-pill" style="text-align: right; margin-bottom: 0;" title="${this.escapeHTML(deal.merchant)}">${this.escapeHTML(deal.merchant)}${_span}                  ${_div}                ${_div}                \x3Cdiv class="tg-df-card-body">                  ${starHtml}                  ${badgesHtml}                  \x3Ch3 class="tg-df-card-title tg-df-custom-savings-squad-title" title="${this.escapeHTML(deal.title)}">                    \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit;">                      ${isSavingsSquadMode                         ? (deal.isCheckPrice                             ? (deal.title && deal.title.includes(':')                                 ? `\x3Cstrong>${this.escapeHTML(deal.title.substring(0, deal.title.indexOf(':') + 1))}${_strong}\x3Cspan style="color: #1f69ff; font-weight: normal;">${this.escapeHTML(deal.title.substring(deal.title.indexOf(':') + 1))}${_span}`                                : this.escapeHTML(deal.title)                              )                             : `\x3Cstrong>${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_strong} ${deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `\x3Cspan style="color: #d0021b; text-decoration: line-through; font-weight: normal; margin-right: 4px;">was ${currencySym}${escapedMsrp}${_span} ` : ''}\x3Cspan style="color: #1f69ff; font-weight: normal;">now ${formattedPrice} at ${this.escapeHTML(deal.merchant)}${_span}`                          )                        : this.escapeHTML(deal.title)                      }                    ${_a}                  ${_h3}                  ${deal.description ? `\x3Cdiv class="tg-df-card-desc-container" style="margin-bottom: 12px; position: relative;">                    \x3Cp class="tg-df-card-desc-content" style="font-size: 13px; color: var(--tg-df-text-muted); margin-bottom: 0; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;">${this.escapeHTML(deal.description)}${_p}                    \x3Cbutton type="button" class="tg-df-card-desc-btn" style="display: none; appearance: none; border: none; color: #000000; font-size: 11px; font-weight: 700; text-transform: uppercase; cursor: pointer; font-family: inherit; position: absolute; bottom: 2px; right: 0; background: linear-gradient(to right, transparent, #fff 20%, #fff); padding: 0 0 0 16px;" onclick="                      var c = this.parentNode;                      if (this.dataset.expanded === 'true') {                        var pd = (c.tagName === 'P') ? c : this.previousElementSibling;                        if (c.tagName === 'P') { c.parentNode.appendChild(this); pd = c; }                        pd.style.display = '-webkit-box';                        pd.style.webkitLineClamp = '3';                        this.textContent = 'READ MORE';                        this.style.position = 'absolute';                        this.style.background = 'linear-gradient(to right, transparent, #fff 20%, #fff)';                        this.style.paddingLeft = '16px';                        this.dataset.expanded = 'false';                      } else {                        var pd = this.previousElementSibling;                        pd.style.display = 'inline';                        pd.style.webkitLineClamp = 'unset';                        this.textContent = 'READ LESS';                        this.style.position = 'static';                        this.style.background = 'transparent';                        this.style.paddingLeft = '4px';                        this.dataset.expanded = 'true';                        pd.appendChild(this);                      }                    ">READ MORE${_button}                  \x3C/div>` : ''}                  \x3Cdiv class="tg-df-card-footer">                    ${deal.authorName ? `                    \x3Cdiv class="tg-df-author-line-desktop" style="padding: 0 0 ${isSavingsSquadMode ? 0 : 12}px 0;">                       \x3Cdiv style="display: flex; align-items: center; gap: 10px;">                          ${deal.authorImage ? `\x3Cimg src="${this.escapeHTML(deal.authorImage)}" alt="${this.escapeHTML(deal.authorName)}" class="tg-df-author-img" width="36" height="36" style="border-radius: 50%; object-fit: cover; flex-shrink: 0; aspect-ratio: 1 / 1; min-width: 36px; min-height: 36px;">` : ''}                          \x3Cdiv style="display: flex; flex-direction: column;">                             \x3Cdiv style="font-size: 10px; color: var(--tg-df-text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 2px; font-weight: 600;">Recommended by:${_div}                             \x3Cdiv style="font-size: 11px; color: var(--tg-df-text); line-height: 1.2;">                                \x3Cstrong>\x3Ca href="https://www.tomsguide.com/${this.escapeHTML(deal.documentUrl || '').replace(/^\/+/, '')}" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit; border-bottom: 1px dotted var(--tg-df-text-muted);">${this.escapeHTML(deal.authorName)}${_a}${_strong}                                ${deal.authorRole && !['null', 'nul', 'undefined'].includes(String(deal.authorRole).toLowerCase()) ? ` • ${this.escapeHTML(deal.authorRole)}` : ''}                                ${deal.modifiedDate ? `\x3Cspan style="color: var(--tg-df-text-muted);"> • ${getTimeAgo(deal.modifiedDate)}${_span}` : ''}                             ${_div}                          ${_div}                       ${_div}                    ${_div}                    ` : ''}                    ${priceGroupHtml}                  ${_div}                ${_div}                \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" class="tg-df-card-cta" style="text-decoration: none; border-radius: 0;">${ctaText}${_a}              ${_div}            `;                        return htmlOutput;            } catch (e) {               console.log("Error rendering deal in map for index", index, typeof deal === 'object' ? JSON.stringify(deal) : deal, "MSG:", e.message);               return '';            }          }).join('');                    if (displayDeals.length > this.displayLimit) {            dealsHtml += `              \x3Cdiv style="width: 100%; display: flex; justify-content: center; margin-top: 16px; grid-column: 1 / -1;">                \x3Cbutton type="button" class="tg-df-tag-outline tg-df-load-more" style="padding: 8px 24px; border-radius: 100px; font-weight: 600; font-size: 14px; cursor: pointer;">Load More${_button}              ${_div}            `;          }                    this.grid.innerHTML = dealsHtml;          // Inject JSON-LD          try {            let targetNode = this.hostContainer || document.head;            let jsonLdScript = targetNode.querySelector('#tg-df-json-ld-' + this.widgetId);            if (!jsonLdScript) {                jsonLdScript = document.createElement('script');                jsonLdScript.type = 'application/ld+json';                jsonLdScript.id = 'tg-df-json-ld-' + this.widgetId;                targetNode.appendChild(jsonLdScript);            }            const jsonLdData = {              "@context": "https://schema.org",              "@type": "ItemList",              "itemListElement": displayDeals.slice(0, this.displayLimit).map((deal, index) => {                 let isoCurrency = "USD";                 if (deal.currency === '£') isoCurrency = "GBP";                 else if (deal.currency === '€') isoCurrency = "EUR";                 else if (deal.currency === 'A$') isoCurrency = "AUD";                 else if (deal.currency === 'CA$') isoCurrency = "CAD";                 const areaCode = typeof this.getAreaCode === 'function' ? this.getAreaCode() : 'US';                 const revenueId = typeof generateRevenueId === 'function' ? generateRevenueId(deal.url, deal.title, deal.merchant, null) : '';                 const rewrittenLink = typeof rewriteAffiliateLink === 'function' ? rewriteAffiliateLink(deal.url, areaCode, revenueId) : deal.url;                 return {                   "@type": "ListItem",                   "position": index + 1,                   "item": {                     "@type": "Product",                     "name": deal.title,                     "image": deal.image || "",                     "description": deal.description || "",                     "brand": {                       "@type": "Brand",                       "name": deal.brand || ""                     },                     "offers": {                       "@type": "Offer",                       "priceCurrency": isoCurrency,                       "price": deal.rawPrice || 0,                       "url": rewrittenLink,                       "seller": {                         "@type": "Organization",                         "name": deal.merchant || ""                       }                     }                   }                 };              }).filter(item => item.item.name)            };            jsonLdScript.textContent = JSON.stringify(jsonLdData);          } catch(e) { console.warn("JSON-LD generation failed", e); }          setTimeout(() => {            const contents = this.root.querySelectorAll('.tg-df-card-desc-content');            contents.forEach(p => {              if (p.scrollHeight > p.clientHeight || p.scrollHeight > 60) {                if (p.nextElementSibling) {                  p.nextElementSibling.style.display = 'block';                }              }            });                        // Allow hawklinks.js to discover and rewrite our widget links             // by appending the .article-body class and manually triggering processArticle.            let container = this.root.classList.contains('tg-df-container') ? this.root : this.root.querySelector('.tg-df-container');            if (container && !container.classList.contains('article-body')) {               container.classList.add('article-body');            }            if (this.grid && !this.grid.classList.contains('article-body')) this.grid.classList.add('article-body');            document.dispatchEvent(new CustomEvent('processArticle', { detail: { element: this.root } }));          }, 50);          const loadMoreBtn = this.grid.querySelector('.tg-df-load-more');          if (loadMoreBtn) {            loadMoreBtn.addEventListener('click', () => {              if (typeof trackElementInteraction === 'function') {                trackElementInteraction({ id: 'load-more', name: 'Load more', label: 'Load More Results' });              }              this.displayLimit += this.getRowsLimit();              this.render();            });          }                      this.bindCouponButtons();            this.checkAndUpdateCoupons();          } catch(e) {            console.warn("Widget render error", e);          }        }                async checkAndUpdateCoupons() {          const wrappers = Array.from(this.root.querySelectorAll('.tg-df-coupon-wrapper'));          if (wrappers.length === 0) return;                    const merchants = [...new Set(wrappers.map(w => w.getAttribute('data-merchant')).filter(Boolean))];          if (merchants.length === 0) return;          const couponResultsMap = await this.checkMerchantsCouponsBulk(merchants);                    for (const merchant of merchants) {            const hasCoupons = !!couponResultsMap[merchant];            const merchantWrappers = wrappers.filter(w => w.getAttribute('data-merchant') === merchant);            merchantWrappers.forEach(wrapper => {              const spinner = wrapper.querySelector('.tg-df-coupon-spinner');              const btn = wrapper.querySelector('.tg-df-tag-coupons');                            if (spinner) spinner.style.display = 'none';                            if (hasCoupons && btn) {                btn.style.display = 'inline-flex';              } else if (!hasCoupons) {                wrapper.style.display = 'none';              }            });          }        }        updateFloatingCopyBar() {          if (!this.editorBar || !this.editorSelectedCount) return;          if (this.editorMode && this.selectedDeals.size > 0) {            this.editorBar.style.display = 'flex';            this.editorSelectedCount.innerText = this.selectedDeals.size;          } else {            this.editorBar.style.display = 'none';          }        }        async copySelectedDealsToCMS() {           function htmlToSlate(htmlString) {              if (!htmlString) return [{ type: 'paragraph', children: [{ text: '' }] }];              let doc;              if (typeof window !== 'undefined' && window.DOMParser) {                 doc = new DOMParser().parseFromString(htmlString, 'text/html');              } else {                 doc = document.implementation.createHTMLDocument('');                 doc.body.innerHTML = htmlString;              }                            function parseNode(node, marks = {}) {                  if (node.nodeType === 3) {                      const text = node.textContent;                      if (!text) return null;                      return { text: text, ...marks };                  }                  if (node.nodeType === 1) {                      const tagName = node.tagName.toLowerCase();                      if (tagName === 'br') {                          return { type: 'line-break', children: [{ text: '' }] };                      }                      if (tagName === 'p') {                          let children = Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                          if (children.length === 0) children.push({ text: "" });                          return { type: 'paragraph', children };                      }                      if (tagName === 'strong' || tagName === 'b') {                          const newMarks = { ...marks, bold: true };                          return Array.from(node.childNodes).map(child => parseNode(child, newMarks)).flat().filter(Boolean);                      }                      if (tagName === 'em' || tagName === 'i') {                          const newMarks = { ...marks, italic: true };                          return Array.from(node.childNodes).map(child => parseNode(child, newMarks)).flat().filter(Boolean);                      }                      if (tagName === 'a') {                          const href = node.getAttribute('href') || '';                          let children = Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                          if (children.length === 0) children.push({ text: "" });                          return {                              type: 'link',                              url: href,                              isNoFollow: (node.getAttribute('rel') || '').includes('nofollow'),                              isSponsored: (node.getAttribute('rel') || '').includes('sponsored'),                              isOpenNewTab: node.getAttribute('target') === '_blank',                              isPreventDataRewrite: false,                              children: children                          };                      }                      return Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                  }                  return null;              }                            let blocksArray = [];              let currentParagraphChildren = [];              function flushParagraph() {                  if (currentParagraphChildren.length > 0) {                      blocksArray.push({ type: 'paragraph', children: currentParagraphChildren });                      currentParagraphChildren = [];                  }              }              Array.from(doc.body.childNodes).forEach(node => {                  const parsed = parseNode(node, {});                  const parsedItems = Array.isArray(parsed) ? parsed : (parsed ? [parsed] : []);                  parsedItems.forEach(item => {                      if (item.type === 'paragraph') {                          flushParagraph();                          blocksArray.push(item);                      } else {                          currentParagraphChildren.push(item);                      }                  });              });              flushParagraph();              if (blocksArray.length === 0) {                  blocksArray = [{ type: 'paragraph', children: [{ text: '' }] }];              }              return blocksArray;           }           const blocks = [];                      this.editorCopyBtn.innerHTML = '\x3Cspan class="tg-df-coupon-spinner" style="display:inline-block; margin-right:8px; border-top-color:#fff;">' + '<' + '/span> Copying...';           for (const deal of Array.from(this.selectedDeals.values())) {              const url = deal.url;              const merchant = deal.merchant;              const title = deal.title;              const image = deal.image;              const currentPrice = deal.currency + deal.rawPrice;              const wasPrice = deal.hasWasPrice && deal.rawMsrp > deal.rawPrice ? deal.currency + deal.rawMsrp : '';                            let couponsChildren = [];              try {                  const area = this.getAreaCode();                  const apiUrl = new URL('https://search-api.fie.future.net.uk/widget.php');                  apiUrl.searchParams.append('model_name', 'Everything');                  apiUrl.searchParams.append('language', 'en-GB');                  apiUrl.searchParams.append('area', area);                  apiUrl.searchParams.append('combine_product_types', '1');                  apiUrl.searchParams.append('filter_merchant_name', merchant);                  apiUrl.searchParams.append('all_filters', 'false');                  apiUrl.searchParams.append('exclude_unlabelled', 'false');                  apiUrl.searchParams.append('include_specs', 'false');                  apiUrl.searchParams.append('sort', 'voucher');                  apiUrl.searchParams.append('distinct_merchants', 'natural');                  apiUrl.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');                  apiUrl.searchParams.append('rows', '3');                  apiUrl.searchParams.append('origin', 'widgets-clientside');                                    let res; try { res = await fetch(apiUrl.toString()); } catch (e) { return; }                  if (res.ok) {                      const data = await res.json();                      let offers = [];                      if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {                        offers = data.widget.data.offers;                      } else if (data && data.data && Array.isArray(data.data.offers)) {                        offers = data.data.offers;                      }                                            if (offers.length > 0) {                          couponsChildren.push({ text: "Also check out these coupons: ", bold: true });                          offers.slice(0, 3).forEach((offer, idx) => {                              const actualOffer = offer.offer || offer;                              const offerName = actualOffer.name || actualOffer.title || offer.model_name || offer.title || offer.name || 'Coupon';                              const linkUrl = actualOffer.link || actualOffer.url || actualOffer.offer_link || '#';                              couponsChildren.push({ type: "line-break", children: [{ text: "" }] });                              couponsChildren.push({ text: "🎟️ " });                              couponsChildren.push({                                  type: "link",                                  url: linkUrl,                                  isNoFollow: true,                                  isSponsored: false,                                  isOpenNewTab: true,                                  isPreventDataRewrite: false,                                  children: [{ text: offerName, bold: true }]                              });                          });                      }                  }              } catch (err) {                  console.warn('Failed to fetch coupons for', merchant, err);              }              let descriptionValue = [];              if (deal.text) {                 descriptionValue = htmlToSlate(deal.text);              } else {                 const dealDescriptions = [                   `Don't miss out on this fantastic deal for the ${title}. It is currently available at ${merchant} for a highly competitive price.`,                   `We've spotted an excellent price drop on the ${title}. Grab it now at ${merchant} before it's gone.`,                   `The ${title} is currently seeing a generous discount over at ${merchant}. This is a perfect time to buy if you've been holding out.`,                   `If you're in the market for the ${title}, ${merchant} has just the deal for you.`,                   `Score the ${title} for less at ${merchant} right now. This is a rare chance to save big.`,                   `Upgrade your setup with the ${title}, now available at a stellar price via ${merchant}.`                 ];                 const randomDescription = dealDescriptions[Math.floor(Math.random() * dealDescriptions.length)];                 descriptionValue = [                    { type: "paragraph", children: [{ text: randomDescription }] }                 ];              }                            if (couponsChildren.length > 0) {                 let lastBlock = descriptionValue[descriptionValue.length - 1];                 if (lastBlock && lastBlock.type === 'paragraph') {                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children.push({ text: "Also check out these coupons: ", bold: true });                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children = lastBlock.children.concat(couponsChildren);                 } else {                     descriptionValue.push({                         type: "paragraph",                         children: [                             { type: "line-break", children: [{ text: "" }] },                             { type: "line-break", children: [{ text: "" }] },                             { text: "Also check out these coupons: ", bold: true },                             { type: "line-break", children: [{ text: "" }] },                             ...couponsChildren                         ]                     });                 }              }              function normalizeCurrencyToISO(symbol) {                const map = { '£': 'GBP', '$': 'USD', 'A$': 'AUD', 'CA$': 'CAD', '€': 'EUR' };                return map[symbol] || symbol;              }              const isoCurrency = normalizeCurrencyToISO(deal.currency);              blocks.push({                 id: (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : 'cms-' + Date.now() + Math.random(),                 blockTypeName: "deal",                 excludeFrom: [],                 collapsible: false,                 props: {                    description: {                       value: descriptionValue,                       touched: false,                       validationMessage: ""                    },                    image: {                       value: {                          credit: [{ type: "paragraph", children: [{ text: merchant }] }],                          dateCreated: Date.now(),                          dateModified: Date.now(),                          distribution: [],                          fileSize: 0,                          height: 1000,                          id: deal.id,                          imageRights: "",                          src: image,                          name: title + ".jpg",                          tags: [],                          width: 1000                       },                       touched: false,                       validationMessage: ""                    },                    showDealButton: { value: true, touched: false, validationMessage: "" },                    isPreferredPartner: { value: false, touched: false, validationMessage: "" },                    linkHref: { value: url, touched: false, validationMessage: "" },                    linkLabel: { value: "", touched: false, validationMessage: "" },                    linkIsNoFollow: { value: true, touched: false, validationMessage: "" },                    linkIsSponsored: { value: false, touched: false, validationMessage: "" },                    linkIsOpenNewWindow: { value: true, touched: false, validationMessage: "" },                    customPromoFlags: { value: [], touched: false, validationMessage: "" },                    showStarDeal: { value: false, touched: false, validationMessage: "" },                    savingType: { value: "none", touched: false, validationMessage: "" },                    starDealPromoFlag: { value: "", touched: false, validationMessage: "" },                    showEditorsChoice: { value: false, touched: false, validationMessage: "" },                    editorsChoiceTitle: { value: "", touched: false, validationMessage: "" },                    hawkPriceCurrency: { value: { value: isoCurrency, label: isoCurrency }, touched: false, validationMessage: "" },                    hawkPrice: { value: deal.hasWasPrice ? String(deal.rawMsrp) : String(deal.rawPrice), touched: false, validationMessage: "" },                    hawkSalePrice: { value: String(deal.rawPrice), touched: false, validationMessage: "" },                    lastCheckedPriceDate: { value: "", touched: false, validationMessage: "" },                    hawkModel: { touched: false, validationMessage: "" },                    productId: { value: "", touched: false, validationMessage: "" },                    voucherId: { value: "", touched: false, validationMessage: "" },                    brand: { value: deal.brand || merchant, touched: false, validationMessage: "" },                    productName: { value: title, touched: false, validationMessage: "" },                    label: { value: "", touched: false, validationMessage: "" },                    retailer: { value: merchant, touched: false, validationMessage: "" },                    priceCheckError: false                 },                 failedFetchError: ""              });           }           const payload = {              type: "articleBuilderPages",              data: blocks           };           const jsonStr = JSON.stringify(payload);                      if (navigator.clipboard && navigator.clipboard.writeText) {              navigator.clipboard.writeText(jsonStr).then(() => {                 this.editorCopyBtn.innerHTML = 'Copied!';                 setTimeout(() => {                    this.editorCopyBtn.innerHTML = '\x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2"><' + '/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"><' + '/path><' + '/svg> Copy to CMS';                 }, 2000);              }).catch(err => {                 console.warn('Failed to copy text: ', err);                 alert('Failed to copy deals to clipboard. See console.');              });           } else {              // Fallback              const textArea = document.createElement("textarea");              textArea.value = jsonStr;              document.body.appendChild(textArea);              textArea.focus();              textArea.select();              try {                 document.execCommand('copy');                 this.editorCopyBtn.innerHTML = 'Copied!';                 setTimeout(() => {                    this.editorCopyBtn.innerHTML = '\x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2"><' + '/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"><' + '/path><' + '/svg> Copy to CMS';                 }, 2000);              } catch (err) {                 console.warn('Fallback: Oops, unable to copy', err);                 alert('Fallback: Failed to copy deals to clipboard.');              }              document.body.removeChild(textArea);           }        }      }      // Initialize the Widget      if (document.readyState === 'loading') {        document.addEventListener('DOMContentLoaded', () => new DealsFinderWidget({ rootId: 'signal-deals-finder-root', rootNode: shadowRoot, hostContainer: hostContainer }));      } else {        new DealsFinderWidget({ rootId: 'signal-deals-finder-root', rootNode: shadowRoot, hostContainer: hostContainer });      }    })();  </script></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ iPhone 18 Pro teardown reveals the ins and outs of the latest iPhone models — including one annoying repair issue ]]></title>
                                                                                                <dc:content><![CDATA[ <p>The <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro and iPhone 18 Pro Max</a> are out in the world, and that means we’re starting to hear about all the things Apple didn’t tell us about. The teardown specialists at iFixit have already revealed how large the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-battery-size-just-revealed-heres-the-official-capacity-from-ifixits-teardown">batteries are inside the eSIM-only models that are on sale in the U.S</a>. But what other secrets are hiding inside? </p><p>Here's what was uncovered when <a href="https://www.ifixit.com/News/119329/inside-the-tiny-unfixable-eye-iphone-18-pro-and-pro-max-teardown" target="_blank">iFixit popped open the iPhone 18 Pro and the iPhone 18 Pro Max.</a></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/oS_HMre7vk0" allowfullscreen></iframe></div></div><h2 id="the-ins-and-outs-of-variable-aperture">The ins and outs of variable aperture</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:55.90%;"><img id="wU9sfgNVT4TH522q8ZXj7A" name="Screenshot 2026-09-21 114542" alt="iphone 18 pro teardowns" src="https://cdn.mos.cms.futurecdn.net/wU9sfgNVT4TH522q8ZXj7A-1920-80.png" mos="" align="middle" fullscreen="" width="2560" height="1431" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: iFixit)</span></figcaption></figure><p>One of the biggest upgrades in the iPhone 18 Pro and Pro Max is the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-variable-aperture-camera-explained-heres-what-it-actually-does">variable aperture camera lens</a>, which lets you adjust how much light actually makes it through the camera lens. It’s a feature that a lot of people have raved about, though iFixit simply calls it “a nice gimmick.”</p><p>Why a gimmick? Because the site questions the feature's validity altogether, given how iPhone cameras actually work. The camera sensors are a little over half an inch in size, which limits the potential to let more light inside the camera in the first place. The short focal length of the lens already ensures most of your photo is kept in focus, while depth of field effects, including bokeh, have been software-based for a long time.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.09%;"><img id="dkKfidRas85VkHaGwxbsH9" name="Screenshot 2026-09-21 114658" alt="iphone 18 pro teardowns" src="https://cdn.mos.cms.futurecdn.net/dkKfidRas85VkHaGwxbsH9-1920-80.png" mos="" align="middle" fullscreen="" width="2560" height="1436" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: iFixit)</span></figcaption></figure><p>Most crucially, though, is the fact that the variable aperture blades offer a brand new place for iPhone cameras to fail. More moving parts mean more things that can break, as users reported in the past on other variable aperture-capable phones like the <a href="https://www.tomsguide.com/us/galaxy-s9-photo-samples,news-26696.html">Samsung Galaxy S9</a>. This means that the ability to fix those blades is crucial, and apart from some issues with the screen reaching the camera, it isn’t that difficult.</p><p>However, any issues with the aperture blades will likely require a full replacement of the camera assembly — which isn’t going to be cheap. Apple’s official spare parts store sells<a href="https://www.tomsguide.com/phones/iphones/apple-iphone-17-pro-review"> iPhone 17 Pro</a> cameras for $250, and the addition of variable aperture isn’t likely to make a replacement iPhone 18 Pro camera any less expensive.</p><p>Sadly, replacing the aperture alone isn’t going to be possible. Getting inside the main lens is a complicated process, and putting everything back together again afterward straight isn’t going to happen. Better hope Apple’s reputation for quality control doesn't fail when it comes to those blades. </p><p>That said, if the issue is with the blades being stuck, and you can live without them, iFixit did spot that the blades can be controlled with an external magnet. That hopefully means stuck aperture blades don’t necessarily mean a broken camera system.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-eGby2X"></div>                            </div>                            <script src="https://kwizly.com/embed/eGby2X.js" async></script><h2 id="what-other-changes-are-involved">What other changes are involved?</h2><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.41%;"><img id="bKHaY66HwUcyTtLLeyF54A" name="Screenshot 2026-09-21 114445" alt="iphone 18 pro teardowns" src="https://cdn.mos.cms.futurecdn.net/bKHaY66HwUcyTtLLeyF54A-1920-80.png" mos="" align="middle" fullscreen="" width="2560" height="1444" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: iFixit)</span></figcaption></figure><p>The iPhone 18 Pro and Pro Max don’t quite make Face ID a true under-display system, but it has moved the facial recognition hardware around in order to make the Dynamic Island slightly smaller. This includes moving the infrared camera from the center of the screen to the left-hand side, with a punch hole in the under-screen frame and allowing the IR camera to hide out of sight.</p><p>How does the IR light come through the screen? Inspection with a microscope shows that every other pixel over that holepunch is missing. This allows IR light to pass through without requiring a noticeable break in the display itself.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.17%;"><img id="DZQgRPP4gBN78cgQ2Nfet9" name="Screenshot 2026-09-21 114730" alt="iphone 18 pro teardowns" src="https://cdn.mos.cms.futurecdn.net/DZQgRPP4gBN78cgQ2Nfet9-1920-80.png" mos="" align="middle" fullscreen="" width="2560" height="1438" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: iFixit)</span></figcaption></figure><p>The <a href="https://www.tomsguide.com/phones/iphones/apple-a20-pro-chip-why-its-such-a-big-deal-for-the-iphone-ultra-and-iphone-18-pro-max">A20 Pro chip</a> has also been moved to the outside of the logic board, which should help it dissipate heat more easily by giving it a more direct route to the 18 Pro’s active cooling system. Speaking of which, the new vapor chamber looks at least twice as large as the one on the iPhone 17 Pro and spreads across almost the entirety of the phone.</p><p>Curiously, iFixit notices that the U.S. version of the iPhone 18 Pro Max does not use the Apple C2 modem. Instead, it still has a Qualcomm modem, which is likely to use a lot more power. That extra power consumption probably explains why it’s only in the U.S. eSIM variant of the 18 Pro Max, which has the larger 5,567 mAh battery. </p><h2 id="how-easy-is-it-to-repair-the-iphone-18-pro">How easy is it to repair the iPhone 18 Pro?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.09%;"><img id="VAQZedfymk6nbpG6qpVF4A" name="Screenshot 2026-09-21 114404" alt="iphone 18 pro teardowns" src="https://cdn.mos.cms.futurecdn.net/VAQZedfymk6nbpG6qpVF4A-1920-80.png" mos="" align="middle" fullscreen="" width="2560" height="1436" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: iFixit)</span></figcaption></figure><p>Sadly, the back panels in the iPhone 18 Pro and Pro Max don't give you access to much, and fixing anything beyond the wireless charger is going to require you pop off the front screen — a complicated and fiddly process that has a good chance of causing problems.</p><p>In fact, the site opened up four iPhone 18 Pro models and found that removing the front glass broke the white plastic frame on three of them. That frame is a crucial part of the display panel, and it isn’t a part that can be purchased on its own. The broken frame means no water resistance and a screen that won’t ever stay flush against the rest of the device. Ouch.</p><p>The state of that frame is apparently inconsistent across the repair community, with some reporting breakages and others reporting no issues. It’s also been in Pro-tier iPhones since the <a href="https://www.tomsguide.com/reviews/iphone-15-pro">15 Pro</a>, without causing nearly as many problems. Unfortunately, it’s not clear what might have changed this year, or what sort of external factors may have contributed to the repeated problems it faced. This means more testing is needed.</p><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.41%;"><img id="bKHaY66HwUcyTtLLeyF54A" name="Screenshot 2026-09-21 114445" alt="iphone 18 pro teardowns" src="https://cdn.mos.cms.futurecdn.net/bKHaY66HwUcyTtLLeyF54A-1920-80.png" mos="" align="middle" fullscreen="" width="2560" height="1444" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: iFixit)</span></figcaption></figure><p>As for a battery repair, Apple has refrained from using any glue. Instead, the power pack is held in place by 13 different screws, and as much of a pain as it is to unscrew 13 tiny screws, it’s better than the alternative. The battery is still stuck to its tray with Apple’s special ionic adhesive, which disconnects when subjected to a 12V charge, but the tray itself is only attached via screws. I’ll be curious to see what the price difference is for replacement batteries with the tray and those without.</p><p>The USB-C port isn’t so lucky. While technically a modular component, the sheer amount of glue and screws involved in removing the board means it’s going to be a pain in the butt to remove and replace. Which is weird, with iFixit notes that the iPhone 16 Pro actually solved this issue two years ago. But sadly, port replacement has long been an issue with iPhones.</p><p>iFixit has complimented Apple’s repair support, particularly the availability of Apple’s thorough repair manuals. iPhone 18 Pro parts aren’t available yet, but they should be arriving in the near future, with the repair assistant tool all but eliminating the parts-pairing woes of the past.</p><p>iFixit has given the 18 Pro and Pro Max a provisional repair score of seven out of ten, with the score taking a hit on account of all major repairs having to go down through the screen. iFixit notes that the damaged frames haven’t been taken into consideration yet, simply because there are too many unknowns about why the white plastic has broken so easily. </p><p>However, the score itself isn’t going to be finalized just yet, at least not until Apple releases spare parts and iFixit can do more parts-pairing tests of its own.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/i-spent-30-minutes-with-the-iphone-duo-3-things-you-just-dont-get-from-the-pictures">I spent 30 minutes with the iPhone Duo — 3 things you just don’t get from the pictures</a></li><li><a href="https://www.tomsguide.com/phones/i-put-the-iphone-18-pro-max-vs-galaxy-s26-ultra">I put the iPhone 18 Pro Max vs. Galaxy S26 Ultra through a 7-round face-off — here’s the winner</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-iphone-18-pro-your-10-biggest-questions-answered">I've been testing the iPhone 18 Pro Max and iPhone 18 Pro — your 10 biggest questions answered</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/iphone-18-pro-teardown-reveals-the-ins-and-outs-of-the-latest-iphone-models-including-one-annoying-repair-issue</link>
                                                                            <description>
                            <![CDATA[ All your repairs have to go through the screen — and don't even think about replacing variable aperture blades ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">kgdfbnxp9PdZPagU9hHgcj</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/ikngBPdhzFZLTfupTVcdi8-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 21 Sep 2026 11:21:44 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ tom.pritchard@futurenet.com (Tom Pritchard) ]]></author>                    <dc:creator><![CDATA[ Tom Pritchard ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/biCewUkKfSA6QnT2HxVc3f-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/ikngBPdhzFZLTfupTVcdi8-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 18 Pro shown in hand]]></media:description>                                                            <media:text><![CDATA[iPhone 18 Pro shown in hand]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 18 Pro shown in hand]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/ikngBPdhzFZLTfupTVcdi8-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro and iPhone 18 Pro Max</a> are out in the world, and that means we’re starting to hear about all the things Apple didn’t tell us about. The teardown specialists at iFixit have already revealed how large the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-battery-size-just-revealed-heres-the-official-capacity-from-ifixits-teardown">batteries are inside the eSIM-only models that are on sale in the U.S</a>. But what other secrets are hiding inside? </p><p>Here's what was uncovered when <a href="https://www.ifixit.com/News/119329/inside-the-tiny-unfixable-eye-iphone-18-pro-and-pro-max-teardown" target="_blank">iFixit popped open the iPhone 18 Pro and the iPhone 18 Pro Max.</a></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/oS_HMre7vk0" allowfullscreen></iframe></div></div><h2 id="the-ins-and-outs-of-variable-aperture">The ins and outs of variable aperture</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:55.90%;"><img id="wU9sfgNVT4TH522q8ZXj7A" name="Screenshot 2026-09-21 114542" alt="iphone 18 pro teardowns" src="https://cdn.mos.cms.futurecdn.net/wU9sfgNVT4TH522q8ZXj7A-1920-80.png" mos="" align="middle" fullscreen="" width="2560" height="1431" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: iFixit)</span></figcaption></figure><p>One of the biggest upgrades in the iPhone 18 Pro and Pro Max is the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-variable-aperture-camera-explained-heres-what-it-actually-does">variable aperture camera lens</a>, which lets you adjust how much light actually makes it through the camera lens. It’s a feature that a lot of people have raved about, though iFixit simply calls it “a nice gimmick.”</p><p>Why a gimmick? Because the site questions the feature's validity altogether, given how iPhone cameras actually work. The camera sensors are a little over half an inch in size, which limits the potential to let more light inside the camera in the first place. The short focal length of the lens already ensures most of your photo is kept in focus, while depth of field effects, including bokeh, have been software-based for a long time.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.09%;"><img id="dkKfidRas85VkHaGwxbsH9" name="Screenshot 2026-09-21 114658" alt="iphone 18 pro teardowns" src="https://cdn.mos.cms.futurecdn.net/dkKfidRas85VkHaGwxbsH9-1920-80.png" mos="" align="middle" fullscreen="" width="2560" height="1436" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: iFixit)</span></figcaption></figure><p>Most crucially, though, is the fact that the variable aperture blades offer a brand new place for iPhone cameras to fail. More moving parts mean more things that can break, as users reported in the past on other variable aperture-capable phones like the <a href="https://www.tomsguide.com/us/galaxy-s9-photo-samples,news-26696.html">Samsung Galaxy S9</a>. This means that the ability to fix those blades is crucial, and apart from some issues with the screen reaching the camera, it isn’t that difficult.</p><p>However, any issues with the aperture blades will likely require a full replacement of the camera assembly — which isn’t going to be cheap. Apple’s official spare parts store sells<a href="https://www.tomsguide.com/phones/iphones/apple-iphone-17-pro-review"> iPhone 17 Pro</a> cameras for $250, and the addition of variable aperture isn’t likely to make a replacement iPhone 18 Pro camera any less expensive.</p><p>Sadly, replacing the aperture alone isn’t going to be possible. Getting inside the main lens is a complicated process, and putting everything back together again afterward straight isn’t going to happen. Better hope Apple’s reputation for quality control doesn't fail when it comes to those blades. </p><p>That said, if the issue is with the blades being stuck, and you can live without them, iFixit did spot that the blades can be controlled with an external magnet. That hopefully means stuck aperture blades don’t necessarily mean a broken camera system.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-eGby2X"></div>                            </div>                            <script src="https://kwizly.com/embed/eGby2X.js" async></script><h2 id="what-other-changes-are-involved">What other changes are involved?</h2><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.41%;"><img id="bKHaY66HwUcyTtLLeyF54A" name="Screenshot 2026-09-21 114445" alt="iphone 18 pro teardowns" src="https://cdn.mos.cms.futurecdn.net/bKHaY66HwUcyTtLLeyF54A-1920-80.png" mos="" align="middle" fullscreen="" width="2560" height="1444" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: iFixit)</span></figcaption></figure><p>The iPhone 18 Pro and Pro Max don’t quite make Face ID a true under-display system, but it has moved the facial recognition hardware around in order to make the Dynamic Island slightly smaller. This includes moving the infrared camera from the center of the screen to the left-hand side, with a punch hole in the under-screen frame and allowing the IR camera to hide out of sight.</p><p>How does the IR light come through the screen? Inspection with a microscope shows that every other pixel over that holepunch is missing. This allows IR light to pass through without requiring a noticeable break in the display itself.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.17%;"><img id="DZQgRPP4gBN78cgQ2Nfet9" name="Screenshot 2026-09-21 114730" alt="iphone 18 pro teardowns" src="https://cdn.mos.cms.futurecdn.net/DZQgRPP4gBN78cgQ2Nfet9-1920-80.png" mos="" align="middle" fullscreen="" width="2560" height="1438" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: iFixit)</span></figcaption></figure><p>The <a href="https://www.tomsguide.com/phones/iphones/apple-a20-pro-chip-why-its-such-a-big-deal-for-the-iphone-ultra-and-iphone-18-pro-max">A20 Pro chip</a> has also been moved to the outside of the logic board, which should help it dissipate heat more easily by giving it a more direct route to the 18 Pro’s active cooling system. Speaking of which, the new vapor chamber looks at least twice as large as the one on the iPhone 17 Pro and spreads across almost the entirety of the phone.</p><p>Curiously, iFixit notices that the U.S. version of the iPhone 18 Pro Max does not use the Apple C2 modem. Instead, it still has a Qualcomm modem, which is likely to use a lot more power. That extra power consumption probably explains why it’s only in the U.S. eSIM variant of the 18 Pro Max, which has the larger 5,567 mAh battery. </p><h2 id="how-easy-is-it-to-repair-the-iphone-18-pro">How easy is it to repair the iPhone 18 Pro?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.09%;"><img id="VAQZedfymk6nbpG6qpVF4A" name="Screenshot 2026-09-21 114404" alt="iphone 18 pro teardowns" src="https://cdn.mos.cms.futurecdn.net/VAQZedfymk6nbpG6qpVF4A-1920-80.png" mos="" align="middle" fullscreen="" width="2560" height="1436" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: iFixit)</span></figcaption></figure><p>Sadly, the back panels in the iPhone 18 Pro and Pro Max don't give you access to much, and fixing anything beyond the wireless charger is going to require you pop off the front screen — a complicated and fiddly process that has a good chance of causing problems.</p><p>In fact, the site opened up four iPhone 18 Pro models and found that removing the front glass broke the white plastic frame on three of them. That frame is a crucial part of the display panel, and it isn’t a part that can be purchased on its own. The broken frame means no water resistance and a screen that won’t ever stay flush against the rest of the device. Ouch.</p><p>The state of that frame is apparently inconsistent across the repair community, with some reporting breakages and others reporting no issues. It’s also been in Pro-tier iPhones since the <a href="https://www.tomsguide.com/reviews/iphone-15-pro">15 Pro</a>, without causing nearly as many problems. Unfortunately, it’s not clear what might have changed this year, or what sort of external factors may have contributed to the repeated problems it faced. This means more testing is needed.</p><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.41%;"><img id="bKHaY66HwUcyTtLLeyF54A" name="Screenshot 2026-09-21 114445" alt="iphone 18 pro teardowns" src="https://cdn.mos.cms.futurecdn.net/bKHaY66HwUcyTtLLeyF54A-1920-80.png" mos="" align="middle" fullscreen="" width="2560" height="1444" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: iFixit)</span></figcaption></figure><p>As for a battery repair, Apple has refrained from using any glue. Instead, the power pack is held in place by 13 different screws, and as much of a pain as it is to unscrew 13 tiny screws, it’s better than the alternative. The battery is still stuck to its tray with Apple’s special ionic adhesive, which disconnects when subjected to a 12V charge, but the tray itself is only attached via screws. I’ll be curious to see what the price difference is for replacement batteries with the tray and those without.</p><p>The USB-C port isn’t so lucky. While technically a modular component, the sheer amount of glue and screws involved in removing the board means it’s going to be a pain in the butt to remove and replace. Which is weird, with iFixit notes that the iPhone 16 Pro actually solved this issue two years ago. But sadly, port replacement has long been an issue with iPhones.</p><p>iFixit has complimented Apple’s repair support, particularly the availability of Apple’s thorough repair manuals. iPhone 18 Pro parts aren’t available yet, but they should be arriving in the near future, with the repair assistant tool all but eliminating the parts-pairing woes of the past.</p><p>iFixit has given the 18 Pro and Pro Max a provisional repair score of seven out of ten, with the score taking a hit on account of all major repairs having to go down through the screen. iFixit notes that the damaged frames haven’t been taken into consideration yet, simply because there are too many unknowns about why the white plastic has broken so easily. </p><p>However, the score itself isn’t going to be finalized just yet, at least not until Apple releases spare parts and iFixit can do more parts-pairing tests of its own.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/i-spent-30-minutes-with-the-iphone-duo-3-things-you-just-dont-get-from-the-pictures">I spent 30 minutes with the iPhone Duo — 3 things you just don’t get from the pictures</a></li><li><a href="https://www.tomsguide.com/phones/i-put-the-iphone-18-pro-max-vs-galaxy-s26-ultra">I put the iPhone 18 Pro Max vs. Galaxy S26 Ultra through a 7-round face-off — here’s the winner</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-iphone-18-pro-your-10-biggest-questions-answered">I've been testing the iPhone 18 Pro Max and iPhone 18 Pro — your 10 biggest questions answered</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Apple's $250 million class action settlement website is now open — here's how eligible iPhone owners can file a claim and how much they'll get ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Apple elected to settle <a href="https://www.tomsguide.com/phones/iphones/apple-agrees-usd250m-settlement-over-siri-class-action-lawsuit-that-means-up-to-36m-iphone-users-could-be-eligible-for-a-pay-out-this-is-how-much-you-could-receive">a $250 million class action lawsuit back in May</a> that means up to 36 million iPhone owners are eligible for a payout of up to $95 per device. The lawsuit alleged Apple misled customers with false advertising over the arrival of Siri AI and Apple Intelligence.</p><p>Apple denied any wrongdoing, but did decide to settle the lawsuit to resolve the claims swiftly. In a statement, it said this meant it could "stay focused" on "delivering the most innovative products and services to our users."</p><p>The settlement allowed each eligible person who filed a claim to receive a per-device payment of $25, which could increase up to $95 depending on the claim volume.</p><section class="howto-block">                    <h3>Are you eligible?</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/DfjRJhDZNxBTaA5HnSYXzM.jpg"                                        alt="iPhone 15 Pro Max in hand "                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/DfjRJhDZNxBTaA5HnSYXzM.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Future)</div></figure>                    <p><p>The <a href="https://www.courtlistener.com/docket/69759747/79/landsheft-v-apple-inc/" target="_blank">settlement</a> covers about 36 million devices, including most of the <a href="https://www.tomsguide.com/us/best-apple-iphone,review-6348.html">best iPhones</a>. But in order to submit a claim, <strong>you must reside in the United States</strong> and have <strong>purchased one of the affected models for purposes other than resale between June 10, 2024 and March 29, 2025</strong>.</p></p>                </section><section class="howto-block">                    <h3>Which iPhone models are eligible?</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/NppQwHbpWx8HMgt5YJRe9.jpg"                                        alt="iPhone 16 Pro vs iPhone 16 Pro Max in hand showing displays"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/NppQwHbpWx8HMgt5YJRe9.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Future)</div></figure>                    <p><p>The full list of eligible iPhone models includes:</p><ul><li>iPhone 15 Pro</li><li>iPhone 15 Pro Max</li><li><a href="https://www.tomsguide.com/phones/iphones/apple-iphone-16-review">iPhone 16</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-16e-just-announced-specs-release-date-and-surprisingly-high-price">iPhone 16e</a></li><li>iPhone 16 Plus</li><li><a href="https://www.tomsguide.com/phones/iphones/apple-iphone-16-pro-review">iPhone 16 Pro</a></li><li><a href="https://www.tomsguide.com/phones/iphones/apple-iphone-16-pro-max-review">iPhone 16 Pro Max</a></li></ul></p>                </section><section class="howto-block">                    <h3>How do I claim?</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/AFwjWBtTjiru8PAQgLdDX7.jpg"                                        alt="Apple Store with white Apple logo "                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/AFwjWBtTjiru8PAQgLdDX7.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Shutterstock)</div></figure>                    <p><p>Over the next few days, <strong>eligible customers will be notified about the settlement via email</strong>. The email should contain a claim ID and a PIN code allowing you to <strong>fill out a form that will ask you for personal information as well as the serial number of the eligible iPhone. </strong></p><p>If you don't have the serial number of the iPhone, you will need to <strong>supply your Apple Account email as well as the device's phone number</strong>.</p><p>Alternatively, <a href="https://aplsconnect.com/smartphoneaisettlement/" target="_blank"><strong>the settlement website is now live</strong></a><strong> for you to proactively file a claim without the above information</strong>. The window for submitting a claim runs from today, <strong>September 21 until December 21, 2026</strong>.  </p></p>                </section><section class="howto-block">                    <h3>How much will I get and when will I receive it?</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/gu28huKNHn4cg4NDY2Gue.jpg"                                        alt="iPhone 16 Pro vs iPhone 16 Pro Max in one hand "                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/gu28huKNHn4cg4NDY2Gue.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Future)</div></figure>                    <p><p>Each person who files an eligible claim will <strong>receive a per-device payment of $25</strong>. This could increase up to a maximum of $95, depending on how many people file a claim while the settlement window is open. If it's lower than expected, there is more chance of receiving a higher payout.</p><p>The final approval hearing is taking place on February 24, 2027, which means <strong>payments are unlikely to be made to customers until later next year</strong>.</p></p>                </section><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XZq6YO"></div>                            </div>                            <script src="https://kwizly.com/embed/XZq6YO.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/phones/iphones/iphone-18-pro-max-and-iphone-18-pro-your-10-biggest-questions-answered">I've been testing the iPhone 18 Pro Max and iPhone 18 Pro — your 10 biggest questions answered</a></li><li><a href="https://www.tomsguide.com/phones/iphones/apple-added-5-new-lock-screen-tools-in-ios-27-heres-what-to-change-first">Apple added 5 new lock screen tools in iOS 27 — here's what to change first</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-spent-30-minutes-with-the-iphone-duo-3-things-you-just-dont-get-from-the-pictures">I spent 30 minutes with the iPhone Duo — 3 things you just don’t get from the pictures</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/apples-usd250-million-class-action-settlement-website-is-now-open-heres-how-eligible-iphone-owners-can-file-a-claim-and-how-much-theyll-get</link>
                                                                            <description>
                            <![CDATA[ Apple settled a class action lawsuit for $250 million earlier this year over Siri AI and now eligible iPhone owners can claim their payout. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">nq9MCeUhyZg49XiMcPtByh</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/zfqhHJwLq6gXDG26NbSkVR-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 21 Sep 2026 11:11:34 +0000</pubDate>                                                                                                                                <updated>Tue, 22 Sep 2026 14:20:17 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[AI]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ jeff.parsons@futurenet.com (Jeff Parsons) ]]></author>                    <dc:creator><![CDATA[ Jeff Parsons ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/7z3UTGGrmSokMKxTWHmhjX-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Jeff is U.K. Editor-in-Chief for Tom’s Guide looking after the day-to-day output of the site’s British contingent. &lt;/p&gt;&lt;p&gt;Rising early and heading straight for the coffee machine, Jeff loves nothing more than dialling into the zeitgeist of the day’s tech news. A journalist for over a decade, he&#039;s travelled around the world testing and reviewing any gadget he can get his hands on.&lt;/p&gt;&lt;p&gt;Before joining the team at Tom’s Guide, Jeff covered technology and science for two of the U.K.’s biggest national news sites: Metro.co.uk and the Daily Mirror. Memorable moments include getting lost in Vienna in an electric Audi, touring Lockheed Martin’s mile-long jet factory in Fort Worth and filming a Netflix documentary about Elon Musk in West London.&lt;/p&gt;&lt;p&gt;When not plugged into the current news agenda, editing or commissioning a series of articles or debating the merits of Apple vs Android, Jeff can usually be found out for a run trying to shave precious seconds off his PB. Or lifting weights in a vain attempt to offset the ageing process.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/zfqhHJwLq6gXDG26NbSkVR-1920-80.jpg">
                                                            <media:credit><![CDATA[Getty Images]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Apple logo on Apple Store ]]></media:description>                                                            <media:text><![CDATA[Apple logo on Apple Store ]]></media:text>
                                <media:title type="plain"><![CDATA[Apple logo on Apple Store ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/zfqhHJwLq6gXDG26NbSkVR-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Apple elected to settle <a href="https://www.tomsguide.com/phones/iphones/apple-agrees-usd250m-settlement-over-siri-class-action-lawsuit-that-means-up-to-36m-iphone-users-could-be-eligible-for-a-pay-out-this-is-how-much-you-could-receive">a $250 million class action lawsuit back in May</a> that means up to 36 million iPhone owners are eligible for a payout of up to $95 per device. The lawsuit alleged Apple misled customers with false advertising over the arrival of Siri AI and Apple Intelligence.</p><p>Apple denied any wrongdoing, but did decide to settle the lawsuit to resolve the claims swiftly. In a statement, it said this meant it could "stay focused" on "delivering the most innovative products and services to our users."</p><p>The settlement allowed each eligible person who filed a claim to receive a per-device payment of $25, which could increase up to $95 depending on the claim volume.</p><section class="howto-block">                    <h3>Are you eligible?</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/DfjRJhDZNxBTaA5HnSYXzM.jpg"                                        alt="iPhone 15 Pro Max in hand "                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/DfjRJhDZNxBTaA5HnSYXzM.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Future)</div></figure>                    <p><p>The <a href="https://www.courtlistener.com/docket/69759747/79/landsheft-v-apple-inc/" target="_blank">settlement</a> covers about 36 million devices, including most of the <a href="https://www.tomsguide.com/us/best-apple-iphone,review-6348.html">best iPhones</a>. But in order to submit a claim, <strong>you must reside in the United States</strong> and have <strong>purchased one of the affected models for purposes other than resale between June 10, 2024 and March 29, 2025</strong>.</p></p>                </section><section class="howto-block">                    <h3>Which iPhone models are eligible?</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/NppQwHbpWx8HMgt5YJRe9.jpg"                                        alt="iPhone 16 Pro vs iPhone 16 Pro Max in hand showing displays"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/NppQwHbpWx8HMgt5YJRe9.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Future)</div></figure>                    <p><p>The full list of eligible iPhone models includes:</p><ul><li>iPhone 15 Pro</li><li>iPhone 15 Pro Max</li><li><a href="https://www.tomsguide.com/phones/iphones/apple-iphone-16-review">iPhone 16</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-16e-just-announced-specs-release-date-and-surprisingly-high-price">iPhone 16e</a></li><li>iPhone 16 Plus</li><li><a href="https://www.tomsguide.com/phones/iphones/apple-iphone-16-pro-review">iPhone 16 Pro</a></li><li><a href="https://www.tomsguide.com/phones/iphones/apple-iphone-16-pro-max-review">iPhone 16 Pro Max</a></li></ul></p>                </section><section class="howto-block">                    <h3>How do I claim?</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/AFwjWBtTjiru8PAQgLdDX7.jpg"                                        alt="Apple Store with white Apple logo "                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/AFwjWBtTjiru8PAQgLdDX7.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Shutterstock)</div></figure>                    <p><p>Over the next few days, <strong>eligible customers will be notified about the settlement via email</strong>. The email should contain a claim ID and a PIN code allowing you to <strong>fill out a form that will ask you for personal information as well as the serial number of the eligible iPhone. </strong></p><p>If you don't have the serial number of the iPhone, you will need to <strong>supply your Apple Account email as well as the device's phone number</strong>.</p><p>Alternatively, <a href="https://aplsconnect.com/smartphoneaisettlement/" target="_blank"><strong>the settlement website is now live</strong></a><strong> for you to proactively file a claim without the above information</strong>. The window for submitting a claim runs from today, <strong>September 21 until December 21, 2026</strong>.  </p></p>                </section><section class="howto-block">                    <h3>How much will I get and when will I receive it?</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/gu28huKNHn4cg4NDY2Gue.jpg"                                        alt="iPhone 16 Pro vs iPhone 16 Pro Max in one hand "                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/gu28huKNHn4cg4NDY2Gue.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Future)</div></figure>                    <p><p>Each person who files an eligible claim will <strong>receive a per-device payment of $25</strong>. This could increase up to a maximum of $95, depending on how many people file a claim while the settlement window is open. If it's lower than expected, there is more chance of receiving a higher payout.</p><p>The final approval hearing is taking place on February 24, 2027, which means <strong>payments are unlikely to be made to customers until later next year</strong>.</p></p>                </section><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XZq6YO"></div>                            </div>                            <script src="https://kwizly.com/embed/XZq6YO.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/phones/iphones/iphone-18-pro-max-and-iphone-18-pro-your-10-biggest-questions-answered">I've been testing the iPhone 18 Pro Max and iPhone 18 Pro — your 10 biggest questions answered</a></li><li><a href="https://www.tomsguide.com/phones/iphones/apple-added-5-new-lock-screen-tools-in-ios-27-heres-what-to-change-first">Apple added 5 new lock screen tools in iOS 27 — here's what to change first</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-spent-30-minutes-with-the-iphone-duo-3-things-you-just-dont-get-from-the-pictures">I spent 30 minutes with the iPhone Duo — 3 things you just don’t get from the pictures</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I extended my iPhone's telephoto range with this add-on camera lens — and my point-and-shoot camera is officially retired ]]></title>
                                                                                                <dc:content><![CDATA[ <p>For years, I’ve kept a compact point-and-shoot camera in my backpack when I commute to work or go on trips. Part of the reason is that it offers longer telephoto reach, as well as intuitive software with the manual controls I crave. But despite testing an assortment of the <a href="https://www.tomsguide.com/phones/iphones/best-iphone-lenses">best iPhone lenses</a>, none have really felt like a complete shooting solution compelling enough to pry me away from my dedicated camera.</p><p>That changed when I got my hands on the <a href="https://www.telesinstore.com/products/telesin-master-grip-kit-for-iphone-18-pro-series?variant=50462969659640" target="_blank" rel="nofollow">Telesin Master Grip Kit</a>. Rather than treating the telephoto lens as an isolated add-on, it approaches mobile photography as an entire ecosystem — a MagSafe-enabled rig that pairs a lens with an ergonomic grip. It fundamentally changes how I handle the device, and after using it for nearly a month, I can tell you that the difference isn't subtle. Here’s why.</p><h2 id="way-better-telephoto-performance">Way better telephoto performance</h2><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/RypYatXV64w3H6AffAYakR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 40x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/k8KrxqH5CXGsjfi3iaeexW-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/v3XijzdcRCZyBwawnaKiKR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 40x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/cSyRDrYqLY5eFXyBAuSeMW-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/EgH2nH4vK7fMpKTvFWyJRR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 40x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/HjonEFQRjr3JeN9wju5EMW-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/geoFjYw2tYaXTCfVCJprjR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 40x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/6RzDJX2do3nG9YzuTDZ9mW-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/KJFmqays3mVP6PGMj8nTkR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 40x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/9cqEYKst9TdM8yzAyDPgaW-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/SakZVfa495DKRsWAcnLdkR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 40x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/3KUMHqub2bRctBS3wRYigW-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/robGpkHKgYuX7L4NbwWKmR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 40x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/Nr2oXfaGymh2WHbQHTaRyW-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/uu6yXSmjSfkVd96vbmyNnR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 40x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/rULXViKwXemz8Dmze7sj2X-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/R9db5Ea5nddfQGAY9CYprR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 40x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/E79oFzzezWuP79te23d54X-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure></figure><p>I don’t miss the Space Zoom on Samsung’s flagship models now that the Telesin 3.5x lens paired with my <a href="https://www.tomsguide.com/phones/iphones/iphone-17-pro-max-review">iPhone 17 Pro</a> drastically sharpens its telephoto reach. Don’t believe me? Take a look at the side-by-side snapshots above comparing my standalone iPhone 17 Pro at 40x zoom against the Telesin 3.5x setup.</p><p>In the first set of images, the shot from my iPhone leaves the wood grain indistinct and almost smeary, with fine depth flattened by the phone's aggressive image processing. Distant textures simply lack clarity and definition. The results with the Telesin kit offer a stark contrast because every groove of the wood grain is sharp and clearly defined, while natural contrast and dynamic range are preserved.</p><div class="product"><a data-dimension112="912a2bee-b39c-11f1-a6ec-938be7b47f46" data-action="Deal Block" data-label="Master Grip Kit" data-dimension48="Master Grip Kit" data-dimension25="$229.99" href="https://www.telesinstore.com/products/telesin-master-grip-kit-for-iphone-18-pro-series?variant=50462969692408" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="GPZpWomTTTuBWxG5t4xGKa" name="Telesin Master Grip Kit deal block" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/GPZpWomTTTuBWxG5t4xGKa-1920-80.jpg" mos="" align="middle" fullscreen="" width="600" height="600" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>Transform your iPhone into a versatile dedicated camera system with the Telesin Master Grip Kit. It snaps onto your iPhone via MagSafe, offering physical controls and a grip to properly frame shots with ease. With the included telephoto lens, you can pair it with the iPhone's main or telephoto cameras to get more zoom without the artificial look that normally comes with computational photography. Use code <strong>4BU3AHFE  </strong>at checkout for an additional 15% off.<a class="view-deal button" href="https://www.telesinstore.com/products/telesin-master-grip-kit-for-iphone-18-pro-series?variant=50462969692408" target="_blank" rel="nofollow" data-dimension112="912a2bee-b39c-11f1-a6ec-938be7b47f46" data-action="Deal Block" data-label="Master Grip Kit" data-dimension48="Master Grip Kit" data-dimension25="$229.99">View Deal</a></p></div><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/fDsACnb5G3dafXpjfd4yWR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 1x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/8DG6PNtTjPe6HhjsakLEXW-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure></figure><p>This isn't just a minor bump in quality — it proves how dedicated optical glass can salvage distant subjects that's ruined by digital processing. The long-exposure shot above perfectly illustrates this reach, by transforming the distant 9/11 Tribute in Light as two distinctly separated pillars of light when zoomed all the way in with the Telesin lens. The kit delivers the kind of true optical performance that finally lets me leave my dedicated camera behind.</p><h2 id="versatile-grip-and-case">Versatile grip and case</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="7UCQDEYBbznaWF8Nk48q4C" name="Telesin Master Grip Kit on iPhone" alt="Telesin Master Grip Kit on iPhone." src="https://cdn.mos.cms.futurecdn.net/7UCQDEYBbznaWF8Nk48q4C-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>The optical reach is only half the story because how the phone handles is what really cements that mirrorless camera feel for me. The Telesin kit centers around an ergonomic, MagSafe-enabled camera grip that snaps onto the back with a firm lock. With tactile buttons and dials that emulate a traditional camera layout, it gives my shooting hand the stability needed to keep my framing right while shooting with the telephoto lens.</p><p>Even better, the grip doubles as a power bank that actively charges my iPhone. Around the base, a standard 1/4-inch tripod mount lets me seamlessly attach the entire rig to essential accessories I typically carry — like my monopod or selfie stick — without taking anything apart.</p><p>The accompanying case ties everything together with thoughtful hardware touches. It features a slide-on protective lens cover with threaded mounts, allowing me to screw the add-on glass directly over either the main or telephoto camera. On top of that, built-in lanyard cutouts on the side let me thread standard camera straps and wrist lanyards directly to the phone.</p><h2 id="bottom-line-6">Bottom line</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="D2KJywVA3N5xdc6NxwrF4C" name="Telesin Master Grip Kit on iPhone" alt="Telesin Master Grip Kit on iPhone." src="https://cdn.mos.cms.futurecdn.net/D2KJywVA3N5xdc6NxwrF4C-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>At $229, the Telesin Master Grip Kit with the 3.5x telephoto lens isn’t an impulse buy — it’s undeniably an investment. But when I factor in the camera-style handling of the grip, integrated battery charging, and optical reach that actually rivals a dedicated compact shooter, it has convinced me to finally retire my old point-and-shoot.</p><p>If you don't need extreme 400mm-equivalent reach for concerts or wildlife, Telesin also offers a cheaper $179 kit that swaps out the 3.5x glass for a 2x telephoto lens, giving you the same ergonomic rig and street-friendly focal lengths for $50 less. For anyone tired of carrying a separate camera just to get reliable zoom and real manual feel, this setup is well worth the price.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-W0EB7O"></div>                            </div>                            <script src="https://kwizly.com/embed/W0EB7O.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/phones/iphones/11-best-ios-27-hidden-features-you-cant-afford-to-miss">11 best iOS 27 hidden features you can't afford to miss</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">I tested iPhone 18 Pro Max variable aperture camera and I can (almost) ditch my mirrorless</a></li><li><a href="https://www.tomsguide.com/phones/iphones/the-iphone-duo-has-a-lot-of-hype-but-this-poll-has-a-surprising-reveal-for-samsungs-foldable">The iPhone Duo has a lot of hype, but this poll has a surprising reveal for Samsung's foldable</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/i-extended-my-iphones-telephoto-range-with-this-add-on-camera-lens-and-my-point-and-shoot-camera-is-officially-retired</link>
                                                                            <description>
                            <![CDATA[ I tested the Telesin Master Grip Kit with 3.5x zoom lens for nearly a month and it made me ditch my usual point and shoot camera. Here's why. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Lpt88K3R7GBDopEJzfBLmj</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/4ZkKpvPmvFKMAaxqePAkxB-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 21 Sep 2026 06:30:00 +0000</pubDate>                                                                                                                                <updated>Mon, 21 Sep 2026 13:04:49 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Cameras & Photography]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ john.velasco@futurenet.com (John Velasco) ]]></author>                    <dc:creator><![CDATA[ John Velasco ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/TSj224oX8d5ERXaDs8pDGd-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/4ZkKpvPmvFKMAaxqePAkxB-1920-80.jpg">
                                                            <media:credit><![CDATA[John Velasco / Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Telesin Master Grip Kit on iPhone.]]></media:description>                                                            <media:text><![CDATA[Telesin Master Grip Kit on iPhone.]]></media:text>
                                <media:title type="plain"><![CDATA[Telesin Master Grip Kit on iPhone.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/4ZkKpvPmvFKMAaxqePAkxB-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>For years, I’ve kept a compact point-and-shoot camera in my backpack when I commute to work or go on trips. Part of the reason is that it offers longer telephoto reach, as well as intuitive software with the manual controls I crave. But despite testing an assortment of the <a href="https://www.tomsguide.com/phones/iphones/best-iphone-lenses">best iPhone lenses</a>, none have really felt like a complete shooting solution compelling enough to pry me away from my dedicated camera.</p><p>That changed when I got my hands on the <a href="https://www.telesinstore.com/products/telesin-master-grip-kit-for-iphone-18-pro-series?variant=50462969659640" target="_blank" rel="nofollow">Telesin Master Grip Kit</a>. Rather than treating the telephoto lens as an isolated add-on, it approaches mobile photography as an entire ecosystem — a MagSafe-enabled rig that pairs a lens with an ergonomic grip. It fundamentally changes how I handle the device, and after using it for nearly a month, I can tell you that the difference isn't subtle. Here’s why.</p><h2 id="way-better-telephoto-performance">Way better telephoto performance</h2><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/RypYatXV64w3H6AffAYakR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 40x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/k8KrxqH5CXGsjfi3iaeexW-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/v3XijzdcRCZyBwawnaKiKR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 40x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/cSyRDrYqLY5eFXyBAuSeMW-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/EgH2nH4vK7fMpKTvFWyJRR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 40x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/HjonEFQRjr3JeN9wju5EMW-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/geoFjYw2tYaXTCfVCJprjR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 40x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/6RzDJX2do3nG9YzuTDZ9mW-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/KJFmqays3mVP6PGMj8nTkR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 40x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/9cqEYKst9TdM8yzAyDPgaW-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/SakZVfa495DKRsWAcnLdkR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 40x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/3KUMHqub2bRctBS3wRYigW-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/robGpkHKgYuX7L4NbwWKmR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 40x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/Nr2oXfaGymh2WHbQHTaRyW-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/uu6yXSmjSfkVd96vbmyNnR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 40x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/rULXViKwXemz8Dmze7sj2X-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/R9db5Ea5nddfQGAY9CYprR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 40x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/E79oFzzezWuP79te23d54X-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure></figure><p>I don’t miss the Space Zoom on Samsung’s flagship models now that the Telesin 3.5x lens paired with my <a href="https://www.tomsguide.com/phones/iphones/iphone-17-pro-max-review">iPhone 17 Pro</a> drastically sharpens its telephoto reach. Don’t believe me? Take a look at the side-by-side snapshots above comparing my standalone iPhone 17 Pro at 40x zoom against the Telesin 3.5x setup.</p><p>In the first set of images, the shot from my iPhone leaves the wood grain indistinct and almost smeary, with fine depth flattened by the phone's aggressive image processing. Distant textures simply lack clarity and definition. The results with the Telesin kit offer a stark contrast because every groove of the wood grain is sharp and clearly defined, while natural contrast and dynamic range are preserved.</p><div class="product"><a data-dimension112="912a2bee-b39c-11f1-a6ec-938be7b47f46" data-action="Deal Block" data-label="Master Grip Kit" data-dimension48="Master Grip Kit" data-dimension25="$229.99" href="https://www.telesinstore.com/products/telesin-master-grip-kit-for-iphone-18-pro-series?variant=50462969692408" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="GPZpWomTTTuBWxG5t4xGKa" name="Telesin Master Grip Kit deal block" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/GPZpWomTTTuBWxG5t4xGKa-1920-80.jpg" mos="" align="middle" fullscreen="" width="600" height="600" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>Transform your iPhone into a versatile dedicated camera system with the Telesin Master Grip Kit. It snaps onto your iPhone via MagSafe, offering physical controls and a grip to properly frame shots with ease. With the included telephoto lens, you can pair it with the iPhone's main or telephoto cameras to get more zoom without the artificial look that normally comes with computational photography. Use code <strong>4BU3AHFE  </strong>at checkout for an additional 15% off.<a class="view-deal button" href="https://www.telesinstore.com/products/telesin-master-grip-kit-for-iphone-18-pro-series?variant=50462969692408" target="_blank" rel="nofollow" data-dimension112="912a2bee-b39c-11f1-a6ec-938be7b47f46" data-action="Deal Block" data-label="Master Grip Kit" data-dimension48="Master Grip Kit" data-dimension25="$229.99">View Deal</a></p></div><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/fDsACnb5G3dafXpjfd4yWR-1920-80.jpg" alt="iPhone 17 Pro telephoto sample." /><figcaption>iPhone 17 Pro 1x zoom.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/8DG6PNtTjPe6HhjsakLEXW-1920-80.jpg" alt="iPhone 17 Pro telephoto Telesin sample." /><figcaption>iPhone 17 Pro with Telesin 3.5x zoom lens.<small role="credit">John Velasco / Tom's Guide</small></figcaption></figure></figure><p>This isn't just a minor bump in quality — it proves how dedicated optical glass can salvage distant subjects that's ruined by digital processing. The long-exposure shot above perfectly illustrates this reach, by transforming the distant 9/11 Tribute in Light as two distinctly separated pillars of light when zoomed all the way in with the Telesin lens. The kit delivers the kind of true optical performance that finally lets me leave my dedicated camera behind.</p><h2 id="versatile-grip-and-case">Versatile grip and case</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="7UCQDEYBbznaWF8Nk48q4C" name="Telesin Master Grip Kit on iPhone" alt="Telesin Master Grip Kit on iPhone." src="https://cdn.mos.cms.futurecdn.net/7UCQDEYBbznaWF8Nk48q4C-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>The optical reach is only half the story because how the phone handles is what really cements that mirrorless camera feel for me. The Telesin kit centers around an ergonomic, MagSafe-enabled camera grip that snaps onto the back with a firm lock. With tactile buttons and dials that emulate a traditional camera layout, it gives my shooting hand the stability needed to keep my framing right while shooting with the telephoto lens.</p><p>Even better, the grip doubles as a power bank that actively charges my iPhone. Around the base, a standard 1/4-inch tripod mount lets me seamlessly attach the entire rig to essential accessories I typically carry — like my monopod or selfie stick — without taking anything apart.</p><p>The accompanying case ties everything together with thoughtful hardware touches. It features a slide-on protective lens cover with threaded mounts, allowing me to screw the add-on glass directly over either the main or telephoto camera. On top of that, built-in lanyard cutouts on the side let me thread standard camera straps and wrist lanyards directly to the phone.</p><h2 id="bottom-line-6">Bottom line</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="D2KJywVA3N5xdc6NxwrF4C" name="Telesin Master Grip Kit on iPhone" alt="Telesin Master Grip Kit on iPhone." src="https://cdn.mos.cms.futurecdn.net/D2KJywVA3N5xdc6NxwrF4C-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>At $229, the Telesin Master Grip Kit with the 3.5x telephoto lens isn’t an impulse buy — it’s undeniably an investment. But when I factor in the camera-style handling of the grip, integrated battery charging, and optical reach that actually rivals a dedicated compact shooter, it has convinced me to finally retire my old point-and-shoot.</p><p>If you don't need extreme 400mm-equivalent reach for concerts or wildlife, Telesin also offers a cheaper $179 kit that swaps out the 3.5x glass for a 2x telephoto lens, giving you the same ergonomic rig and street-friendly focal lengths for $50 less. For anyone tired of carrying a separate camera just to get reliable zoom and real manual feel, this setup is well worth the price.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-W0EB7O"></div>                            </div>                            <script src="https://kwizly.com/embed/W0EB7O.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/phones/iphones/11-best-ios-27-hidden-features-you-cant-afford-to-miss">11 best iOS 27 hidden features you can't afford to miss</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">I tested iPhone 18 Pro Max variable aperture camera and I can (almost) ditch my mirrorless</a></li><li><a href="https://www.tomsguide.com/phones/iphones/the-iphone-duo-has-a-lot-of-hype-but-this-poll-has-a-surprising-reveal-for-samsungs-foldable">The iPhone Duo has a lot of hype, but this poll has a surprising reveal for Samsung's foldable</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I've been testing the iPhone 18 Pro Max and iPhone 18 Pro — your 10 biggest questions answered ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I’ve been testing the new <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro and iPhone 18 Pro Max for our review</a> and much more, and I know there's a lot of questions people want answered before they decide whether to upgrade. Is the A20 Pro performance leap big enough? How good is the battery life? Which model is better for you? And should you just wait for the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a>?</p><p>I've scoured all of the comments and questions we've been getting on the <a href="https://www.youtube.com/@TomsGuideUS">Tom's Guide YouTube</a> channel, <a href="https://www.tiktok.com/@tomsguide?lang=en">TikTok</a> hot takes, <a href="https://www.instagram.com/tomsguide/?hl=en">Instagram videos</a> and and my recent <a href="https://www.youtube.com/watch?v=uJKt432tWM4&t=288s">interview with Apple CEO John Ternus</a>, and these are the top 10 questions you have about Apple's new flagships along with my answers. </p><div class="youtube-video" data-nosnippet ><div class="video-aspect-box"><iframe data-lazy-priority="low" data-lazy-src="https://www.youtube-nocookie.com/embed/sqaV5mFJav8" allowfullscreen></iframe></div></div><h2 id="39-glad-i-ordered-the-pro-the-pro-max-looks-so-massive-249-grams-is-a-whole-ipad-39">'Glad I ordered the Pro, the Pro Max looks so massive. 249 grams is a whole iPad.'</h2><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="ZhVLRJCFGxVjGeDa3TaWmK" name="iPhone 18 Pro and Pro Max-LIST3" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/ZhVLRJCFGxVjGeDa3TaWmK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The iPhone 18 Pro Max is not quite the weight of an iPad mini, but there's no denying that Apple's biggest flagship has been getting heavier each generation. The iPhone 17 Pro Max weighed 8.22 ounces while the iPhone 18 Pro Max is 8.78 ounces. That's a pretty significant increase for just one year.</p><div ><table><thead><tr><th class="firstcol " ><p>Device</p></th><th  ><p>Weight (Ounces)</p></th><th  ><p>Weight (Grams)</p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>iPhone 15 Pro Max</strong> (2023)</p></td><td  ><p>7.81 oz</p></td><td  ><p>221 g</p></td></tr><tr><td class="firstcol " ><p><strong>iPhone 16 Pro Max</strong> (2024)</p></td><td  ><p>7.99 oz</p></td><td  ><p>227 g</p></td></tr><tr><td class="firstcol " ><p><strong>iPhone 17 Pro Max</strong> (2025)</p></td><td  ><p>8.22 oz</p></td><td  ><p>233 g</p></td></tr><tr><td class="firstcol " ><p><strong>iPhone 18 Pro Max</strong> (2026)</p></td><td  ><p>8.78 oz</p></td><td  ><p>249 g</p></td></tr><tr><td class="firstcol " ><p><strong>iPad mini</strong> (A17 Pro, Wi-Fi)</p></td><td  ><p>10.34 oz</p></td><td  ><p>293 g</p></td></tr></tbody></table></div><p>The extra heft for the new iPhone is likely due to Apple adding a bigger internal vapor chamber cooling system, as well as physical mechanical blades for the variable aperture.</p><p>Plus, you get a bigger battery on the iPhone 18 Pro Max. The eSIM model of the iPhone 18 Pro Max reportedly has a 5,567 mAh battery, compared to 5,088 mAh on the iPhone 17 Pro max.</p><p>If you carry your iPhone 18 Pro Max in your front pocket all day, you <em>will</em> feel those 249 grams. The standard iPhone 18 Pro comes in at 211 grams, which is much more manageable.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-eGby2X"></div>                            </div>                            <script src="https://kwizly.com/embed/eGby2X.js" async></script><h2 id="39-will-my-iphone-17-pro-case-fit-the-iphone-18-pro-39">'Will my iPhone 17 Pro case fit the iPhone 18 Pro?'</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="bW96LgRiL7LmZwbnVC2VtM" name="iPhone 18 Pro in case" alt="iPhone 18 Pro in case" src="https://cdn.mos.cms.futurecdn.net/bW96LgRiL7LmZwbnVC2VtM-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Yes, your iPhone 17 Pro and iPhone 17 Pro cases should fit your iPhone 18 Pro and iPhone 18 Pro Max. Apple kept the physical height, width, and depth dimensions identical to last year's models, so you don't need to spend another $50 on a new case unless you just want a new style or color.</p><p>If you're looking to protect your investment, we've got a roundup of the 12 <a href="https://www.tomsguide.com/phones/iphones/keep-your-new-iphone-18-pro-or-iphone-18-pro-max-safe-from-day-one-the-cases-to-buy-right-now">best iPhone 18 Pro and iPhone 18 Pro Max cases</a> to get, including Apple, Otterbox and Casetify.</p><h2 id="39-can-we-turn-the-dynamic-island-off-i-hate-when-app-icons-block-the-top-39">'Can we turn the Dynamic Island off? I hate when app icons block the top'</h2><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="4edCqgzDe6Geozici7QFqK" name="iPhone 18 Pro and Pro Max-14" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/4edCqgzDe6Geozici7QFqK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>No, you can’t disable the Dynamic Island on the iPhone 18 Pro or Pro Max. But Apple did make the cutout smaller this year by moving the infrared sensor for Face ID underneath the display glass.</p><p>More good news: You can now show up to three Live Activities at once instead of just two. So I could easily toggle between a timer, Spotify controls, and Apple Maps directions at the top of my screen.</p><h2 id="39-how-does-the-18-pro-battery-compare-to-the-17-pro-max-39">'How does the 18 Pro battery compare to the 17 Pro Max?'</h2><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="S8VCNwUf4CeCFFtLAWtVmK" name="iPhone 18 Pro and Pro Max-8" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/S8VCNwUf4CeCFFtLAWtVmK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The new iPhone 18 Pro models do last longer on charge than the iPhone 17 Pro series, but it's not quite the leap we thought it would be. Let’s look at the actual Tom's Guide lab test numbers:</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>Hrs:Mins</strong></p></td></tr><tr><td class="firstcol " ><p><strong>iPhone 18 Pro Max </strong></p></td><td  ><p>18:27 </p></td></tr><tr><td class="firstcol " ><p><strong>iPhone 18 Pro</strong></p></td><td  ><p>16:17</p></td></tr><tr><td class="firstcol " ><p><strong>iPhone 17 Pro Max</strong></p></td><td  ><p>17:54</p></td></tr><tr><td class="firstcol " ><p><strong>iPhone 17 Pro</strong></p></td><td  ><p>15:21</p></td></tr><tr><td class="firstcol " ><p><strong>Galaxy S26 Ultra </strong></p></td><td  ><p>16:40</p></td></tr><tr><td class="firstcol " ><p><strong>OnePlus 15</strong></p></td><td  ><p>25:13</p></td></tr></tbody></table></div><p>The iPhone 18 Pro lasted 16 hours and 17 minutes on the Tom's Guide battery test, which involves web surfing over 5G at 150 nits of screen brightness. That’s nearly an hour gain over the 17 Pro, but it does <em>not</em> beat last year's 17 Pro Max, which hit 17:54.</p><p>The iPhone 18 Pro Max is still the battery life king at 18 hours and 27 minutes. It's the longest-lasting iPhone we have ever benchmarked and makes it among the top performers on the Tom's Guide <a href="https://www.tomsguide.com/us/smartphones-best-battery-life,review-2857.html">best phone battery life</a> list. It also beats the Galaxy S26 Ultra by nearly 2 hours.</p><h2 id="39-give-me-an-iphone-duo-with-the-iphone-18-pro-camera-suite-that-39-s-literally-all-i-want-39">'Give me an iPhone Duo with the iPhone 18 Pro camera suite. That's literally all I want.'</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1802px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="ENFN2u4hpSYiQYfbA6WbcL" name="Apple iPhone Duo hands on-4" alt="Apple iPhone Duo shown in hand" src="https://cdn.mos.cms.futurecdn.net/ENFN2u4hpSYiQYfbA6WbcL-1920-80.jpg" mos="" align="middle" fullscreen="" width="1802" height="1014" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I’m right there with you, but here’s why that camera setup is likely exclusive to the 18 Pro series. Apple likely couldn't find the room to add a telephoto lens to the Duo, so you get just a wide and ultrawide lens. </p><p>So if you want a longer 4x optical zoom, go with the iPhone 18 Pro or Pro Max.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1280px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dwK9C9bzHe8Bqt6sMrUca" name="iPhone 18 Pro Max variable aperture camera.GIF" alt="iPhone 18 Pro Max variable aperture camera." src="https://cdn.mos.cms.futurecdn.net/dwK9C9bzHe8Bqt6sMrUca-1920-80.gif" mos="" align="middle" fullscreen="" width="1280" height="720" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>In addition, Apple added six mechanical blades that expand and contract to the main 48MP camera on the Pros in order to achieve variable aperture. It shifts anywhere from f/1.48 to f/4.0 automatically, or you can customize it using new Pro controls.</p><p>That six-blade mechanism requires physical depth. That's why the thinner foldable iPhone Duo likely can't fit this exact camera suite without adding a massive camera bump. See our in-depth <a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">iPhone 18 Pro Max variable aperture camera testing</a> for some good examples of what you can do.</p><h2 id="39-can-you-actually-edit-cinematic-mode-after-you-record-a-video-now-or-did-i-misread-that-39">'Can you actually edit Cinematic Mode AFTER you record a video now, or did I misread that?'</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="mbQXJpVhh2gJNSgo7i2ixg" name="iPhone 18 Pro Cinematic mode" alt="iPhone 18 Pro Cinematic mode" src="https://cdn.mos.cms.futurecdn.net/mbQXJpVhh2gJNSgo7i2ixg-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>You read that right. And this is probably my favorite software quality-of-life upgrade on the iPhone 18 Pro and Pro Max.</p><p>Historically, if you forgot to select Cinematic Mode <em>before</em> hitting record, you were stuck with standard video. On the 18 Pro series, you can shoot standard 4K video, open up the editor, and toggle Cinematic Mode on or off after the fact right at the top of the display.</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/t7LuoywmKb0" allowfullscreen></iframe></div></div><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/-XgH2ozgkDU" allowfullscreen></iframe></div></div><p>You can see the results above, as the background is more blurred out with Cinematic Mode enabled. It's essentially like Portrait mode for video.</p><p>Apple also added manual shutter speed controls for video and 4K Dolby Vision Timelapses. If you shoot video for social media or YouTube, this gives you way more flexibility in post-production without locking you into specific camera modes up front.</p><h2 id="39-performance-get-the-iphone-18-pro-entertainment-wait-for-the-iphone-duo-39">'Performance = Get the iPhone 18 Pro. Entertainment = Wait for the iPhone Duo.'</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="LnmNWSENsBFHRGRWmcFa7" name="iPhone Duo vs iPhone 18 Pro" alt="iPhone Duo vs iPhone 18 Pro" src="https://cdn.mos.cms.futurecdn.net/LnmNWSENsBFHRGRWmcFa7-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>This is an interesting take on the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-vs-iphone-18-pro-vs-iphone-18-pro-max-heres-the-one-i-recommend">iPhone 18 Pro vs. iPhone Duo</a> comparison.</p><p>The 18 Pro is powered by the 2nm A20 Pro chip. In our benchmark tests, it scored over 4,700 on single-core CPU tests and turned in a massive 45% graphics jump over the 17 Pro Max, also comfortably beating Samsung's Galaxy S26 Ultra across the board.</p><p>The iPhone Duo uses this <em>exact same</em> processor. Our <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen">A20 Pro lab testing</a> proves that this chip has the raw GPU horsepower and 80% thermal stability required to run dual-screen multitasking without overheating or tanking performance.</p><p>However, driving a larger display requires more resources, and it's not clear how much the iPhone Duo's thinner design will impact sustained performance. The bigger difference to me is likely to be battery life, though, as the iPhone 18 Pro Max is rated for 45 hours of video playback versus 31 for the Duo on its main 7.6-inch panel.</p><p>If you want a traditional, ultra-durable slab phone with max camera control and 18+ hours of battery, get the 18 Pro Max. But if you want a dual-screen workstation for media and multitasking, wait for the Duo, because the chip inside should be ready for it.</p><h2 id="39-is-siri-ai-on-ios-27-actually-useful-now-39">'Is Siri AI on iOS 27 actually useful now?'</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="UHFLgbZkizWAuzbea6ATRH" name="iPhone 18 Pro and Pro Max" alt="Siri AI on an iPhone 18 Pro" src="https://cdn.mos.cms.futurecdn.net/UHFLgbZkizWAuzbea6ATRH-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I’m not going to say that <a href="https://www.tomsguide.com/ai/apple-finally-fixed-siri-heres-all-the-features-for-the-new-siri-ai-announced-at-wwdc">Siri AI</a> is smarter than Gemini or ChatGPT yet. But thanks to <a href="https://www.tomsguide.com/phones/iphones/ios-27-7-features-you-need-to-try-first-after-updating">iOS 27</a> and the A20 Pro’s new dual 16-core Neural Engine, which logged a 40% to 48% speed boost in our Geekbench AI lab tests, it’s significantly more helpful.</p><p>The big difference this year is personal context and multi-step voice prompts. Instead of asking Siri to do one basic task at a time, you can do several things at once.</p><p>For example, I could ask for Siri to check my calendar for any openings for lunch with my brother, research restaurants around Bryant Park and include recommended dishes and send a text to him in a single prompt.  </p><p>I just wish that you could talk to Siri in real time while looking at live video, as you can with Gemini and ChatGPT Voice. </p><h2 id="39-is-there-actually-100-more-worth-of-upgrades-here-39">'Is there actually $100 more worth of upgrades here?'</h2><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="zQniEFCJPwZTgNapSzUwAB" name="iPhone 18 Pro Max vs 14 Pro Max LIST" alt="iPhone 18 Pro Max vs 14 Pro Max." src="https://cdn.mos.cms.futurecdn.net/zQniEFCJPwZTgNapSzUwAB-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>This question is referring to the $100 price hike for the iPhone 18 Pro and iPhone 18 Pro Max, which is likely due to the component shortage. So, what does that extra $100 actually buy you under the hood?</p><ul><li>A blazing  A20 Pro chip</li><li>A physical, six-blade mechanical variable aperture main camera</li><li>An internal vapor chamber that's three times larger for sustained cooling</li><li>Upgraded 60W fast charging</li><li>Solid battery life gains for both models</li></ul><p>Whether these upgrades justify the extra cash depends on your current iPhone. If you're coming from an iPhone 17 Pro, paying $100 is a tough sell.</p><p>But if you're upgrading from a an <a href="https://www.tomsguide.com/reviews/iphone-14-pro">iPhone 14 Pro</a> or <a href="https://www.tomsguide.com/reviews/iphone-15-pro">iPhone 15 Pro</a>, that $100 gets you a massive 50% performance leap, real optical aperture control, and over three additional hours of screen time.</p><h2 id="39-should-i-get-the-iphone-18-pro-or-iphone-18-pro-max-39">'Should I get the iPhone 18 Pro or iPhone 18 Pro Max?'</h2><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="ZtKf5v9A9ty5HGwMasFK7f" name="iPhone 18 Pro and Pro Max-4" alt="Apple iPhone 18 Pro Max" src="https://cdn.mos.cms.futurecdn.net/ZtKf5v9A9ty5HGwMasFK7f-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>This is not an easy call. There’s four main differences between the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-vs-iphone-18-pro-which-could-be-the-superior-flagship">iPhone 18 Pro vs iPhone 18 Pro Max</a>.</p><p>No. 1 is the display size. The 6.3-inch OLED panel on the iPhone 18 Pro is great, but the 6.9-inch screen on the Max gives you a more immersive viewing experience for playing games and watching movies. Plus, there’s more info on screen at once when reviewing documents or surfing the web.</p>                    <div class= "tiktok-wrapper" style="min-height: 750px;"><blockquote class="tiktok-embed" cite="https://www.tiktok.com/@mspoonyg/video/7686313211167132941" data-video-id="7686313211167132941" style="max-width: 605px; min-width: 325px;">                        <section>                            <a target="_blank" title="@mspoonyg" href="https://www.tiktok.com/@mspoonyg">@mspoonyg</a>                            <p></p><a target="_blank" title="♬ original sound - mspoonyg" href="https://www.tiktok.com/music/original-sound-7686313250731870990">♬ original sound - mspoonyg</a></section>                    </blockquote></div>                <p>Second, you get more battery life on the iPhone 18 Pro Max, hitting nearly 18.5 hours — which is a bit over 2 hours more than the iPhone 18 Pro.</p><p>On the other hand, the iPhone 18 Pro is more compact and lighter. It’s like having a stealth bomber in your pocket with all that A20 Pro power. And the iPhone 18 Pro starts at $100 less. That might not seem like much but you can put that savings towards additional storage.</p><p>For me I’d get the iPhone 18 Pro Max but it really comes down to screen size and price.</p><h2 id="bottom-line-7">Bottom line</h2><p>The iPhone 18 Pro and Pro Max might not look radically different at first glance,  but underneath, the A20 Pro chip, camera hardware, and thermal redesign set a new baseline for Apple flagships.</p><p>Did we answer your key questions about the 18 Pro series? Are you picking one up, or holding out for our full iPhone Duo review? Let us know in the comments! </p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/i-spent-30-minutes-with-the-iphone-duo-3-things-you-just-dont-get-from-the-pictures">I spent 30 minutes with the iPhone Duo — 3 things you just don’t get from the pictures</a></li><li><a href="https://www.tomsguide.com/phones/i-put-the-iphone-18-pro-max-vs-galaxy-s26-ultra">I put the iPhone 18 Pro Max vs. Galaxy S26 Ultra through a 7-round face-off — here’s the winner</a></li><li><a href="https://www.tomsguide.com/ai/i-replaced-chatgpt-with-siri-ai-for-a-day-heres-what-surprised-me">I replaced ChatGPT with Siri AI for a day — here's what surprised me</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-iphone-18-pro-your-10-biggest-questions-answered</link>
                                                                            <description>
                            <![CDATA[ What you need to know before you buy ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">RRtnWjZnYVSYvAz5hEf4Ye</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/5kKUCv7Eef6yGkMMGEgbvJ-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 21 Sep 2026 05:15:00 +0000</pubDate>                                                                                                                                <updated>Mon, 21 Sep 2026 08:48:20 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                                    <dc:creator><![CDATA[ Mark Spoonauer ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/wtAspSzVfcKLB4JEd39AMo-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Mark Spoonauer is the global editor in chief of Tom&#039;s Guide and has covered technology for over 20 years. He oversees the direction of Tom&#039;s Guide and leads a team of over 25 journalists to bring you our expert buying guides, reviews, news, how-to articles, deals and other coverage.&lt;/p&gt;&lt;p&gt;Mark has a passion for covering all things mobile, having reviewed dozens of smartphones and other gadgets. He enjoys testing the top mobile devices and putting them up against each other in our in-depth face-offs. He also works hand in hand with our editors and testing team to continually improve how we evaluate products. &lt;/p&gt;&lt;p&gt;Having led Tom&#039;s Guide since 2013, Mark has focused on growing the core tech coverage of the site while also expanding into new areas, such as entertainment, fitness and home, recruiting talented writers and editors to help our readers figure out what to buy and how to get the most out of the products and services they use every day. &lt;/p&gt;&lt;p&gt;Mark has spoken at key industry events and appears regularly on TV to discuss the latest trends, including &lt;a href=&quot;https://cheddar.com/media/pixel-watch-gets-a-release-date-at-google-i-o-2022&quot;&gt;Cheddar&lt;/a&gt;, Fox 5, &lt;a href=&quot;https://www.foxbusiness.com/technology/apple-march-event-5g-iphone&quot;&gt;Fox Business&lt;/a&gt; and other outlets. Mark was previously editor in chief of Laptop Mag, and his work has appeared in Wired, Popular Science and Inc. Follow him on Twitter at @mspoonauer.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/5kKUCv7Eef6yGkMMGEgbvJ-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Apple iPhone 18 Pro and Pro Max shown in hand]]></media:description>                                                            <media:text><![CDATA[Apple iPhone 18 Pro and Pro Max shown in hand]]></media:text>
                                <media:title type="plain"><![CDATA[Apple iPhone 18 Pro and Pro Max shown in hand]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/5kKUCv7Eef6yGkMMGEgbvJ-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I’ve been testing the new <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro and iPhone 18 Pro Max for our review</a> and much more, and I know there's a lot of questions people want answered before they decide whether to upgrade. Is the A20 Pro performance leap big enough? How good is the battery life? Which model is better for you? And should you just wait for the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a>?</p><p>I've scoured all of the comments and questions we've been getting on the <a href="https://www.youtube.com/@TomsGuideUS">Tom's Guide YouTube</a> channel, <a href="https://www.tiktok.com/@tomsguide?lang=en">TikTok</a> hot takes, <a href="https://www.instagram.com/tomsguide/?hl=en">Instagram videos</a> and and my recent <a href="https://www.youtube.com/watch?v=uJKt432tWM4&t=288s">interview with Apple CEO John Ternus</a>, and these are the top 10 questions you have about Apple's new flagships along with my answers. </p><div class="youtube-video" data-nosnippet ><div class="video-aspect-box"><iframe data-lazy-priority="low" data-lazy-src="https://www.youtube-nocookie.com/embed/sqaV5mFJav8" allowfullscreen></iframe></div></div><h2 id="39-glad-i-ordered-the-pro-the-pro-max-looks-so-massive-249-grams-is-a-whole-ipad-39">'Glad I ordered the Pro, the Pro Max looks so massive. 249 grams is a whole iPad.'</h2><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="ZhVLRJCFGxVjGeDa3TaWmK" name="iPhone 18 Pro and Pro Max-LIST3" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/ZhVLRJCFGxVjGeDa3TaWmK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The iPhone 18 Pro Max is not quite the weight of an iPad mini, but there's no denying that Apple's biggest flagship has been getting heavier each generation. The iPhone 17 Pro Max weighed 8.22 ounces while the iPhone 18 Pro Max is 8.78 ounces. That's a pretty significant increase for just one year.</p><div ><table><thead><tr><th class="firstcol " ><p>Device</p></th><th  ><p>Weight (Ounces)</p></th><th  ><p>Weight (Grams)</p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>iPhone 15 Pro Max</strong> (2023)</p></td><td  ><p>7.81 oz</p></td><td  ><p>221 g</p></td></tr><tr><td class="firstcol " ><p><strong>iPhone 16 Pro Max</strong> (2024)</p></td><td  ><p>7.99 oz</p></td><td  ><p>227 g</p></td></tr><tr><td class="firstcol " ><p><strong>iPhone 17 Pro Max</strong> (2025)</p></td><td  ><p>8.22 oz</p></td><td  ><p>233 g</p></td></tr><tr><td class="firstcol " ><p><strong>iPhone 18 Pro Max</strong> (2026)</p></td><td  ><p>8.78 oz</p></td><td  ><p>249 g</p></td></tr><tr><td class="firstcol " ><p><strong>iPad mini</strong> (A17 Pro, Wi-Fi)</p></td><td  ><p>10.34 oz</p></td><td  ><p>293 g</p></td></tr></tbody></table></div><p>The extra heft for the new iPhone is likely due to Apple adding a bigger internal vapor chamber cooling system, as well as physical mechanical blades for the variable aperture.</p><p>Plus, you get a bigger battery on the iPhone 18 Pro Max. The eSIM model of the iPhone 18 Pro Max reportedly has a 5,567 mAh battery, compared to 5,088 mAh on the iPhone 17 Pro max.</p><p>If you carry your iPhone 18 Pro Max in your front pocket all day, you <em>will</em> feel those 249 grams. The standard iPhone 18 Pro comes in at 211 grams, which is much more manageable.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-eGby2X"></div>                            </div>                            <script src="https://kwizly.com/embed/eGby2X.js" async></script><h2 id="39-will-my-iphone-17-pro-case-fit-the-iphone-18-pro-39">'Will my iPhone 17 Pro case fit the iPhone 18 Pro?'</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="bW96LgRiL7LmZwbnVC2VtM" name="iPhone 18 Pro in case" alt="iPhone 18 Pro in case" src="https://cdn.mos.cms.futurecdn.net/bW96LgRiL7LmZwbnVC2VtM-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Yes, your iPhone 17 Pro and iPhone 17 Pro cases should fit your iPhone 18 Pro and iPhone 18 Pro Max. Apple kept the physical height, width, and depth dimensions identical to last year's models, so you don't need to spend another $50 on a new case unless you just want a new style or color.</p><p>If you're looking to protect your investment, we've got a roundup of the 12 <a href="https://www.tomsguide.com/phones/iphones/keep-your-new-iphone-18-pro-or-iphone-18-pro-max-safe-from-day-one-the-cases-to-buy-right-now">best iPhone 18 Pro and iPhone 18 Pro Max cases</a> to get, including Apple, Otterbox and Casetify.</p><h2 id="39-can-we-turn-the-dynamic-island-off-i-hate-when-app-icons-block-the-top-39">'Can we turn the Dynamic Island off? I hate when app icons block the top'</h2><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="4edCqgzDe6Geozici7QFqK" name="iPhone 18 Pro and Pro Max-14" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/4edCqgzDe6Geozici7QFqK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>No, you can’t disable the Dynamic Island on the iPhone 18 Pro or Pro Max. But Apple did make the cutout smaller this year by moving the infrared sensor for Face ID underneath the display glass.</p><p>More good news: You can now show up to three Live Activities at once instead of just two. So I could easily toggle between a timer, Spotify controls, and Apple Maps directions at the top of my screen.</p><h2 id="39-how-does-the-18-pro-battery-compare-to-the-17-pro-max-39">'How does the 18 Pro battery compare to the 17 Pro Max?'</h2><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="S8VCNwUf4CeCFFtLAWtVmK" name="iPhone 18 Pro and Pro Max-8" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/S8VCNwUf4CeCFFtLAWtVmK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The new iPhone 18 Pro models do last longer on charge than the iPhone 17 Pro series, but it's not quite the leap we thought it would be. Let’s look at the actual Tom's Guide lab test numbers:</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>Hrs:Mins</strong></p></td></tr><tr><td class="firstcol " ><p><strong>iPhone 18 Pro Max </strong></p></td><td  ><p>18:27 </p></td></tr><tr><td class="firstcol " ><p><strong>iPhone 18 Pro</strong></p></td><td  ><p>16:17</p></td></tr><tr><td class="firstcol " ><p><strong>iPhone 17 Pro Max</strong></p></td><td  ><p>17:54</p></td></tr><tr><td class="firstcol " ><p><strong>iPhone 17 Pro</strong></p></td><td  ><p>15:21</p></td></tr><tr><td class="firstcol " ><p><strong>Galaxy S26 Ultra </strong></p></td><td  ><p>16:40</p></td></tr><tr><td class="firstcol " ><p><strong>OnePlus 15</strong></p></td><td  ><p>25:13</p></td></tr></tbody></table></div><p>The iPhone 18 Pro lasted 16 hours and 17 minutes on the Tom's Guide battery test, which involves web surfing over 5G at 150 nits of screen brightness. That’s nearly an hour gain over the 17 Pro, but it does <em>not</em> beat last year's 17 Pro Max, which hit 17:54.</p><p>The iPhone 18 Pro Max is still the battery life king at 18 hours and 27 minutes. It's the longest-lasting iPhone we have ever benchmarked and makes it among the top performers on the Tom's Guide <a href="https://www.tomsguide.com/us/smartphones-best-battery-life,review-2857.html">best phone battery life</a> list. It also beats the Galaxy S26 Ultra by nearly 2 hours.</p><h2 id="39-give-me-an-iphone-duo-with-the-iphone-18-pro-camera-suite-that-39-s-literally-all-i-want-39">'Give me an iPhone Duo with the iPhone 18 Pro camera suite. That's literally all I want.'</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1802px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="ENFN2u4hpSYiQYfbA6WbcL" name="Apple iPhone Duo hands on-4" alt="Apple iPhone Duo shown in hand" src="https://cdn.mos.cms.futurecdn.net/ENFN2u4hpSYiQYfbA6WbcL-1920-80.jpg" mos="" align="middle" fullscreen="" width="1802" height="1014" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I’m right there with you, but here’s why that camera setup is likely exclusive to the 18 Pro series. Apple likely couldn't find the room to add a telephoto lens to the Duo, so you get just a wide and ultrawide lens. </p><p>So if you want a longer 4x optical zoom, go with the iPhone 18 Pro or Pro Max.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1280px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dwK9C9bzHe8Bqt6sMrUca" name="iPhone 18 Pro Max variable aperture camera.GIF" alt="iPhone 18 Pro Max variable aperture camera." src="https://cdn.mos.cms.futurecdn.net/dwK9C9bzHe8Bqt6sMrUca-1920-80.gif" mos="" align="middle" fullscreen="" width="1280" height="720" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>In addition, Apple added six mechanical blades that expand and contract to the main 48MP camera on the Pros in order to achieve variable aperture. It shifts anywhere from f/1.48 to f/4.0 automatically, or you can customize it using new Pro controls.</p><p>That six-blade mechanism requires physical depth. That's why the thinner foldable iPhone Duo likely can't fit this exact camera suite without adding a massive camera bump. See our in-depth <a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">iPhone 18 Pro Max variable aperture camera testing</a> for some good examples of what you can do.</p><h2 id="39-can-you-actually-edit-cinematic-mode-after-you-record-a-video-now-or-did-i-misread-that-39">'Can you actually edit Cinematic Mode AFTER you record a video now, or did I misread that?'</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="mbQXJpVhh2gJNSgo7i2ixg" name="iPhone 18 Pro Cinematic mode" alt="iPhone 18 Pro Cinematic mode" src="https://cdn.mos.cms.futurecdn.net/mbQXJpVhh2gJNSgo7i2ixg-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>You read that right. And this is probably my favorite software quality-of-life upgrade on the iPhone 18 Pro and Pro Max.</p><p>Historically, if you forgot to select Cinematic Mode <em>before</em> hitting record, you were stuck with standard video. On the 18 Pro series, you can shoot standard 4K video, open up the editor, and toggle Cinematic Mode on or off after the fact right at the top of the display.</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/t7LuoywmKb0" allowfullscreen></iframe></div></div><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/-XgH2ozgkDU" allowfullscreen></iframe></div></div><p>You can see the results above, as the background is more blurred out with Cinematic Mode enabled. It's essentially like Portrait mode for video.</p><p>Apple also added manual shutter speed controls for video and 4K Dolby Vision Timelapses. If you shoot video for social media or YouTube, this gives you way more flexibility in post-production without locking you into specific camera modes up front.</p><h2 id="39-performance-get-the-iphone-18-pro-entertainment-wait-for-the-iphone-duo-39">'Performance = Get the iPhone 18 Pro. Entertainment = Wait for the iPhone Duo.'</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="LnmNWSENsBFHRGRWmcFa7" name="iPhone Duo vs iPhone 18 Pro" alt="iPhone Duo vs iPhone 18 Pro" src="https://cdn.mos.cms.futurecdn.net/LnmNWSENsBFHRGRWmcFa7-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>This is an interesting take on the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-vs-iphone-18-pro-vs-iphone-18-pro-max-heres-the-one-i-recommend">iPhone 18 Pro vs. iPhone Duo</a> comparison.</p><p>The 18 Pro is powered by the 2nm A20 Pro chip. In our benchmark tests, it scored over 4,700 on single-core CPU tests and turned in a massive 45% graphics jump over the 17 Pro Max, also comfortably beating Samsung's Galaxy S26 Ultra across the board.</p><p>The iPhone Duo uses this <em>exact same</em> processor. Our <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen">A20 Pro lab testing</a> proves that this chip has the raw GPU horsepower and 80% thermal stability required to run dual-screen multitasking without overheating or tanking performance.</p><p>However, driving a larger display requires more resources, and it's not clear how much the iPhone Duo's thinner design will impact sustained performance. The bigger difference to me is likely to be battery life, though, as the iPhone 18 Pro Max is rated for 45 hours of video playback versus 31 for the Duo on its main 7.6-inch panel.</p><p>If you want a traditional, ultra-durable slab phone with max camera control and 18+ hours of battery, get the 18 Pro Max. But if you want a dual-screen workstation for media and multitasking, wait for the Duo, because the chip inside should be ready for it.</p><h2 id="39-is-siri-ai-on-ios-27-actually-useful-now-39">'Is Siri AI on iOS 27 actually useful now?'</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="UHFLgbZkizWAuzbea6ATRH" name="iPhone 18 Pro and Pro Max" alt="Siri AI on an iPhone 18 Pro" src="https://cdn.mos.cms.futurecdn.net/UHFLgbZkizWAuzbea6ATRH-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I’m not going to say that <a href="https://www.tomsguide.com/ai/apple-finally-fixed-siri-heres-all-the-features-for-the-new-siri-ai-announced-at-wwdc">Siri AI</a> is smarter than Gemini or ChatGPT yet. But thanks to <a href="https://www.tomsguide.com/phones/iphones/ios-27-7-features-you-need-to-try-first-after-updating">iOS 27</a> and the A20 Pro’s new dual 16-core Neural Engine, which logged a 40% to 48% speed boost in our Geekbench AI lab tests, it’s significantly more helpful.</p><p>The big difference this year is personal context and multi-step voice prompts. Instead of asking Siri to do one basic task at a time, you can do several things at once.</p><p>For example, I could ask for Siri to check my calendar for any openings for lunch with my brother, research restaurants around Bryant Park and include recommended dishes and send a text to him in a single prompt.  </p><p>I just wish that you could talk to Siri in real time while looking at live video, as you can with Gemini and ChatGPT Voice. </p><h2 id="39-is-there-actually-100-more-worth-of-upgrades-here-39">'Is there actually $100 more worth of upgrades here?'</h2><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="zQniEFCJPwZTgNapSzUwAB" name="iPhone 18 Pro Max vs 14 Pro Max LIST" alt="iPhone 18 Pro Max vs 14 Pro Max." src="https://cdn.mos.cms.futurecdn.net/zQniEFCJPwZTgNapSzUwAB-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>This question is referring to the $100 price hike for the iPhone 18 Pro and iPhone 18 Pro Max, which is likely due to the component shortage. So, what does that extra $100 actually buy you under the hood?</p><ul><li>A blazing  A20 Pro chip</li><li>A physical, six-blade mechanical variable aperture main camera</li><li>An internal vapor chamber that's three times larger for sustained cooling</li><li>Upgraded 60W fast charging</li><li>Solid battery life gains for both models</li></ul><p>Whether these upgrades justify the extra cash depends on your current iPhone. If you're coming from an iPhone 17 Pro, paying $100 is a tough sell.</p><p>But if you're upgrading from a an <a href="https://www.tomsguide.com/reviews/iphone-14-pro">iPhone 14 Pro</a> or <a href="https://www.tomsguide.com/reviews/iphone-15-pro">iPhone 15 Pro</a>, that $100 gets you a massive 50% performance leap, real optical aperture control, and over three additional hours of screen time.</p><h2 id="39-should-i-get-the-iphone-18-pro-or-iphone-18-pro-max-39">'Should I get the iPhone 18 Pro or iPhone 18 Pro Max?'</h2><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="ZtKf5v9A9ty5HGwMasFK7f" name="iPhone 18 Pro and Pro Max-4" alt="Apple iPhone 18 Pro Max" src="https://cdn.mos.cms.futurecdn.net/ZtKf5v9A9ty5HGwMasFK7f-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>This is not an easy call. There’s four main differences between the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-vs-iphone-18-pro-which-could-be-the-superior-flagship">iPhone 18 Pro vs iPhone 18 Pro Max</a>.</p><p>No. 1 is the display size. The 6.3-inch OLED panel on the iPhone 18 Pro is great, but the 6.9-inch screen on the Max gives you a more immersive viewing experience for playing games and watching movies. Plus, there’s more info on screen at once when reviewing documents or surfing the web.</p>                    <div class= "tiktok-wrapper" style="min-height: 750px;"><blockquote class="tiktok-embed" cite="https://www.tiktok.com/@mspoonyg/video/7686313211167132941" data-video-id="7686313211167132941" style="max-width: 605px; min-width: 325px;">                        <section>                            <a target="_blank" title="@mspoonyg" href="https://www.tiktok.com/@mspoonyg">@mspoonyg</a>                            <p></p><a target="_blank" title="♬ original sound - mspoonyg" href="https://www.tiktok.com/music/original-sound-7686313250731870990">♬ original sound - mspoonyg</a></section>                    </blockquote></div>                <p>Second, you get more battery life on the iPhone 18 Pro Max, hitting nearly 18.5 hours — which is a bit over 2 hours more than the iPhone 18 Pro.</p><p>On the other hand, the iPhone 18 Pro is more compact and lighter. It’s like having a stealth bomber in your pocket with all that A20 Pro power. And the iPhone 18 Pro starts at $100 less. That might not seem like much but you can put that savings towards additional storage.</p><p>For me I’d get the iPhone 18 Pro Max but it really comes down to screen size and price.</p><h2 id="bottom-line-7">Bottom line</h2><p>The iPhone 18 Pro and Pro Max might not look radically different at first glance,  but underneath, the A20 Pro chip, camera hardware, and thermal redesign set a new baseline for Apple flagships.</p><p>Did we answer your key questions about the 18 Pro series? Are you picking one up, or holding out for our full iPhone Duo review? Let us know in the comments! </p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/i-spent-30-minutes-with-the-iphone-duo-3-things-you-just-dont-get-from-the-pictures">I spent 30 minutes with the iPhone Duo — 3 things you just don’t get from the pictures</a></li><li><a href="https://www.tomsguide.com/phones/i-put-the-iphone-18-pro-max-vs-galaxy-s26-ultra">I put the iPhone 18 Pro Max vs. Galaxy S26 Ultra through a 7-round face-off — here’s the winner</a></li><li><a href="https://www.tomsguide.com/ai/i-replaced-chatgpt-with-siri-ai-for-a-day-heres-what-surprised-me">I replaced ChatGPT with Siri AI for a day — here's what surprised me</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I spent 30 minutes with the iPhone Duo — 3 things you just don’t get from the pictures ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I have a confession to make: When I first saw the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> announced at September’s <a href="https://www.tomsguide.com/news/live/apple-event-live-foldable-iphone-iphone-18-pro-max-apple-watch-12-and-all-the-big-news">‘Surprise and shine’ keynote</a>, I was happy to see Apple enter the foldable market — but I wasn’t entirely sold on the device.</p><p>My limited <a href="https://www.tomsguide.com/opinion/i-ditched-the-iphone-15-pro-for-the-oneplus-open-5-things-i-discovered-after-using-a-foldable">experience with various Android foldables has been positive</a> — but it’s always left me feeling like I’d rather pair a small regular phone with a mini tablet instead of having them sandwiched together. So I went into a brief hands-on demo with the iPhone Duo this week with a healthy amount of skepticism.</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/2qNfOa5AuVU" allowfullscreen></iframe></div></div><p>Of course, I’m going to reserve full judgment for when Tom’s Guide can test and review the device properly — but three things immediately stood out to me after spending a half hour with Apple's $1,999 handset. </p><p>These were things you just don’t appreciate when you look at pictures or watch videos of the device; you need to hold it in your hand to really appreciate them. And I’m not talking about <a href="https://www.tomsguide.com/phones/iphones/iphone-ultra-heres-how-apple-is-reportedly-erasing-the-crease-for-its-foldable-phone">the crease</a>.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-W2EK0e"></div>                            </div>                            <script src="https://kwizly.com/embed/W2EK0e.js" async></script><h3 class="article-body__section" id="section-the-weighting-is-perfect"><span>The weighting is perfect</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="rSoCvpXGwqJDaxV5wFWorU" name="iPhone Duo-4" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/rSoCvpXGwqJDaxV5wFWorU-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>In an effort to make folding phones as thin and light as possible when folded, I’ve noticed they sometimes feel too flimsy when unfolded. Case in point is last year's <a href="https://www.tomsguide.com/phones/android-phones/oppo-find-n5-review-simply-superior">Oppo Find N5</a>, which is the foldable I've spent the most time with and measures just 4.21mm when open (8.93mm thick when folded) and weighs 229 grams (8.07 ounces).</p><p>The iPhone Duo, by comparison, is 5.2mm when open and weighs 254 grams (8.96 ounces). If your first instinct is to shudder and recoil because <em>thinner and lighter is always better</em>, then I’m here to tell you it’s not the case when you hold the device in your hand. </p><p>Part of the reason I like using a tablet is that there’s some degree of heft and chunk that you can actually grip onto when you’re reading, sketching or watching something. Not enough to make your arm sore, of course, but enough to make it feel like you’re holding something that won’t snap in half. The iPhone Duo nails that balance perfectly, and it was super reassuring the second I picked it up off the display table.</p><h3 class="article-body__section" id="section-the-matte-display-rocks"><span>The matte display rocks</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vYM5tTFWZqoCzzH8Kj9EHV" name="iPhone Duo-3" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/vYM5tTFWZqoCzzH8Kj9EHV-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>I’m not going to talk about the crease (yes there is one, and yes, you can see it if you look closely) or the animation, but what was really cool about the Duo’s inner display was the Nano-texture finish. It gives it this epic level of matte quality that Apple says is scratch-resistant and 40 percent stiffer than the competition. </p><p>My use case for foldable phones is chiefly about productivity — for my sins I look at spreadsheets more than Netflix movies while commuting — and the Duo’s inner display is so easy on the eyes I couldn’t help but feel it’d be perfect for this. Reflective glare from aggressive overhead lighting is expertly muted by this matte texture for readability and functionality. </p><p>If you want to read ebooks, or when you come to use an Apple Pencil to sketch or take notes, I’m convinced the decision to go matte will make this a quality experience.</p><h3 class="article-body__section" id="section-it-s-a-fingerprint-magnet"><span>It’s a fingerprint magnet</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="tMqrxu9xgE5keuWLjFoH4V" name="iPhone Duo-7" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/tMqrxu9xgE5keuWLjFoH4V-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>Okay, this isn’t exactly a positive point, but I need to make it anyway. The iPhone Duo comes in two shades: Star White and Night Sky. And the latter seemed — to me, at least — a fingerprint magnet. In all the images, you’re likely to see the finely polished Ceramic Shield back looking flawless. And it does... until you start pawing at it with greasy fingers. For what it's worth, I didn’t notice this as much on the Star White colorway.</p><p>It seems petty to dunk on such a well-engineered device for something so trivial, especially since Apple has achieved an IP68 protection rating. That means it's safe against both water and dust and (as with the weight example above) this really does feel like a durable device in the hand. If you're one of the people who wraps their iPhone up in a case anyway, then you can completely ignore this entire point.</p><h3 class="article-body__section" id="section-bottom-line"><span>Bottom line</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="JvujTtKZVT9EXJzzqh9FHV" name="iPhone Duo-LIST2" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/JvujTtKZVT9EXJzzqh9FHV-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>There is, of course, way more to unpack with the iPhone Duo when it hits the market in October. And I have more thoughts on things like the camera performance and iOS 27 that I’ll write up if and when I get more time with it. But the points above were just what sprung instantly to mind the minute I picked it up. If you want more, read my colleague Mark’s <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">in-depth hands-on with the Duo</a> following his experience with it at Apple Park.</p><p>But from my very brief time with it, my takeaway is that Apple’s long-awaited entry into the foldable phone category has arrived in style. Everything from the feeling of snapping it shut to the way the passport-style form factor nestles into your palm is sublime. There’s certainly a high price of entry, but after using the iPhone Duo myself, I think a <a href="https://www.tomsguide.com/phones/iphones/i-have-not-been-this-excited-about-apple-in-a-long-time-toms-guides-readers-react-to-the-iphone-duo">lot of people will be willing to pay it</a> once they actually get to experience it in their own hands.</p><p>Let me know what your thoughts are about the iPhone Duo in the comments below. Are you interested in trying one, or are you happy with a regular, non-folding phone? I’d love to hear from you.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo hands-on</a></li><li><a href="https://www.tomsguide.com/phones/iphones/best-iphone-18-pro-and-pro-max-deals">iPhone 18 Pro and Pro Max deals are live — here's the biggest discounts at T-Mobile, Verizon and more</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">I tested the iPhone 18 Pro Max's variable aperture camera — here's the results</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/i-spent-30-minutes-with-the-iphone-duo-3-things-you-just-dont-get-from-the-pictures</link>
                                                                            <description>
                            <![CDATA[ After a 30-minute demo session with the folding iPhone Duo, I came away with three clear impressions you just don’t get from the pictures of it ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">VVamj5XisisDkxmEQUSJcC</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/GTrSzbvbSigPgscpMS3JsU-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 09:45:00 +0000</pubDate>                                                                                                                                <updated>Mon, 21 Sep 2026 14:53:18 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ jeff.parsons@futurenet.com (Jeff Parsons) ]]></author>                    <dc:creator><![CDATA[ Jeff Parsons ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/7z3UTGGrmSokMKxTWHmhjX-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Jeff is U.K. Editor-in-Chief for Tom’s Guide looking after the day-to-day output of the site’s British contingent. &lt;/p&gt;&lt;p&gt;Rising early and heading straight for the coffee machine, Jeff loves nothing more than dialling into the zeitgeist of the day’s tech news. A journalist for over a decade, he&#039;s travelled around the world testing and reviewing any gadget he can get his hands on.&lt;/p&gt;&lt;p&gt;Before joining the team at Tom’s Guide, Jeff covered technology and science for two of the U.K.’s biggest national news sites: Metro.co.uk and the Daily Mirror. Memorable moments include getting lost in Vienna in an electric Audi, touring Lockheed Martin’s mile-long jet factory in Fort Worth and filming a Netflix documentary about Elon Musk in West London.&lt;/p&gt;&lt;p&gt;When not plugged into the current news agenda, editing or commissioning a series of articles or debating the merits of Apple vs Android, Jeff can usually be found out for a run trying to shave precious seconds off his PB. Or lifting weights in a vain attempt to offset the ageing process.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/GTrSzbvbSigPgscpMS3JsU-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide / Jeff Parsons]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone Duo hands-on pictures]]></media:description>                                                            <media:text><![CDATA[iPhone Duo hands-on pictures]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone Duo hands-on pictures]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/GTrSzbvbSigPgscpMS3JsU-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I have a confession to make: When I first saw the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> announced at September’s <a href="https://www.tomsguide.com/news/live/apple-event-live-foldable-iphone-iphone-18-pro-max-apple-watch-12-and-all-the-big-news">‘Surprise and shine’ keynote</a>, I was happy to see Apple enter the foldable market — but I wasn’t entirely sold on the device.</p><p>My limited <a href="https://www.tomsguide.com/opinion/i-ditched-the-iphone-15-pro-for-the-oneplus-open-5-things-i-discovered-after-using-a-foldable">experience with various Android foldables has been positive</a> — but it’s always left me feeling like I’d rather pair a small regular phone with a mini tablet instead of having them sandwiched together. So I went into a brief hands-on demo with the iPhone Duo this week with a healthy amount of skepticism.</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/2qNfOa5AuVU" allowfullscreen></iframe></div></div><p>Of course, I’m going to reserve full judgment for when Tom’s Guide can test and review the device properly — but three things immediately stood out to me after spending a half hour with Apple's $1,999 handset. </p><p>These were things you just don’t appreciate when you look at pictures or watch videos of the device; you need to hold it in your hand to really appreciate them. And I’m not talking about <a href="https://www.tomsguide.com/phones/iphones/iphone-ultra-heres-how-apple-is-reportedly-erasing-the-crease-for-its-foldable-phone">the crease</a>.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-W2EK0e"></div>                            </div>                            <script src="https://kwizly.com/embed/W2EK0e.js" async></script><h3 class="article-body__section" id="section-the-weighting-is-perfect"><span>The weighting is perfect</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="rSoCvpXGwqJDaxV5wFWorU" name="iPhone Duo-4" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/rSoCvpXGwqJDaxV5wFWorU-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>In an effort to make folding phones as thin and light as possible when folded, I’ve noticed they sometimes feel too flimsy when unfolded. Case in point is last year's <a href="https://www.tomsguide.com/phones/android-phones/oppo-find-n5-review-simply-superior">Oppo Find N5</a>, which is the foldable I've spent the most time with and measures just 4.21mm when open (8.93mm thick when folded) and weighs 229 grams (8.07 ounces).</p><p>The iPhone Duo, by comparison, is 5.2mm when open and weighs 254 grams (8.96 ounces). If your first instinct is to shudder and recoil because <em>thinner and lighter is always better</em>, then I’m here to tell you it’s not the case when you hold the device in your hand. </p><p>Part of the reason I like using a tablet is that there’s some degree of heft and chunk that you can actually grip onto when you’re reading, sketching or watching something. Not enough to make your arm sore, of course, but enough to make it feel like you’re holding something that won’t snap in half. The iPhone Duo nails that balance perfectly, and it was super reassuring the second I picked it up off the display table.</p><h3 class="article-body__section" id="section-the-matte-display-rocks"><span>The matte display rocks</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vYM5tTFWZqoCzzH8Kj9EHV" name="iPhone Duo-3" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/vYM5tTFWZqoCzzH8Kj9EHV-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>I’m not going to talk about the crease (yes there is one, and yes, you can see it if you look closely) or the animation, but what was really cool about the Duo’s inner display was the Nano-texture finish. It gives it this epic level of matte quality that Apple says is scratch-resistant and 40 percent stiffer than the competition. </p><p>My use case for foldable phones is chiefly about productivity — for my sins I look at spreadsheets more than Netflix movies while commuting — and the Duo’s inner display is so easy on the eyes I couldn’t help but feel it’d be perfect for this. Reflective glare from aggressive overhead lighting is expertly muted by this matte texture for readability and functionality. </p><p>If you want to read ebooks, or when you come to use an Apple Pencil to sketch or take notes, I’m convinced the decision to go matte will make this a quality experience.</p><h3 class="article-body__section" id="section-it-s-a-fingerprint-magnet"><span>It’s a fingerprint magnet</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="tMqrxu9xgE5keuWLjFoH4V" name="iPhone Duo-7" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/tMqrxu9xgE5keuWLjFoH4V-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>Okay, this isn’t exactly a positive point, but I need to make it anyway. The iPhone Duo comes in two shades: Star White and Night Sky. And the latter seemed — to me, at least — a fingerprint magnet. In all the images, you’re likely to see the finely polished Ceramic Shield back looking flawless. And it does... until you start pawing at it with greasy fingers. For what it's worth, I didn’t notice this as much on the Star White colorway.</p><p>It seems petty to dunk on such a well-engineered device for something so trivial, especially since Apple has achieved an IP68 protection rating. That means it's safe against both water and dust and (as with the weight example above) this really does feel like a durable device in the hand. If you're one of the people who wraps their iPhone up in a case anyway, then you can completely ignore this entire point.</p><h3 class="article-body__section" id="section-bottom-line"><span>Bottom line</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="JvujTtKZVT9EXJzzqh9FHV" name="iPhone Duo-LIST2" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/JvujTtKZVT9EXJzzqh9FHV-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>There is, of course, way more to unpack with the iPhone Duo when it hits the market in October. And I have more thoughts on things like the camera performance and iOS 27 that I’ll write up if and when I get more time with it. But the points above were just what sprung instantly to mind the minute I picked it up. If you want more, read my colleague Mark’s <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">in-depth hands-on with the Duo</a> following his experience with it at Apple Park.</p><p>But from my very brief time with it, my takeaway is that Apple’s long-awaited entry into the foldable phone category has arrived in style. Everything from the feeling of snapping it shut to the way the passport-style form factor nestles into your palm is sublime. There’s certainly a high price of entry, but after using the iPhone Duo myself, I think a <a href="https://www.tomsguide.com/phones/iphones/i-have-not-been-this-excited-about-apple-in-a-long-time-toms-guides-readers-react-to-the-iphone-duo">lot of people will be willing to pay it</a> once they actually get to experience it in their own hands.</p><p>Let me know what your thoughts are about the iPhone Duo in the comments below. Are you interested in trying one, or are you happy with a regular, non-folding phone? I’d love to hear from you.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo hands-on</a></li><li><a href="https://www.tomsguide.com/phones/iphones/best-iphone-18-pro-and-pro-max-deals">iPhone 18 Pro and Pro Max deals are live — here's the biggest discounts at T-Mobile, Verizon and more</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">I tested the iPhone 18 Pro Max's variable aperture camera — here's the results</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Forget variable aperture! The real upgrade with the iPhone 18 Pro Max is Pro Controls ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I’ve been dinging Apple for years for holding back on giving serious shooters like me what we’ve been asking for: true manual camera controls. But while testing the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max</a>, I found myself initially distracted by another headline grabber: the <a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">variable aperture camera</a>.</p><p>To be fair, it genuinely changes the mechanics of shooting with a phone — not just an iPhone. Instead of relying on simulated portrait blur, you get authentic optical depth of field and true light control. That's the exact tool I want when dialed into chasing a specific aesthetic.</p><p>But the longer I’ve spent working inside Apple’s revamped Camera app, the more I’ve realized my attention was pulled in the wrong direction. The real star of the show isn't the moving physical blades — it’s Pro Controls. Here’s why.</p><div class="youtube-video" data-nosnippet ><div class="video-aspect-box"><iframe data-lazy-priority="low" data-lazy-src="https://www.youtube-nocookie.com/embed/sqaV5mFJav8" allowfullscreen></iframe></div></div><h2 id="not-all-iphones-get-it">Not all iPhones get it</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vkrHAQnia6j8yUVnx2mZfB" name="iPhone 18 Pro Max camera" alt="iPhone 18 Pro Max camera." src="https://cdn.mos.cms.futurecdn.net/vkrHAQnia6j8yUVnx2mZfB-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>Pro Controls finally makes the native iOS Camera app feel less like a basic point-and-shoot and more like a serious mirrorless rig. Quite simply, it’s the dedicated manual shooting suite I’ve been demanding for years, with granular controls for exposure, shutter speed, white balance, focus, aperture, resolution, and more. Best of all, these tools are accessible right from the viewfinder — no more jumping into the system Settings just to tweak a shooting parameter. But there’s a catch.</p><p>Apple is keeping the feature strictly walled off, making it exclusive to the iPhone 18 Pro and iPhone 18 Pro Max. I was crossing my fingers that it might trickle down to the <a href="https://www.tomsguide.com/phones/iphones/iphone-17-pro-max-7-reasons-to-buy-and-3-reasons-to-skip">iPhone 17 Pro</a> series via the official iOS 27 update, but that’s not happening. Just as surprising, the upcoming <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> <em>won’t</em> get Pro Controls either.</p><h2 id="a-familiar-layout-with-depth-under-the-hood">A familiar layout with depth under the hood</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1510px;"><p class="vanilla-image-block" style="padding-top:59.60%;"><img id="ZgAP8qUs7NPRCpFJNvsDPT" name="Pro Controls - Shutter Speed" alt="Pro Controls screenshot." src="https://cdn.mos.cms.futurecdn.net/ZgAP8qUs7NPRCpFJNvsDPT-1920-80.jpg" mos="" align="middle" fullscreen="" width="1510" height="900" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Along the edge of the viewfinder are the essential toggles for white balance, aperture, exposure compensation, flash, and Live Photos. They remain there for quick, one-tap access, but reaching the rest of the Pro Controls requires digging a little deeper by tapping the camera settings icon. </p><p>Doing so opens a floating overlay where you can adjust shutter speed, manual focus, format options, and more. It’s also where you can toggle a live histogram, select a Photographic Style, or tweak Night mode.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1510px;"><p class="vanilla-image-block" style="padding-top:59.60%;"><img id="miLQZkZ6dUcskubbKtQ5LK" name="iPhone 18 Pro Max iPhone 18 Pro Max Pro Controls" alt="Pro Controls screen shot." src="https://cdn.mos.cms.futurecdn.net/miLQZkZ6dUcskubbKtQ5LK-1920-80.jpg" mos="" align="middle" fullscreen="" width="1510" height="900" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Interestingly, Apple includes separate controls for aperture and depth. The former physically moves the blades on the main sensor to cycle through four hardware aperture stops, while the latter controls simulated bokeh — fake background blur, as I call it. Both have their place, but I far prefer the authentic falloff of the physical aperture.</p><p>If there’s one issue I have with this setup, it’s that there doesn't appear to be a way to customize which parameters stay pinned to the primary screen. Personally, I couldn't care less about Live Photos or the flash. I just hope Apple realizes this and gives shooters the freedom to organize the layout that best suits them with subsequent software updates.</p><h2 id="video-also-gets-the-pro-treatment">Video also gets the Pro treatment</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1510px;"><p class="vanilla-image-block" style="padding-top:59.60%;"><img id="Z7NbTK7YxsaDrmPyWFa4LK" name="iPhone 18 Pro Max iPhone 18 Pro Max Pro Controls" alt="Pro Controls screen shot." src="https://cdn.mos.cms.futurecdn.net/Z7NbTK7YxsaDrmPyWFa4LK-1920-80.jpg" mos="" align="middle" fullscreen="" width="1510" height="900" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Stills aren’t the only beneficiary on the iPhone 18 Pro series — Pro Controls makes its way over to video recording as well. While the suite isn’t quite as extensive as the photo side, Apple included the two parameters that matter most for serious video work: physical aperture and manual shutter speed.</p><p>Unlocking shutter speed is a huge win for videographers like me who juggle multi-camera workflows. Previous iPhones locked shutter speed behind automated computational exposure, often resulting in unnatural or jittery motion blur that.</p><p>Being able to manually dial in your shutter speed makes it far easier to cut footage from the iPhone 18 Pro alongside dedicated cameras. For instance, you can lock in at 1/50 or 1/60 to maintain natural motion blur, or crank it to 1/240 to give fast-paced action sequences that dramatic edge.</p><h2 id="bottom-line-8">Bottom line</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="MNt6boVo4QsPRZW9F5qafB" name="iPhone 18 Pro Max camera" alt="iPhone 18 Pro Max camera held in the hand." src="https://cdn.mos.cms.futurecdn.net/MNt6boVo4QsPRZW9F5qafB-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>At the end of the day, Pro Controls is the real camera upgrade I’ve been asking for because I no longer need to rely on third-party apps just to take full creative command of a shot. Everything I need is finally baked directly into the native Camera app, with zero subscription fees or clunky workarounds.</p><p>The only glaring omission left on the table is manual ISO control, which Apple stubbornly keeps locked down. Even with that limitation, Pro Controls is the definitive feature that transforms the iPhone 18 Pro series from a mere point-and-shoot smartphone into a genuine creative powerhouse.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Oo29oW"></div>                            </div>                            <script src="https://kwizly.com/embed/Oo29oW.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/apple-hid-a-retro-mac-easter-egg-inside-ios-27-heres-how-to-find-it"><strong>iOS 27 has a hidden Mac Easter egg — here's how to trigger it</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen"><strong>iPhone 18 Pro benchmarks: Apple just built the most powerful phones we've ever seen</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-18-pro-battery-life-tested-the-results-are-surprising"><strong>iPhone 18 Pro Max and 18 Pro battery life tested — the results are surprising</strong></a><strong></strong></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/forget-variable-aperture-the-real-upgrade-with-the-iphone-18-pro-max-is-pro-controls</link>
                                                                            <description>
                            <![CDATA[ While the iPhone 18 Pro Max's variable aperture gets all the attention, the introduction of native Pro Controls is the real upgrade I've been asking for. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">mjH3ocwjrFHDCfWsfW4MKR</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/fSfcu82S2PYwmZZN7nthvB-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 05:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ john.velasco@futurenet.com (John Velasco) ]]></author>                    <dc:creator><![CDATA[ John Velasco ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/TSj224oX8d5ERXaDs8pDGd-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/fSfcu82S2PYwmZZN7nthvB-1920-80.jpg">
                                                            <media:credit><![CDATA[John Velasco / Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 18 Pro Max camera.]]></media:description>                                                            <media:text><![CDATA[iPhone 18 Pro Max camera.]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 18 Pro Max camera.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/fSfcu82S2PYwmZZN7nthvB-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I’ve been dinging Apple for years for holding back on giving serious shooters like me what we’ve been asking for: true manual camera controls. But while testing the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max</a>, I found myself initially distracted by another headline grabber: the <a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">variable aperture camera</a>.</p><p>To be fair, it genuinely changes the mechanics of shooting with a phone — not just an iPhone. Instead of relying on simulated portrait blur, you get authentic optical depth of field and true light control. That's the exact tool I want when dialed into chasing a specific aesthetic.</p><p>But the longer I’ve spent working inside Apple’s revamped Camera app, the more I’ve realized my attention was pulled in the wrong direction. The real star of the show isn't the moving physical blades — it’s Pro Controls. Here’s why.</p><div class="youtube-video" data-nosnippet ><div class="video-aspect-box"><iframe data-lazy-priority="low" data-lazy-src="https://www.youtube-nocookie.com/embed/sqaV5mFJav8" allowfullscreen></iframe></div></div><h2 id="not-all-iphones-get-it">Not all iPhones get it</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vkrHAQnia6j8yUVnx2mZfB" name="iPhone 18 Pro Max camera" alt="iPhone 18 Pro Max camera." src="https://cdn.mos.cms.futurecdn.net/vkrHAQnia6j8yUVnx2mZfB-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>Pro Controls finally makes the native iOS Camera app feel less like a basic point-and-shoot and more like a serious mirrorless rig. Quite simply, it’s the dedicated manual shooting suite I’ve been demanding for years, with granular controls for exposure, shutter speed, white balance, focus, aperture, resolution, and more. Best of all, these tools are accessible right from the viewfinder — no more jumping into the system Settings just to tweak a shooting parameter. But there’s a catch.</p><p>Apple is keeping the feature strictly walled off, making it exclusive to the iPhone 18 Pro and iPhone 18 Pro Max. I was crossing my fingers that it might trickle down to the <a href="https://www.tomsguide.com/phones/iphones/iphone-17-pro-max-7-reasons-to-buy-and-3-reasons-to-skip">iPhone 17 Pro</a> series via the official iOS 27 update, but that’s not happening. Just as surprising, the upcoming <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> <em>won’t</em> get Pro Controls either.</p><h2 id="a-familiar-layout-with-depth-under-the-hood">A familiar layout with depth under the hood</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1510px;"><p class="vanilla-image-block" style="padding-top:59.60%;"><img id="ZgAP8qUs7NPRCpFJNvsDPT" name="Pro Controls - Shutter Speed" alt="Pro Controls screenshot." src="https://cdn.mos.cms.futurecdn.net/ZgAP8qUs7NPRCpFJNvsDPT-1920-80.jpg" mos="" align="middle" fullscreen="" width="1510" height="900" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Along the edge of the viewfinder are the essential toggles for white balance, aperture, exposure compensation, flash, and Live Photos. They remain there for quick, one-tap access, but reaching the rest of the Pro Controls requires digging a little deeper by tapping the camera settings icon. </p><p>Doing so opens a floating overlay where you can adjust shutter speed, manual focus, format options, and more. It’s also where you can toggle a live histogram, select a Photographic Style, or tweak Night mode.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1510px;"><p class="vanilla-image-block" style="padding-top:59.60%;"><img id="miLQZkZ6dUcskubbKtQ5LK" name="iPhone 18 Pro Max iPhone 18 Pro Max Pro Controls" alt="Pro Controls screen shot." src="https://cdn.mos.cms.futurecdn.net/miLQZkZ6dUcskubbKtQ5LK-1920-80.jpg" mos="" align="middle" fullscreen="" width="1510" height="900" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Interestingly, Apple includes separate controls for aperture and depth. The former physically moves the blades on the main sensor to cycle through four hardware aperture stops, while the latter controls simulated bokeh — fake background blur, as I call it. Both have their place, but I far prefer the authentic falloff of the physical aperture.</p><p>If there’s one issue I have with this setup, it’s that there doesn't appear to be a way to customize which parameters stay pinned to the primary screen. Personally, I couldn't care less about Live Photos or the flash. I just hope Apple realizes this and gives shooters the freedom to organize the layout that best suits them with subsequent software updates.</p><h2 id="video-also-gets-the-pro-treatment">Video also gets the Pro treatment</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1510px;"><p class="vanilla-image-block" style="padding-top:59.60%;"><img id="Z7NbTK7YxsaDrmPyWFa4LK" name="iPhone 18 Pro Max iPhone 18 Pro Max Pro Controls" alt="Pro Controls screen shot." src="https://cdn.mos.cms.futurecdn.net/Z7NbTK7YxsaDrmPyWFa4LK-1920-80.jpg" mos="" align="middle" fullscreen="" width="1510" height="900" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Stills aren’t the only beneficiary on the iPhone 18 Pro series — Pro Controls makes its way over to video recording as well. While the suite isn’t quite as extensive as the photo side, Apple included the two parameters that matter most for serious video work: physical aperture and manual shutter speed.</p><p>Unlocking shutter speed is a huge win for videographers like me who juggle multi-camera workflows. Previous iPhones locked shutter speed behind automated computational exposure, often resulting in unnatural or jittery motion blur that.</p><p>Being able to manually dial in your shutter speed makes it far easier to cut footage from the iPhone 18 Pro alongside dedicated cameras. For instance, you can lock in at 1/50 or 1/60 to maintain natural motion blur, or crank it to 1/240 to give fast-paced action sequences that dramatic edge.</p><h2 id="bottom-line-8">Bottom line</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="MNt6boVo4QsPRZW9F5qafB" name="iPhone 18 Pro Max camera" alt="iPhone 18 Pro Max camera held in the hand." src="https://cdn.mos.cms.futurecdn.net/MNt6boVo4QsPRZW9F5qafB-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>At the end of the day, Pro Controls is the real camera upgrade I’ve been asking for because I no longer need to rely on third-party apps just to take full creative command of a shot. Everything I need is finally baked directly into the native Camera app, with zero subscription fees or clunky workarounds.</p><p>The only glaring omission left on the table is manual ISO control, which Apple stubbornly keeps locked down. Even with that limitation, Pro Controls is the definitive feature that transforms the iPhone 18 Pro series from a mere point-and-shoot smartphone into a genuine creative powerhouse.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Oo29oW"></div>                            </div>                            <script src="https://kwizly.com/embed/Oo29oW.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/apple-hid-a-retro-mac-easter-egg-inside-ios-27-heres-how-to-find-it"><strong>iOS 27 has a hidden Mac Easter egg — here's how to trigger it</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen"><strong>iPhone 18 Pro benchmarks: Apple just built the most powerful phones we've ever seen</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-18-pro-battery-life-tested-the-results-are-surprising"><strong>iPhone 18 Pro Max and 18 Pro battery life tested — the results are surprising</strong></a><strong></strong></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Apple added 5 new lock screen tools in iOS 27 — here's what to change first ]]></title>
                                                                                                <dc:content><![CDATA[ <p>For years, your iPhone’s lock screen was designed around Apple’s rigid aesthetic rules rather than your personal taste.</p><p>With the release of <a href="https://www.tomsguide.com/phones/iphones/ios-27-7-features-you-need-to-try-first-after-updating">iOS 27</a>, Apple has finally handed full visual control back to users. Alongside system-wide refinements to the frosted Liquid Glass interface, the update introduces five key settings that let you strip away visual clutter, resize UI elements, and shape your display to look like you designed it yourself.</p><p>If your iPhone is running iOS 27, taking a few minutes to tweak these controls will completely change how your phone looks every time you pick it up.</p><h3 class="article-body__section" id="section-5-new-lock-screen-tools-in-ios-27"><span>5 new lock screen tools in iOS 27 </span></h3><section class="howto-block">                    <h3>Fine-tune transparency with the Liquid Glass slider</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/UQ98FkNG6uR8qoVpLAYRAn.jpg"                                        alt="Liquid glass slider in iOS 27 highlighted "                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/UQ98FkNG6uR8qoVpLAYRAn.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>When Apple introduced the frosted Liquid Glass aesthetic, users were limited to basic "Clear" or "Tinted" presets. In iOS 27, those rigid toggles have been replaced with a smooth, continuous opacity slider.</p><p>To adjust it, <strong>open Settings, tap Appearance, and select Liquid Glass</strong>. </p><p>Dragging the slider to the left increases transparency for a completely clear view of your wallpaper beneath menus and widgets. </p><p>Sliding to the right deepens the tint, improving text contrast and readability. Because the preview updates in real time, you can dial in the exact balance before exiting. </p></p>                </section><section class="howto-block">                    <h3>Shrink or relocate the oversized clock</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/t3eDtDNVmmfU4mMNRq7K86.jpg"                                        alt="How to customize your iPhone clock in iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/t3eDtDNVmmfU4mMNRq7K86.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>The massive digital clock centered at the top of the lock screen has long dominated precious wallpaper real estate. iOS 27 allows you to shrink it or move it out of the way entirely.</p><p><strong>Press and hold your lock screen, tap Customize, and select the clock</strong> frame. From here, you can reduce the font size or shift the clock up into the top widget row. Keeping photos of family, pets, or landscapes from competing with the time and date display.</p></p>                </section><section class="howto-block">                    <h3>Expand wallpapers with Apple Intelligence </h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/GgUA5PMQADNzL9gCvdd4V6.jpg"                                        alt="How to extend iPhone wallpaper in iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/GgUA5PMQADNzL9gCvdd4V6.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>Setting a favorite photo as your wallpaper often results in awkward cropping, cut-off heads, or exposed black bars if the image ratio does not match your screen.</p><p>iOS 27 solves this with Extend, an Apple Intelligence tool that generates new background detail around image edges.<strong> </strong></p><p><strong>Go to Settings, tap Wallpaper, select Add New Wallpaper, and pick your photo</strong>. Then <strong>tap the three dots in the bottom corner and select Extend Wallpaper</strong>. </p><p>The system automatically generates matching sky, scenery, or texture to fill the gaps, while simultaneously leveling out slightly tilted horizons.</p></p>                </section><section class="howto-block">                    <h3>Dismiss the Now Playing widget without stopping playback</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/E5efiZ7QqDZVMw2uQUwjgA.jpg"                                        alt="How to remove playback controls on iPhone in iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/E5efiZ7QqDZVMw2uQUwjgA.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>In previous versions of iOS, playing music, podcasts, or audiobooks forced a massive "Now Playing" widget onto your lock screen until playback stopped completely.</p><p>In iOS 27, you can dismiss the media controller whenever you want a clean view of your background. When the widget appears on your lock screen,<strong> simply swipe left across the playback controls</strong>. </p><p>This instantly hides the card and clears its status indicator from the Dynamic Island while your audio continues playing uninterrupted in the background.</p></p>                </section><section class="howto-block">                    <h3>Generate custom wallpapers using Image Playground</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/aMSJe24ZoPiGNkKPLwMuig.jpg"                                        alt="How to create your own iPhone wallpapers using Image Playground in iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/aMSJe24ZoPiGNkKPLwMuig.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>If you cannot find the right photo in your camera roll, you can generate custom high-resolution backgrounds directly from the wallpaper menu.</p><p>While customizing a new wallpaper, select <strong>Image Playground</strong> from the menu options. <strong>Type a quick description of the scene </strong>you want to create, then <strong>select a visual style  </strong>—such as Animation, Illustration, or Sketch. </p><p>Apple Intelligence will generate a unique background on the spot, allowing you to tweak elements or apply matching color filters before setting it to your lock screen.</p></p>                </section><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X81pNe"></div>                            </div>                            <script src="https://kwizly.com/embed/X81pNe.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/ios-27-quietly-fixes-the-most-annoying-iphone-workaround-we-all-use"><strong>iOS 27 finally fixes the most annoying iPhone workaround we all use</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/how-to-turn-off-ios-27s-automatic-subtitles-that-no-one-asked-for"><strong>How to disable iOS 27’s auto-subtitles for good</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/ive-been-testing-siri-ai-in-ios-27-for-3-weeks-7-things-to-try-first-and-the-feature-that-won-me-over"><strong>I've been testing Siri AI in iOS 27 for 3 weeks: 7 things to try first (and the feature that won me over)</strong></a><strong></strong></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/apple-added-5-new-lock-screen-tools-in-ios-27-heres-what-to-change-first</link>
                                                                            <description>
                            <![CDATA[ in iOS 27, four new customization options let you finally make your iPhone's lock screen your own. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">es6rUbG7hFLGQ5WXukmhdN</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/X6fmuNsHuHTG4oNkiyewqY-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 10:45:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ kaycee.hill@futurenet.com (Kaycee Hill) ]]></author>                    <dc:creator><![CDATA[ Kaycee Hill ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/xHn6RmpEqg87cvtLwrBu9G-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/X6fmuNsHuHTG4oNkiyewqY-1920-80.jpg">
                                                            <media:credit><![CDATA[Sanuj Bhatia / Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Hands on with various iOS 27 features]]></media:description>                                                            <media:text><![CDATA[Hands on with various iOS 27 features]]></media:text>
                                <media:title type="plain"><![CDATA[Hands on with various iOS 27 features]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/X6fmuNsHuHTG4oNkiyewqY-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>For years, your iPhone’s lock screen was designed around Apple’s rigid aesthetic rules rather than your personal taste.</p><p>With the release of <a href="https://www.tomsguide.com/phones/iphones/ios-27-7-features-you-need-to-try-first-after-updating">iOS 27</a>, Apple has finally handed full visual control back to users. Alongside system-wide refinements to the frosted Liquid Glass interface, the update introduces five key settings that let you strip away visual clutter, resize UI elements, and shape your display to look like you designed it yourself.</p><p>If your iPhone is running iOS 27, taking a few minutes to tweak these controls will completely change how your phone looks every time you pick it up.</p><h3 class="article-body__section" id="section-5-new-lock-screen-tools-in-ios-27"><span>5 new lock screen tools in iOS 27 </span></h3><section class="howto-block">                    <h3>Fine-tune transparency with the Liquid Glass slider</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/UQ98FkNG6uR8qoVpLAYRAn.jpg"                                        alt="Liquid glass slider in iOS 27 highlighted "                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/UQ98FkNG6uR8qoVpLAYRAn.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>When Apple introduced the frosted Liquid Glass aesthetic, users were limited to basic "Clear" or "Tinted" presets. In iOS 27, those rigid toggles have been replaced with a smooth, continuous opacity slider.</p><p>To adjust it, <strong>open Settings, tap Appearance, and select Liquid Glass</strong>. </p><p>Dragging the slider to the left increases transparency for a completely clear view of your wallpaper beneath menus and widgets. </p><p>Sliding to the right deepens the tint, improving text contrast and readability. Because the preview updates in real time, you can dial in the exact balance before exiting. </p></p>                </section><section class="howto-block">                    <h3>Shrink or relocate the oversized clock</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/t3eDtDNVmmfU4mMNRq7K86.jpg"                                        alt="How to customize your iPhone clock in iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/t3eDtDNVmmfU4mMNRq7K86.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>The massive digital clock centered at the top of the lock screen has long dominated precious wallpaper real estate. iOS 27 allows you to shrink it or move it out of the way entirely.</p><p><strong>Press and hold your lock screen, tap Customize, and select the clock</strong> frame. From here, you can reduce the font size or shift the clock up into the top widget row. Keeping photos of family, pets, or landscapes from competing with the time and date display.</p></p>                </section><section class="howto-block">                    <h3>Expand wallpapers with Apple Intelligence </h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/GgUA5PMQADNzL9gCvdd4V6.jpg"                                        alt="How to extend iPhone wallpaper in iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/GgUA5PMQADNzL9gCvdd4V6.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>Setting a favorite photo as your wallpaper often results in awkward cropping, cut-off heads, or exposed black bars if the image ratio does not match your screen.</p><p>iOS 27 solves this with Extend, an Apple Intelligence tool that generates new background detail around image edges.<strong> </strong></p><p><strong>Go to Settings, tap Wallpaper, select Add New Wallpaper, and pick your photo</strong>. Then <strong>tap the three dots in the bottom corner and select Extend Wallpaper</strong>. </p><p>The system automatically generates matching sky, scenery, or texture to fill the gaps, while simultaneously leveling out slightly tilted horizons.</p></p>                </section><section class="howto-block">                    <h3>Dismiss the Now Playing widget without stopping playback</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/E5efiZ7QqDZVMw2uQUwjgA.jpg"                                        alt="How to remove playback controls on iPhone in iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/E5efiZ7QqDZVMw2uQUwjgA.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>In previous versions of iOS, playing music, podcasts, or audiobooks forced a massive "Now Playing" widget onto your lock screen until playback stopped completely.</p><p>In iOS 27, you can dismiss the media controller whenever you want a clean view of your background. When the widget appears on your lock screen,<strong> simply swipe left across the playback controls</strong>. </p><p>This instantly hides the card and clears its status indicator from the Dynamic Island while your audio continues playing uninterrupted in the background.</p></p>                </section><section class="howto-block">                    <h3>Generate custom wallpapers using Image Playground</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/aMSJe24ZoPiGNkKPLwMuig.jpg"                                        alt="How to create your own iPhone wallpapers using Image Playground in iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/aMSJe24ZoPiGNkKPLwMuig.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>If you cannot find the right photo in your camera roll, you can generate custom high-resolution backgrounds directly from the wallpaper menu.</p><p>While customizing a new wallpaper, select <strong>Image Playground</strong> from the menu options. <strong>Type a quick description of the scene </strong>you want to create, then <strong>select a visual style  </strong>—such as Animation, Illustration, or Sketch. </p><p>Apple Intelligence will generate a unique background on the spot, allowing you to tweak elements or apply matching color filters before setting it to your lock screen.</p></p>                </section><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X81pNe"></div>                            </div>                            <script src="https://kwizly.com/embed/X81pNe.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/ios-27-quietly-fixes-the-most-annoying-iphone-workaround-we-all-use"><strong>iOS 27 finally fixes the most annoying iPhone workaround we all use</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/how-to-turn-off-ios-27s-automatic-subtitles-that-no-one-asked-for"><strong>How to disable iOS 27’s auto-subtitles for good</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/ive-been-testing-siri-ai-in-ios-27-for-3-weeks-7-things-to-try-first-and-the-feature-that-won-me-over"><strong>I've been testing Siri AI in iOS 27 for 3 weeks: 7 things to try first (and the feature that won me over)</strong></a><strong></strong></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ iPhone Duo vs iPhone 18 Pro Max + iPad mini: Are two devices better than one? ]]></title>
                                                                                                <dc:content><![CDATA[ <p>It’s official. Apple’s first foldable phone, the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-is-official-price-release-date-specs-and-everything-you-need-to-know">iPhone Duo</a>, will be taking up a surprisingly small space in early adopters’ pockets next month.  </p><p>It’s undeniably expensive, however. The base 256GB model will set you back $1,999 which critics have noted is more than it would cost to buy the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro</a> and the latest <a href="https://www.tomsguide.com/tablets/ipads/ipad-mini-7-review">iPad mini 7</a>.</p><p>So is that worth doing, or does the unique form factor of the iPhone Duo justify the extra cost? Here’s what you should consider before making your choice.</p><h3 class="article-body__section" id="section-why-you-should-choose-iphone-duo"><span>Why you should choose iPhone Duo</span></h3><h2 id="unmatched-portability">Unmatched portability</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Ck8JELAibFWVaimim8EYYK" name="iphone duo keyboard" alt="iPhone Duo hands on" src="https://cdn.mos.cms.futurecdn.net/Ck8JELAibFWVaimim8EYYK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The main thing the iPhone Duo has going for it is its portability. </p><p>When folded, it measures 117.8mm x 84.1mm x 11.3mm. Though that’s not too far removed from the iPhone 18 Pro’s 71.9mm x 150mm x 8.75mm, add in a 134.8mm x 195.4mm x 6.3mm <a href="https://www.tomsguide.com/tablets/ipads/ipad-mini-7-review">iPad mini 7</a>, and pockets alone just wouldn’t cut it.</p><div class="youtube-video" data-nosnippet ><div class="video-aspect-box"><iframe data-lazy-priority="low" data-lazy-src="https://www.youtube-nocookie.com/embed/uJKt432tWM4" allowfullscreen></iframe></div></div><p>And while the iPhone Duo weighs a not-insubstantial 254g, that’s still lighter than the combined weight of the phone and tablet, which together tip the scales at 504g.</p><p>When Tom's Guide sat down to talk with CEO John Ternus and Greg Joswiak following the Apple keynote, Joz specifically highlighted the joy of being able to fold up an iPad and take it around with you as part of the device's appeal.</p><h2 id="unique-features">Unique features</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="EsKpFMrwv4xbEz4arU9ai7" name="iPhone Duo edit 1" alt="iPhone Duo" src="https://cdn.mos.cms.futurecdn.net/EsKpFMrwv4xbEz4arU9ai7-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>As well as the cool factor of a folding phone, the iPhone Duo has a couple of features that are unique to the iPhone family. The internal FaceTime camera is an under-screen model, only visible when required. And that internal screen has a matte finish for less glare and fewer reflections.</p><p>In addition, the iPhone Duo's apps can morph based on the folding state of the device. For example, if you're watching Netflix and fold the device like a laptop, you'll see the video up top and controls down below.</p><p>Also, bear in mind that while the iPhone Duo uses the same A20 Pro chipset as the iPhone 18 Pro and iPhone 18 Pro Max, the iPad mini 7 is a bit longer in the tooth, still using the same A17 Pro silicone as the <a href="https://www.tomsguide.com/reviews/iphone-15-pro">iPhone 15 Pro</a>. The <a href="https://www.tomsguide.com/computing/ipads/ipad-mini-8-rumors-everything-we-know-so-far">iPad mini 8</a> will no doubt close the gap, but its release date (and likely price increase) is still to be determined.</p><h2 id="better-multitasking">Better multitasking</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="UDr8c5DLF9rP5aXyr9NwQ5" name="iphone duo software" alt="iphone duo two apps" src="https://cdn.mos.cms.futurecdn.net/UDr8c5DLF9rP5aXyr9NwQ5-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>One of the main reasons people use a tablet is for the enhanced multitasking abilities that a larger screen offers.</p><p>While both the iPhone Duo and iPad mini allow multiple apps for genuine multitasking, the former has the advantage here. Why? Because all your files, apps and notes are in <em>one place</em>. With an iPad mini, you’d need to make sure your files were synced between devices — something made that bit harder if you opt for the Wi-Fi-only model.</p><h2 id="only-one-device-to-keep-charged">Only one device to keep charged</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="nd9sC2YvUCWqc47etcEbTh" name="Ugreen charger" alt="Ugreen Uno Charger 65W" src="https://cdn.mos.cms.futurecdn.net/nd9sC2YvUCWqc47etcEbTh-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Ugreen)</span></figcaption></figure><p>Keeping electronics charged is one of the more tedious things about modern living. As a two-in-one device, you only need to monitor the battery of one handheld, rather than two.</p><h3 class="article-body__section" id="section-why-you-should-choose-an-iphone-18-pro-and-an-ipad-mini"><span>Why you should choose an iPhone 18 Pro and an iPad mini</span></h3><h2 id="significant-savings">Significant savings</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="TUHKFKjf3sxjBNZKbzJu8o" name="iPhone 18 Pro colors" alt="iPhone 18 Pro Max" src="https://cdn.mos.cms.futurecdn.net/TUHKFKjf3sxjBNZKbzJu8o-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The most obvious advantage of opting for a phone and a tablet over the iPhone Duo is the price difference. An iPhone Duo starts at $1,999, whereas buying both an entry-level iPad mini 7 and a base iPhone 18 Pro together comes to $1,698 — a $301 saving. Even if you opt for an iPhone 18 Pro Max with the iPad mini, you'll still pay a combined $1,798 that comes in cheaper than the Duo. Given the iPad mini 7 is coming up to its second birthday, you’d be able to save a packet by shopping around, too.</p><p>These savings can be even greater if you opt for a different combo, too. The <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-17-review">iPhone 17</a> starts at $899 on the Apple site, immediately slashing a further $300 from the price, and again, if you shop around, you’ll be able to get it cheaper.</p><h2 id="the-battery-power-of-two-devices">The battery power of two devices</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="6BFRufsaFjMeqCoSP4zjS5" name="iPad mini 7-28.jpg" alt="iPad mini 7" src="https://cdn.mos.cms.futurecdn.net/6BFRufsaFjMeqCoSP4zjS5-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Though I already covered the hassle of having to top up two batteries, the flip side to this is the added longevity. </p><p>The iPhone Duo is expected to have a battery that will last for 44 hours of video on the outer screen, or 31 on the internal one. The iPhone 18 Pro is quoted as going for 34 hours of video (<a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-18-pro-battery-life-tested-the-results-are-surprising">our own battery test knocked it out after 16 hours and 17 minutes of real-world endurance</a>), and the iPad mini lasted just over ten hours in <a href="https://www.tomsguide.com/tablets/ipads/ipad-mini-7-review#section-ipad-mini-7-review-the-ups">our battery tests</a>. That’s a slight edge to the pair of devices if the Duo is only used folded, and a resounding win if unfolded.</p><h2 id="better-camera-power">Better camera power</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="HYuuDMJ2Ch2YMUKD2MbYWc" name="iPhone 18 Pro cameras" alt="iPhone 18 Pro cameras" src="https://cdn.mos.cms.futurecdn.net/HYuuDMJ2Ch2YMUKD2MbYWc-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>For a flagship device, the iPhone Duo is surprisingly under-specced in the camera department. There are two 48MP rear cameras: a f/1.6 main lens and a f/2.2 ultrawide.</p><p>While the iPad mini’s camera can be safely ignored for the most part, the iPhone 18 Pro is clearly far more flexible. Not only does the 48MP main camera include a <a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">variable aperture</a>, letting photographers choose between f/1.48m, f/1.8m f/2.8 and f/4.0 values, but you also get an additional 48MP telephoto lens with 4x optical zoom. </p><h2 id="a-full-apple-pencil-experience">A full Apple Pencil experience</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1333px;"><p class="vanilla-image-block" style="padding-top:56.19%;"><img id="ZfhjUYFtyDg9fVzpXc9R6k" name="apple-pencil-pro.jpg" alt="The Apple Pencil Pro in use on an iPad" src="https://cdn.mos.cms.futurecdn.net/ZfhjUYFtyDg9fVzpXc9R6k-1920-80.jpg" mos="" align="middle" fullscreen="" width="1333" height="749" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>Although the iPhone Duo supports the Apple Pencil on both of its screens, there is one big caveat: you have to use the <a href="https://www.tomsguide.com/opinion/apple-pencil-usb-c-3-things-i-like-and-3-i-dont">paired-back USB-C version</a>. That means there’s no pressure sensor, haptic feedback, Find My support or added features like squeeze or double-tap.</p><p>While that’s better than the iPhone 18 Pro, which doesn’t support <em>any </em>Apple Pencils, the iPad mini 7 lets you use the USB-C model or the far better <a href="https://www.tomsguide.com/tablets/ipads/apple-announces-apple-pencil-pro-with-barrel-roll-and-squeeze-capabilities">Apple Pencil Pro</a>. That makes it the superior option for serious doodlers.</p><h3 class="article-body__section" id="section-iphone-duo-or-iphone-18-pro-ipad-mini"><span>iPhone Duo or iPhone 18 Pro + iPad mini?</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="wRdNsfx5snDKH2hTaAqsB8" name="iPhone-Duo-vs-iPhone-18-Pro-Max-LEDE1" alt="iPhone Duo vs iPhone 18 Pro Max." src="https://cdn.mos.cms.futurecdn.net/wRdNsfx5snDKH2hTaAqsB8-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Ultimately, there are benefits to both configurations. The iPhone Duo is undoubtedly more convenient and portable than lugging around two devices, and it has a few neat features that aren’t (yet) available on other Apple handhelds, like the under-screen selfie camera and a matte display. </p><p>But opting for both a less glamorous iPhone and iPad instead will save you at least $200, and likely more if you shop around or look beyond the brand new iPhone 18 Pro. On top of that, you get a superior camera setup and the full Apple Pencil experience.</p><p>In short, there’s no straightforward right or wrong answer here, and what you should choose will depend on your budget and specific circumstances. </p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/your-iphone-duo-deserves-better-than-a-cheap-case-here-are-9-life-savers">Your iPhone Duo deserves better than a cheap case — here are 9 life-savers</a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-series-12-review">Apple Watch Series 12 review: A new heart rate sensor and a readiness score make this the best smartwatch on the market</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen">iPhone 18 Pro and Pro Max benchmarks: These are the fastest phones we've ever tested</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphone-duo-vs-iphone-18-pro-max-ipad-mini-are-two-devices-better-than-one</link>
                                                                            <description>
                            <![CDATA[ There are reasons for and against going all in on Apple’s exciting new two-in-one folding phone. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">A4EUetodGZXrgucTgU3Q9E</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/i4QF9zqZdmy4sZPuE8hXFa-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 09:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Phones]]></category>
                                                    <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[iPads]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                    <category><![CDATA[Tablets]]></category>
                                                                                                                    <dc:creator><![CDATA[ Alan Martin ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/xMmhmPSssqZHHFWveDgSs7-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/i4QF9zqZdmy4sZPuE8hXFa-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone Duo]]></media:description>                                                            <media:text><![CDATA[iPhone Duo]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone Duo]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/i4QF9zqZdmy4sZPuE8hXFa-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>It’s official. Apple’s first foldable phone, the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-is-official-price-release-date-specs-and-everything-you-need-to-know">iPhone Duo</a>, will be taking up a surprisingly small space in early adopters’ pockets next month.  </p><p>It’s undeniably expensive, however. The base 256GB model will set you back $1,999 which critics have noted is more than it would cost to buy the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro</a> and the latest <a href="https://www.tomsguide.com/tablets/ipads/ipad-mini-7-review">iPad mini 7</a>.</p><p>So is that worth doing, or does the unique form factor of the iPhone Duo justify the extra cost? Here’s what you should consider before making your choice.</p><h3 class="article-body__section" id="section-why-you-should-choose-iphone-duo"><span>Why you should choose iPhone Duo</span></h3><h2 id="unmatched-portability">Unmatched portability</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Ck8JELAibFWVaimim8EYYK" name="iphone duo keyboard" alt="iPhone Duo hands on" src="https://cdn.mos.cms.futurecdn.net/Ck8JELAibFWVaimim8EYYK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The main thing the iPhone Duo has going for it is its portability. </p><p>When folded, it measures 117.8mm x 84.1mm x 11.3mm. Though that’s not too far removed from the iPhone 18 Pro’s 71.9mm x 150mm x 8.75mm, add in a 134.8mm x 195.4mm x 6.3mm <a href="https://www.tomsguide.com/tablets/ipads/ipad-mini-7-review">iPad mini 7</a>, and pockets alone just wouldn’t cut it.</p><div class="youtube-video" data-nosnippet ><div class="video-aspect-box"><iframe data-lazy-priority="low" data-lazy-src="https://www.youtube-nocookie.com/embed/uJKt432tWM4" allowfullscreen></iframe></div></div><p>And while the iPhone Duo weighs a not-insubstantial 254g, that’s still lighter than the combined weight of the phone and tablet, which together tip the scales at 504g.</p><p>When Tom's Guide sat down to talk with CEO John Ternus and Greg Joswiak following the Apple keynote, Joz specifically highlighted the joy of being able to fold up an iPad and take it around with you as part of the device's appeal.</p><h2 id="unique-features">Unique features</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="EsKpFMrwv4xbEz4arU9ai7" name="iPhone Duo edit 1" alt="iPhone Duo" src="https://cdn.mos.cms.futurecdn.net/EsKpFMrwv4xbEz4arU9ai7-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>As well as the cool factor of a folding phone, the iPhone Duo has a couple of features that are unique to the iPhone family. The internal FaceTime camera is an under-screen model, only visible when required. And that internal screen has a matte finish for less glare and fewer reflections.</p><p>In addition, the iPhone Duo's apps can morph based on the folding state of the device. For example, if you're watching Netflix and fold the device like a laptop, you'll see the video up top and controls down below.</p><p>Also, bear in mind that while the iPhone Duo uses the same A20 Pro chipset as the iPhone 18 Pro and iPhone 18 Pro Max, the iPad mini 7 is a bit longer in the tooth, still using the same A17 Pro silicone as the <a href="https://www.tomsguide.com/reviews/iphone-15-pro">iPhone 15 Pro</a>. The <a href="https://www.tomsguide.com/computing/ipads/ipad-mini-8-rumors-everything-we-know-so-far">iPad mini 8</a> will no doubt close the gap, but its release date (and likely price increase) is still to be determined.</p><h2 id="better-multitasking">Better multitasking</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="UDr8c5DLF9rP5aXyr9NwQ5" name="iphone duo software" alt="iphone duo two apps" src="https://cdn.mos.cms.futurecdn.net/UDr8c5DLF9rP5aXyr9NwQ5-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>One of the main reasons people use a tablet is for the enhanced multitasking abilities that a larger screen offers.</p><p>While both the iPhone Duo and iPad mini allow multiple apps for genuine multitasking, the former has the advantage here. Why? Because all your files, apps and notes are in <em>one place</em>. With an iPad mini, you’d need to make sure your files were synced between devices — something made that bit harder if you opt for the Wi-Fi-only model.</p><h2 id="only-one-device-to-keep-charged">Only one device to keep charged</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="nd9sC2YvUCWqc47etcEbTh" name="Ugreen charger" alt="Ugreen Uno Charger 65W" src="https://cdn.mos.cms.futurecdn.net/nd9sC2YvUCWqc47etcEbTh-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Ugreen)</span></figcaption></figure><p>Keeping electronics charged is one of the more tedious things about modern living. As a two-in-one device, you only need to monitor the battery of one handheld, rather than two.</p><h3 class="article-body__section" id="section-why-you-should-choose-an-iphone-18-pro-and-an-ipad-mini"><span>Why you should choose an iPhone 18 Pro and an iPad mini</span></h3><h2 id="significant-savings">Significant savings</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="TUHKFKjf3sxjBNZKbzJu8o" name="iPhone 18 Pro colors" alt="iPhone 18 Pro Max" src="https://cdn.mos.cms.futurecdn.net/TUHKFKjf3sxjBNZKbzJu8o-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The most obvious advantage of opting for a phone and a tablet over the iPhone Duo is the price difference. An iPhone Duo starts at $1,999, whereas buying both an entry-level iPad mini 7 and a base iPhone 18 Pro together comes to $1,698 — a $301 saving. Even if you opt for an iPhone 18 Pro Max with the iPad mini, you'll still pay a combined $1,798 that comes in cheaper than the Duo. Given the iPad mini 7 is coming up to its second birthday, you’d be able to save a packet by shopping around, too.</p><p>These savings can be even greater if you opt for a different combo, too. The <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-17-review">iPhone 17</a> starts at $899 on the Apple site, immediately slashing a further $300 from the price, and again, if you shop around, you’ll be able to get it cheaper.</p><h2 id="the-battery-power-of-two-devices">The battery power of two devices</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="6BFRufsaFjMeqCoSP4zjS5" name="iPad mini 7-28.jpg" alt="iPad mini 7" src="https://cdn.mos.cms.futurecdn.net/6BFRufsaFjMeqCoSP4zjS5-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Though I already covered the hassle of having to top up two batteries, the flip side to this is the added longevity. </p><p>The iPhone Duo is expected to have a battery that will last for 44 hours of video on the outer screen, or 31 on the internal one. The iPhone 18 Pro is quoted as going for 34 hours of video (<a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-18-pro-battery-life-tested-the-results-are-surprising">our own battery test knocked it out after 16 hours and 17 minutes of real-world endurance</a>), and the iPad mini lasted just over ten hours in <a href="https://www.tomsguide.com/tablets/ipads/ipad-mini-7-review#section-ipad-mini-7-review-the-ups">our battery tests</a>. That’s a slight edge to the pair of devices if the Duo is only used folded, and a resounding win if unfolded.</p><h2 id="better-camera-power">Better camera power</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="HYuuDMJ2Ch2YMUKD2MbYWc" name="iPhone 18 Pro cameras" alt="iPhone 18 Pro cameras" src="https://cdn.mos.cms.futurecdn.net/HYuuDMJ2Ch2YMUKD2MbYWc-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>For a flagship device, the iPhone Duo is surprisingly under-specced in the camera department. There are two 48MP rear cameras: a f/1.6 main lens and a f/2.2 ultrawide.</p><p>While the iPad mini’s camera can be safely ignored for the most part, the iPhone 18 Pro is clearly far more flexible. Not only does the 48MP main camera include a <a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">variable aperture</a>, letting photographers choose between f/1.48m, f/1.8m f/2.8 and f/4.0 values, but you also get an additional 48MP telephoto lens with 4x optical zoom. </p><h2 id="a-full-apple-pencil-experience">A full Apple Pencil experience</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1333px;"><p class="vanilla-image-block" style="padding-top:56.19%;"><img id="ZfhjUYFtyDg9fVzpXc9R6k" name="apple-pencil-pro.jpg" alt="The Apple Pencil Pro in use on an iPad" src="https://cdn.mos.cms.futurecdn.net/ZfhjUYFtyDg9fVzpXc9R6k-1920-80.jpg" mos="" align="middle" fullscreen="" width="1333" height="749" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>Although the iPhone Duo supports the Apple Pencil on both of its screens, there is one big caveat: you have to use the <a href="https://www.tomsguide.com/opinion/apple-pencil-usb-c-3-things-i-like-and-3-i-dont">paired-back USB-C version</a>. That means there’s no pressure sensor, haptic feedback, Find My support or added features like squeeze or double-tap.</p><p>While that’s better than the iPhone 18 Pro, which doesn’t support <em>any </em>Apple Pencils, the iPad mini 7 lets you use the USB-C model or the far better <a href="https://www.tomsguide.com/tablets/ipads/apple-announces-apple-pencil-pro-with-barrel-roll-and-squeeze-capabilities">Apple Pencil Pro</a>. That makes it the superior option for serious doodlers.</p><h3 class="article-body__section" id="section-iphone-duo-or-iphone-18-pro-ipad-mini"><span>iPhone Duo or iPhone 18 Pro + iPad mini?</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="wRdNsfx5snDKH2hTaAqsB8" name="iPhone-Duo-vs-iPhone-18-Pro-Max-LEDE1" alt="iPhone Duo vs iPhone 18 Pro Max." src="https://cdn.mos.cms.futurecdn.net/wRdNsfx5snDKH2hTaAqsB8-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Ultimately, there are benefits to both configurations. The iPhone Duo is undoubtedly more convenient and portable than lugging around two devices, and it has a few neat features that aren’t (yet) available on other Apple handhelds, like the under-screen selfie camera and a matte display. </p><p>But opting for both a less glamorous iPhone and iPad instead will save you at least $200, and likely more if you shop around or look beyond the brand new iPhone 18 Pro. On top of that, you get a superior camera setup and the full Apple Pencil experience.</p><p>In short, there’s no straightforward right or wrong answer here, and what you should choose will depend on your budget and specific circumstances. </p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/your-iphone-duo-deserves-better-than-a-cheap-case-here-are-9-life-savers">Your iPhone Duo deserves better than a cheap case — here are 9 life-savers</a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-series-12-review">Apple Watch Series 12 review: A new heart rate sensor and a readiness score make this the best smartwatch on the market</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen">iPhone 18 Pro and Pro Max benchmarks: These are the fastest phones we've ever tested</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I replaced ChatGPT with Siri AI for a day — here's what surprised me ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I'll admit, I stopped using Siri around 2010. I didn't think it was very helpful for more than setting a timer and I often had to repeat myself, which seemed to make using it frustrating at times. </p><p>But Siri AI in iOS 27 is something very different and has made me a believer again. The difference is the "AI" in Siri AI. Apple has turned Siri into a conversational AI assistant, much like ChatGPT Voice, that can answer questions and understand what's on your screen and, perhaps most importantly, tap into information already sitting on your iPhone.<br><br>In the same way Personal Intelligence can navigate through Google Workspace, Siri AI does that right on your phone. And that's the thing about this update that caught my attention. </p><p>So I decided to try something I wouldn't have considered doing with the old Siri: I stopped using ChatGPT for a day and asked Siri AI to handle as many of my usual AI tasks as possible.</p><p>I expected ChatGPT to run circles around it. That wasn't always what happened. Here are five things that changed how I use it.</p><h2 id="1-finding-something-i-barely-remember">1. Finding something I barely remember</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="E4V5TXM7JJES5HMnDyTpcW" name="ios 27 photos" alt="iOS 27 logo and Photos logo on iPhone" src="https://cdn.mos.cms.futurecdn.net/E4V5TXM7JJES5HMnDyTpcW-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future / edited with Gemini )</span></figcaption></figure><p>I save everything. I have about 70,657 photos on my iPhone as proof that I'm a digital hoarder. But one of the most frustrating things about having years of messages, emails and photos on my phone is knowing something is there but having absolutely no idea where to look for it. I can't tell you how many times I think "I know I took a screenshot of that phone number sometime in July..." </p><p>Normally, I'd start opening apps and searching individually. Siri's personal context makes a completely different approach possible.</p><p>Instead, I can ask something vague like, "What was the name of the restaurant Steve sent me?" or "When is that appointment I got an email about?"</p><p>That's a deceptively big change. Traditional Siri worked best when you knew exactly what you wanted and phrased the command correctly. The new Siri is much better suited to those moments when <em>you don't know exactly what you're looking for</em>. That's honestly one of the main reasons I need an assistant at all. </p><h2 id="2-doing-something-with-what-39-s-already-on-my-screen">2. Doing something with what's already on my screen</h2><p>If I'm looking at something on my iPhone, I don't necessarily have to explain what "this" is before asking Siri about it.</p><p>For example, if someone sends me information I need later, I can bring up Siri and say, "Remind me about this tomorrow."</p><p>Or I can ask Siri about something I'm looking at and then continue from there. With a traditional chatbot, there's often an extra step involved. I might need to upload a screenshot, copy some text or explain what I'm looking at before asking my question.</p><p>Siri is already there. It's one of those advantages that has less to do with having a smarter model and more to do with where the AI actually lives.</p><h2 id="3-handling-a-messy-normal-life-request">3. Handling a messy, normal-life request</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="TcMU6oXWhHBgtrAeCq3KWN" name="Siri on iPhone" alt="Siri on iPhone" src="https://cdn.mos.cms.futurecdn.net/TcMU6oXWhHBgtrAeCq3KWN-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>AI benchmarks are great for comparing models, but my actual life leads to questions that are more like, "I need to make dinner before soccer at 6. I have chicken in the fridge, I don't want anything complicated and it needs to take less than 25 minutes."</p><p>That's the kind of request I've traditionally taken straight to ChatGPT.  So I started giving similar requests to Siri. And, what I noticed about Siri AI is that it finally keeps the conversation going. It's a lot like ChatGPT voice </p><p>What's different from the Siri of a few years ago is that I can continue the conversation without starting over every time.</p><p>I can ask for dinner ideas, reject the first suggestion, add another constraint and keep going.</p><p><em>"Nothing spicy."</em></p><p><em>"What if I don't have rice?"</em></p><p><em>"Give me the easiest one."</em></p><p>That conversational back-and-forth is something we've taken for granted with <a href="https://www.tomsguide.com/ai/i-challenged-gemini-live-vs-chatgpt-in-5-voice-challenges-there-was-one-clear-winner">ChatGPT and Gemini Live</a>, but it fundamentally changes what Siri feels like to use.</p><h2 id="4-doing-the-things-chatgpt-can-39-t">4. Doing the things ChatGPT can't</h2><p>My opinion started to really change about Siri AI when I tested it to do things that ChatGPT cannot do. If I ask ChatGPT and Siri the same difficult question, I'd still expect ChatGPT to have an advantage in plenty of situations.</p><p>But that's not necessarily the comparison here. Siri can interact with the device I'm holding. That means that Siri is doing so much more than answering questions — it actually takes action. I can ask about information on my phone and then do something with it. I can move between finding information and acting on that information without treating the AI as a separate destination.</p><p>Chatbots have become remarkably good at telling us <em>how</em> to do things. The next step is having an assistant that can actually help carry them out. And because Siri sits at the operating-system level, Apple has an enormous advantage here.</p><h2 id="5-knowing-when-i-39-d-still-choose-chatgpt">5. Knowing when I'd still choose ChatGPT</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Ht39AXCkUg2DrrFxAXLLD" name="chatgpt.shutterstock_2433513105 (1)" alt="ChatGPT on phone" src="https://cdn.mos.cms.futurecdn.net/Ht39AXCkUg2DrrFxAXLLD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>To be clear, Siri hasn't suddenly made ChatGPT irrelevant on my iPhone. I still prefer to brainstorm and fact-check with ChatGPT, or even work through a complicated idea. I just think ChatGPT-6 is a simply better AI, but after diving into Siri AI, I've found myself using the two differently. </p><p>ChatGPT is where I go when I want to <em>think with AI</em>. Siri is now where I go when I want AI to help me <em>do something on my phone</em>.</p><p>The line between those two things will probably get blurrier as both assistants evolve, but right now it's a surprisingly useful distinction. I'm just glad to know that Siri finally has a reason to exist. </p><h2 id="bottom-line-9">Bottom line</h2><p>Siri AI in iOS 27 has made me a believer in Siri again. It finally understands what I need and what I'm looking at without me needing to repeat myself. And, the information is actually useful and already on the device I'm using, which can turn a conversation into an action faster than using ChatGPT. </p><p>There are still plenty of situations where I'd choose ChatGPT first, particularly when I need deeper reasoning or I'm working on something complicated.</p><p>But when I'm holding my iPhone and simply trying to get something done, I'm starting to reach for Siri more often.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/ai/ai-is-turning-ordinary-photos-of-kids-into-sexual-abuse-imagery-heres-how-to-protect-your-family"><strong>AI is turning ordinary photos of kids into sexual abuse imagery — here's how to protect your family</strong></a><strong></strong></li><li><a href="https://www.tomsguide.com/ai/chatgpt/humans-may-be-reading-your-chatgpt-prompts-heres-how-to-stop-it"><strong>OpenAI paid contractors to read ChatGPT conversations — here's how to protect yourself</strong></a></li><li><strong></strong><a href="https://www.tomsguide.com/ai/chatgpt/i-stopped-reading-the-fine-print-myself-after-discovering-this-overlooked-chatgpt-trick"><strong>I stopped reading the fine print myself after discovering this overlooked ChatGPT trick</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/i-replaced-chatgpt-with-siri-ai-for-a-day-heres-what-surprised-me</link>
                                                                            <description>
                            <![CDATA[ What happened when I used Siri AI exclusively for a day over ChatGPT. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">qjB8VQKD8h36psR72dfKG6</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/BK6wAHZvbvvt9kZyzEVG96-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 08:00:00 +0000</pubDate>                                                                                                                                <updated>Sat, 19 Sep 2026 12:36:06 +0000</updated>
                                                                                                                                            <category><![CDATA[AI]]></category>
                                                                                                <author><![CDATA[ amanda.caswell@futurenet.com (Amanda Caswell) ]]></author>                    <dc:creator><![CDATA[ Amanda Caswell ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/zYjevim2q7FjQiefqpjZRB-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/BK6wAHZvbvvt9kZyzEVG96-1920-80.jpg">
                                                            <media:credit><![CDATA[John Velasco / Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iOS 27 Siri AI running on iPhone 17 Pro.]]></media:description>                                                            <media:text><![CDATA[iOS 27 Siri AI running on iPhone 17 Pro.]]></media:text>
                                <media:title type="plain"><![CDATA[iOS 27 Siri AI running on iPhone 17 Pro.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/BK6wAHZvbvvt9kZyzEVG96-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I'll admit, I stopped using Siri around 2010. I didn't think it was very helpful for more than setting a timer and I often had to repeat myself, which seemed to make using it frustrating at times. </p><p>But Siri AI in iOS 27 is something very different and has made me a believer again. The difference is the "AI" in Siri AI. Apple has turned Siri into a conversational AI assistant, much like ChatGPT Voice, that can answer questions and understand what's on your screen and, perhaps most importantly, tap into information already sitting on your iPhone.<br><br>In the same way Personal Intelligence can navigate through Google Workspace, Siri AI does that right on your phone. And that's the thing about this update that caught my attention. </p><p>So I decided to try something I wouldn't have considered doing with the old Siri: I stopped using ChatGPT for a day and asked Siri AI to handle as many of my usual AI tasks as possible.</p><p>I expected ChatGPT to run circles around it. That wasn't always what happened. Here are five things that changed how I use it.</p><h2 id="1-finding-something-i-barely-remember">1. Finding something I barely remember</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="E4V5TXM7JJES5HMnDyTpcW" name="ios 27 photos" alt="iOS 27 logo and Photos logo on iPhone" src="https://cdn.mos.cms.futurecdn.net/E4V5TXM7JJES5HMnDyTpcW-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future / edited with Gemini )</span></figcaption></figure><p>I save everything. I have about 70,657 photos on my iPhone as proof that I'm a digital hoarder. But one of the most frustrating things about having years of messages, emails and photos on my phone is knowing something is there but having absolutely no idea where to look for it. I can't tell you how many times I think "I know I took a screenshot of that phone number sometime in July..." </p><p>Normally, I'd start opening apps and searching individually. Siri's personal context makes a completely different approach possible.</p><p>Instead, I can ask something vague like, "What was the name of the restaurant Steve sent me?" or "When is that appointment I got an email about?"</p><p>That's a deceptively big change. Traditional Siri worked best when you knew exactly what you wanted and phrased the command correctly. The new Siri is much better suited to those moments when <em>you don't know exactly what you're looking for</em>. That's honestly one of the main reasons I need an assistant at all. </p><h2 id="2-doing-something-with-what-39-s-already-on-my-screen">2. Doing something with what's already on my screen</h2><p>If I'm looking at something on my iPhone, I don't necessarily have to explain what "this" is before asking Siri about it.</p><p>For example, if someone sends me information I need later, I can bring up Siri and say, "Remind me about this tomorrow."</p><p>Or I can ask Siri about something I'm looking at and then continue from there. With a traditional chatbot, there's often an extra step involved. I might need to upload a screenshot, copy some text or explain what I'm looking at before asking my question.</p><p>Siri is already there. It's one of those advantages that has less to do with having a smarter model and more to do with where the AI actually lives.</p><h2 id="3-handling-a-messy-normal-life-request">3. Handling a messy, normal-life request</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="TcMU6oXWhHBgtrAeCq3KWN" name="Siri on iPhone" alt="Siri on iPhone" src="https://cdn.mos.cms.futurecdn.net/TcMU6oXWhHBgtrAeCq3KWN-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>AI benchmarks are great for comparing models, but my actual life leads to questions that are more like, "I need to make dinner before soccer at 6. I have chicken in the fridge, I don't want anything complicated and it needs to take less than 25 minutes."</p><p>That's the kind of request I've traditionally taken straight to ChatGPT.  So I started giving similar requests to Siri. And, what I noticed about Siri AI is that it finally keeps the conversation going. It's a lot like ChatGPT voice </p><p>What's different from the Siri of a few years ago is that I can continue the conversation without starting over every time.</p><p>I can ask for dinner ideas, reject the first suggestion, add another constraint and keep going.</p><p><em>"Nothing spicy."</em></p><p><em>"What if I don't have rice?"</em></p><p><em>"Give me the easiest one."</em></p><p>That conversational back-and-forth is something we've taken for granted with <a href="https://www.tomsguide.com/ai/i-challenged-gemini-live-vs-chatgpt-in-5-voice-challenges-there-was-one-clear-winner">ChatGPT and Gemini Live</a>, but it fundamentally changes what Siri feels like to use.</p><h2 id="4-doing-the-things-chatgpt-can-39-t">4. Doing the things ChatGPT can't</h2><p>My opinion started to really change about Siri AI when I tested it to do things that ChatGPT cannot do. If I ask ChatGPT and Siri the same difficult question, I'd still expect ChatGPT to have an advantage in plenty of situations.</p><p>But that's not necessarily the comparison here. Siri can interact with the device I'm holding. That means that Siri is doing so much more than answering questions — it actually takes action. I can ask about information on my phone and then do something with it. I can move between finding information and acting on that information without treating the AI as a separate destination.</p><p>Chatbots have become remarkably good at telling us <em>how</em> to do things. The next step is having an assistant that can actually help carry them out. And because Siri sits at the operating-system level, Apple has an enormous advantage here.</p><h2 id="5-knowing-when-i-39-d-still-choose-chatgpt">5. Knowing when I'd still choose ChatGPT</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Ht39AXCkUg2DrrFxAXLLD" name="chatgpt.shutterstock_2433513105 (1)" alt="ChatGPT on phone" src="https://cdn.mos.cms.futurecdn.net/Ht39AXCkUg2DrrFxAXLLD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>To be clear, Siri hasn't suddenly made ChatGPT irrelevant on my iPhone. I still prefer to brainstorm and fact-check with ChatGPT, or even work through a complicated idea. I just think ChatGPT-6 is a simply better AI, but after diving into Siri AI, I've found myself using the two differently. </p><p>ChatGPT is where I go when I want to <em>think with AI</em>. Siri is now where I go when I want AI to help me <em>do something on my phone</em>.</p><p>The line between those two things will probably get blurrier as both assistants evolve, but right now it's a surprisingly useful distinction. I'm just glad to know that Siri finally has a reason to exist. </p><h2 id="bottom-line-9">Bottom line</h2><p>Siri AI in iOS 27 has made me a believer in Siri again. It finally understands what I need and what I'm looking at without me needing to repeat myself. And, the information is actually useful and already on the device I'm using, which can turn a conversation into an action faster than using ChatGPT. </p><p>There are still plenty of situations where I'd choose ChatGPT first, particularly when I need deeper reasoning or I'm working on something complicated.</p><p>But when I'm holding my iPhone and simply trying to get something done, I'm starting to reach for Siri more often.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/ai/ai-is-turning-ordinary-photos-of-kids-into-sexual-abuse-imagery-heres-how-to-protect-your-family"><strong>AI is turning ordinary photos of kids into sexual abuse imagery — here's how to protect your family</strong></a><strong></strong></li><li><a href="https://www.tomsguide.com/ai/chatgpt/humans-may-be-reading-your-chatgpt-prompts-heres-how-to-stop-it"><strong>OpenAI paid contractors to read ChatGPT conversations — here's how to protect yourself</strong></a></li><li><strong></strong><a href="https://www.tomsguide.com/ai/chatgpt/i-stopped-reading-the-fine-print-myself-after-discovering-this-overlooked-chatgpt-trick"><strong>I stopped reading the fine print myself after discovering this overlooked ChatGPT trick</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Notify Me is easily one of the best features iOS 27 has to offer — but it needs to do better ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Over the past few years I have spent an inordinate amount of my time sitting in virtual queues, waiting for my chance to buy something. Recently my phone was sitting in one for around four hours as I attempted to book a family trip to Disneyland Paris. Since it was the day bookings opened, it seems as though half of Europe was doing the same thing.</p><p>Waiting is bad enough, but it was made worse by the fact I got distracted partway through waiting and missed my window. That means starting the whole process again, and mentally kicking myself for letting myself get distracted attempting to troubleshoot my temperamental 3D printer. This is far from an isolated case for me, either.</p><p>So you can imagine my excitement when I found out about the <a href="https://www.tomsguide.com/phones/iphones/i-tried-the-new-ios-27-safari-features-heres-3-settings-worth-using">new "Notify Me" feature in iOS 27</a>, with the promise that it can monitor webpages and alert you to any changes. Unfortunately spending time with Notify Me shows that Apple hasn't really gone far enough.</p><h2 id="what-notify-me-is-and-how-it-works">What Notify Me is, and how it works</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="3TNuPjESwkkQGg3otBq68M" name="Notify Me in Safari iOS 27" alt="Notify Me in Safari iOS 27" src="https://cdn.mos.cms.futurecdn.net/3TNuPjESwkkQGg3otBq68M-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Notify Me is an artificial intelligence feature for Apple's Safari browser. The idea is that you can single out a webpage and have Apple's AI tell you when things change. That can be general changes, or it could be something specific that you describe with a written prompt.</p><p>The main thing to remember about Notify Me is that the AI doesn't monitor that page all the time. Instead you have to tell it when it should come back and see what's changed. Your options are to do this hourly, daily, weekly or monthly. You also get to set the exact time, day or date (depending on the frequency) that the AI goes back to check.</p><p> It's a very simple feature that can be accessed from the Safari menu bar which sits on the left-hand side of the URL bar — which is typically at the bottom of the screen on iPhone and iPad. It's easy to find and use, which is more than I can say for a lot of features in iOS 27. </p><p>From a practical stand point, Notify Me has everything going for it. Apart from the fact its usefulness is currently rather limited.</p><h2 id="hourly-checks-aren-39-t-enough-to-be-truly-useful">Hourly checks aren't enough to be truly useful</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="bQHyd7TqzPHSxriuHhKYHX" name="iOS 27 Safari on iPhone" alt="An image of an iPhone screen showing the Safari app icon in the center and the iOS 27 logo" src="https://cdn.mos.cms.futurecdn.net/bQHyd7TqzPHSxriuHhKYHX-1920-80.png" mos="" align="middle" fullscreen="" width="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'm not saying that Notify Me is useless in its current form, quite the opposite in fact. The tool is ideal for keeping tabs on certain pages in the long-term. Use cases include keeping tabs on restocks, or checking for discounts on specific products. The pages that you would only look at periodically, checking in very briefly before going back to whatever you would normally be doing.</p><p>Notify Me saves you the effort of remembering to do this yourself, especially if you want to check on some sort of schedule. You don't need to take time out of your day to look, when you have an AI that has been instructed to take care of that for you.</p><p>But in the short term? Notify Me's scope is still a little too limited for my liking. </p><p>Typically getting to the front of a virtual queue means you get some kind of grace period to complete whatever transaction you're doing. In the case of my trip it was 20 minutes, but I've seen them vary anywhere between 10 minutes and an hour. Obviously, having a tool that refreshes a page once an hour at most is not ideal for dealing with these kinds of situations. By the time the AI checks the page, it'll already be too late and you'll have missed your spot.</p><p>Really it would be better if Apple expanded Notify Me for much smaller periods of time. Five to ten minutes would expand its usefulness by a lot, since it would be as close to real-time monitoring as we can hope for with a free AI tool. But even increasing page refreshes to 30 or 15 minutes would make it a more useful and versatile tool.</p><h2 id="bottom-line-10">Bottom line</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Gvdmm9HZT4DwWH6WPi4FW8" name="TG-safari-iphone-shutterstock.jpg" alt="An image of an iPhone screen showing the Safari app icon in the center" src="https://cdn.mos.cms.futurecdn.net/Gvdmm9HZT4DwWH6WPi4FW8-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>Notify Me is definitely a useful tool, but its scope is too limited right now. The fact that you can instruct AI to check webpages for any kind of change you can describe is pretty incredible. But it's very much a long-term tool, that a lot of people probably won't get much use out of. It certainly has the potential to offer a lot more, though.</p><p>The question is whether Apple can actually do that. AI needs a lot of resources to run, and the more you utilize it the more pressure it's going to put on your hardware. In fact, we don't know where this processing is done or how it affects your phone, so there's no telling what sort of stress checking a page multiple times an hour might inflict. Even if<a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen"> Apple has just released the fastest phones</a> we've ever tested.</p><p>But I hope that this is just the start of what Apple has planned, and that Notify Me will be getting an expansion in future versions of iOS and Apple Intelligence. After all, the less we all have to sit in virtual queues to try and get tickets to the next big concert or event, the better.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless"><strong>I tested the iPhone 18 Pro Max's variable aperture camera — here's the results</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/apple-increased-the-price-of-iphone-18-pro-battery-repairs-heres-how-much-youll-pay-now"><strong>Apple increased the price of iPhone 18 Pro battery repairs — here's how much you'll pay now</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/siri-in-ios-27-actually-lives-up-to-the-hype-here-are-the-3-truly-unique-uses"><strong>Siri in iOS 27 actually lives up to the hype — here are 3 truly unique uses</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/notify-me-is-easily-one-of-the-best-features-ios-27-has-to-offer-but-it-needs-to-do-better</link>
                                                                            <description>
                            <![CDATA[ Notify Me is useful, but it could be even better if Apple let it check pages more often. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">xRJcfAgXCqMwUM6tkpCB9U</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/K5SQbjBSv85JzgqYxoY5Lm-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 07:00:00 +0000</pubDate>                                                                                                                                <updated>Sat, 19 Sep 2026 12:37:17 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Apple Intelligence]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                    <category><![CDATA[AI]]></category>
                                                                                                <author><![CDATA[ tom.pritchard@futurenet.com (Tom Pritchard) ]]></author>                    <dc:creator><![CDATA[ Tom Pritchard ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/biCewUkKfSA6QnT2HxVc3f-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/K5SQbjBSv85JzgqYxoY5Lm-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide/Apple/Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iOS 27 icon shown on an iPhone screen]]></media:description>                                                            <media:text><![CDATA[iOS 27 icon shown on an iPhone screen]]></media:text>
                                <media:title type="plain"><![CDATA[iOS 27 icon shown on an iPhone screen]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/K5SQbjBSv85JzgqYxoY5Lm-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Over the past few years I have spent an inordinate amount of my time sitting in virtual queues, waiting for my chance to buy something. Recently my phone was sitting in one for around four hours as I attempted to book a family trip to Disneyland Paris. Since it was the day bookings opened, it seems as though half of Europe was doing the same thing.</p><p>Waiting is bad enough, but it was made worse by the fact I got distracted partway through waiting and missed my window. That means starting the whole process again, and mentally kicking myself for letting myself get distracted attempting to troubleshoot my temperamental 3D printer. This is far from an isolated case for me, either.</p><p>So you can imagine my excitement when I found out about the <a href="https://www.tomsguide.com/phones/iphones/i-tried-the-new-ios-27-safari-features-heres-3-settings-worth-using">new "Notify Me" feature in iOS 27</a>, with the promise that it can monitor webpages and alert you to any changes. Unfortunately spending time with Notify Me shows that Apple hasn't really gone far enough.</p><h2 id="what-notify-me-is-and-how-it-works">What Notify Me is, and how it works</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="3TNuPjESwkkQGg3otBq68M" name="Notify Me in Safari iOS 27" alt="Notify Me in Safari iOS 27" src="https://cdn.mos.cms.futurecdn.net/3TNuPjESwkkQGg3otBq68M-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Notify Me is an artificial intelligence feature for Apple's Safari browser. The idea is that you can single out a webpage and have Apple's AI tell you when things change. That can be general changes, or it could be something specific that you describe with a written prompt.</p><p>The main thing to remember about Notify Me is that the AI doesn't monitor that page all the time. Instead you have to tell it when it should come back and see what's changed. Your options are to do this hourly, daily, weekly or monthly. You also get to set the exact time, day or date (depending on the frequency) that the AI goes back to check.</p><p> It's a very simple feature that can be accessed from the Safari menu bar which sits on the left-hand side of the URL bar — which is typically at the bottom of the screen on iPhone and iPad. It's easy to find and use, which is more than I can say for a lot of features in iOS 27. </p><p>From a practical stand point, Notify Me has everything going for it. Apart from the fact its usefulness is currently rather limited.</p><h2 id="hourly-checks-aren-39-t-enough-to-be-truly-useful">Hourly checks aren't enough to be truly useful</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="bQHyd7TqzPHSxriuHhKYHX" name="iOS 27 Safari on iPhone" alt="An image of an iPhone screen showing the Safari app icon in the center and the iOS 27 logo" src="https://cdn.mos.cms.futurecdn.net/bQHyd7TqzPHSxriuHhKYHX-1920-80.png" mos="" align="middle" fullscreen="" width="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'm not saying that Notify Me is useless in its current form, quite the opposite in fact. The tool is ideal for keeping tabs on certain pages in the long-term. Use cases include keeping tabs on restocks, or checking for discounts on specific products. The pages that you would only look at periodically, checking in very briefly before going back to whatever you would normally be doing.</p><p>Notify Me saves you the effort of remembering to do this yourself, especially if you want to check on some sort of schedule. You don't need to take time out of your day to look, when you have an AI that has been instructed to take care of that for you.</p><p>But in the short term? Notify Me's scope is still a little too limited for my liking. </p><p>Typically getting to the front of a virtual queue means you get some kind of grace period to complete whatever transaction you're doing. In the case of my trip it was 20 minutes, but I've seen them vary anywhere between 10 minutes and an hour. Obviously, having a tool that refreshes a page once an hour at most is not ideal for dealing with these kinds of situations. By the time the AI checks the page, it'll already be too late and you'll have missed your spot.</p><p>Really it would be better if Apple expanded Notify Me for much smaller periods of time. Five to ten minutes would expand its usefulness by a lot, since it would be as close to real-time monitoring as we can hope for with a free AI tool. But even increasing page refreshes to 30 or 15 minutes would make it a more useful and versatile tool.</p><h2 id="bottom-line-10">Bottom line</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Gvdmm9HZT4DwWH6WPi4FW8" name="TG-safari-iphone-shutterstock.jpg" alt="An image of an iPhone screen showing the Safari app icon in the center" src="https://cdn.mos.cms.futurecdn.net/Gvdmm9HZT4DwWH6WPi4FW8-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>Notify Me is definitely a useful tool, but its scope is too limited right now. The fact that you can instruct AI to check webpages for any kind of change you can describe is pretty incredible. But it's very much a long-term tool, that a lot of people probably won't get much use out of. It certainly has the potential to offer a lot more, though.</p><p>The question is whether Apple can actually do that. AI needs a lot of resources to run, and the more you utilize it the more pressure it's going to put on your hardware. In fact, we don't know where this processing is done or how it affects your phone, so there's no telling what sort of stress checking a page multiple times an hour might inflict. Even if<a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen"> Apple has just released the fastest phones</a> we've ever tested.</p><p>But I hope that this is just the start of what Apple has planned, and that Notify Me will be getting an expansion in future versions of iOS and Apple Intelligence. After all, the less we all have to sit in virtual queues to try and get tickets to the next big concert or event, the better.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless"><strong>I tested the iPhone 18 Pro Max's variable aperture camera — here's the results</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/apple-increased-the-price-of-iphone-18-pro-battery-repairs-heres-how-much-youll-pay-now"><strong>Apple increased the price of iPhone 18 Pro battery repairs — here's how much you'll pay now</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/siri-in-ios-27-actually-lives-up-to-the-hype-here-are-the-3-truly-unique-uses"><strong>Siri in iOS 27 actually lives up to the hype — here are 3 truly unique uses</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ iPhone 18 Pro, 18 Pro Max battery size just revealed — here's the official capacity from iFixit's teardown ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Battery capacity for the new <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro</a> and iPhone 18 Pro Max has officially been revealed thanks to <a href="https://www.ifixit.com/">iFixit</a>, which shared the results with Tom's Guide.</p><p>Apple typically doesn't officially list the battery capacity for its iPhones. On the Apple website the only battery spec listed is "Up to 45 hours video playback."</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/QJVNbFMd-zQ" allowfullscreen></iframe></div></div><h2 id="what-ifixit-found">What iFixit found</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="xRhb9BcwotPQZgAgmCvaP3" name="ifixit battery" alt="iFixit iPhone 18 Pro battery capacity reveal" src="https://cdn.mos.cms.futurecdn.net/xRhb9BcwotPQZgAgmCvaP3-1920-80.png" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: iFixit)</span></figcaption></figure><p>From their teardown, iFixit found that the North American i<strong>Phone 18 Pro has a battery capacity of 4,288mAh</strong>. Compared to the iPhone 17 Pro eSIM version, that's only a 1% increase over last year's 4,252 mAh battery. </p><p>In our <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-18-pro-battery-life-tested-the-results-are-surprising">iPhone 18 Pro battery tests</a>, that 1% larger battery capacity added an hour of battery life, up to 16 hours and 17 minutes, compared to 15 hours and 17 minutes on the 17 Pro. Of course, those gains are also attributable to the iPhone 18 Pro's new A20 chip, which is more efficient than the A19 chip in last year's model.</p><p>iFixit also found the <strong>iPhone 18 Pro Max has a 5567 mAh battery</strong>, which is 9.41% larger than the iPhone 17 Pro Max, which has a 5088 mAh battery in the eSIM version. </p><p>Surprisingly, though, that didn't translate into a corresponding increase in battery life; on our tests, the <strong>iPhone 18 Pro Max lasted 18 hours and 27 minutes</strong>, which was barely half an hour longer than the iPhone 17 Pro Max (17:54). </p><p>Interestingly, the iFixit teardown appears to show a different capacity for the U.S. version of the iPhone 18 Pro compared to the EU versions. In Europe, all phones must have a publicly accessible Energy Label which list key details about the device including battery specs.</p><p><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-battery-capacity-confirmed-in-europe-heres-how-they-compare-to-iphone-17-pro">Per the listing we've seen</a>, <strong>iPhone 18 Pro will have </strong><a href="https://apple.sjv.io/c/338476/435410/7643?subId1=tomsguide-us-4874536680432199560&sharedId=tomsguide-us&u=https%3A%2F%2Fregulatoryinfo.apple.com%2Fcwt%2Fapi%2Fext%2Ffile%3FfileId%3DenergyLabels%2FA3714_V1%2FA3714%2FA3714_PIS_LotX_EU_English.pdf" target="_blank"><strong>a 4,056 mAh battery</strong></a>, while the <strong>iPhone 18 Pro Max will offer</strong><a href="https://apple.sjv.io/c/338476/435410/7643?subId1=tomsguide-us-1359959009751235892&sharedId=tomsguide-us&u=https%3A%2F%2Fregulatoryinfo.apple.com%2Fcwt%2Fapi%2Fext%2Ffile%3FfileId%3DenergyLabels%2FA3717_V1%2FA3717%2FA3717_PIS_LotX_EU_English.pdf" target="_blank"><strong> 5,391 mAh capacity. </strong></a>The EU iPhones will likely come with physical SIM card slots and not eSIMs only. This does mean the EU models could differ somewhat.</p><p>Unfortunately, it'll also cost you a bit <a href="https://www.tomsguide.com/phones/iphones/apple-increased-the-price-of-iphone-18-pro-battery-repairs-heres-how-much-youll-pay-now">more to repair the iPhone 18 Pro battery</a> compared to last year's iPhone.</p><p>Apple raised the prices of the iPhone 18 Pro and Pro Max by $100 for the base 256GB model. And if you need to repair the battery, Apple will charge you $129 (plus tax), $10 more than for the iPhone 17 Pro.</p><p>Other repairs appear to have remained the same, though the prices are still high, making <a href="https://www.tomsguide.com/news/what-is-applecare">AppleCare+</a> more enticing.</p><p>Notably, the last time Apple charged more for battery repairs was when it launched the iPhone 16 Pro, which also saw an overall price increase.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/airpods/apple-airpods-5-review"><strong>I tested the AirPods 5 — they're $50 cheaper than the AirPods 4 but 100% better</strong></a></li><li><a href="https://www.tomsguide.com/phones/iphones/siri-in-ios-27-actually-lives-up-to-the-hype-here-are-the-3-truly-unique-uses"><strong>Siri in iOS 27 actually lives up to the hype — here are 3 truly unique uses</strong></a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen"><strong>iPhone 18 Pro and Pro Max benchmarks: These are the fastest phones we've ever tested</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/iphone-18-pro-battery-size-just-revealed-heres-the-official-capacity-from-ifixits-teardown</link>
                                                                            <description>
                            <![CDATA[ The battery capacity for the iPhone 18 Pro and iPhone 18 Pro Max have officially been revealed, thanks to iFixit. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">C7ssBKrUWeazvRsrfGcFDn</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/HYuuDMJ2Ch2YMUKD2MbYWc-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 18 Sep 2026 21:17:21 +0000</pubDate>                                                                                                                                <updated>Fri, 18 Sep 2026 23:48:14 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ scott.younker@futurenet.com (Scott Younker) ]]></author>                    <dc:creator><![CDATA[ Scott Younker ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/RZsUpqcJ6Uj2q83oCUwNhQ-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Scott Younker is the West Coast Reporter at Tom’s Guide. He covers all the latest tech news, including phones, computing and more. He’s been involved in tech since 2011 covering everything from cameras and swimming pool equipment to the latest gaming consoles and smart TVs. He is on a seemingly never ending hunt to build the easiest to use home media system. &lt;/p&gt;&lt;p&gt;Before Tom’s Guide, Scott worked for publications like &lt;em&gt;Digital Trends, Outdoor Photographer, Dead Beats Panel&lt;/em&gt;, and in a brief detour, &lt;em&gt;America’s Funniest Home Videos&lt;/em&gt;. Yes, he has seen more pratfalls, silly pets and ridiculous home movie fails than is reasonably healthy. &lt;/p&gt;&lt;p&gt;When not writing about the latest devices or advances in chipsets, be sure to ask about Scott about disc golf and sustainability, or just if you’re being cheeky, ask about his noodle arm. If you truly want to get nerdy, bring up board games and his ongoing losing streak. &lt;/p&gt;&lt;p&gt;Scott joined Tom&#039;s Guide in 2024 as the West Coast Reporter. He graduated from the School of Journalism at the University of Oregon with a degree in magazine journalism and a minor in communications. While there he blogged or wrote for several magazines including the Fluxx, Ethos and the Oregon Commentator. He briefly wrote and managed a moderately successful blog focused on web comics. &lt;br&gt;Send secure tips on Signal: scyo1.55.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/HYuuDMJ2Ch2YMUKD2MbYWc-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 18 Pro cameras]]></media:description>                                                            <media:text><![CDATA[iPhone 18 Pro cameras]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 18 Pro cameras]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/HYuuDMJ2Ch2YMUKD2MbYWc-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Battery capacity for the new <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro</a> and iPhone 18 Pro Max has officially been revealed thanks to <a href="https://www.ifixit.com/">iFixit</a>, which shared the results with Tom's Guide.</p><p>Apple typically doesn't officially list the battery capacity for its iPhones. On the Apple website the only battery spec listed is "Up to 45 hours video playback."</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/QJVNbFMd-zQ" allowfullscreen></iframe></div></div><h2 id="what-ifixit-found">What iFixit found</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="xRhb9BcwotPQZgAgmCvaP3" name="ifixit battery" alt="iFixit iPhone 18 Pro battery capacity reveal" src="https://cdn.mos.cms.futurecdn.net/xRhb9BcwotPQZgAgmCvaP3-1920-80.png" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: iFixit)</span></figcaption></figure><p>From their teardown, iFixit found that the North American i<strong>Phone 18 Pro has a battery capacity of 4,288mAh</strong>. Compared to the iPhone 17 Pro eSIM version, that's only a 1% increase over last year's 4,252 mAh battery. </p><p>In our <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-18-pro-battery-life-tested-the-results-are-surprising">iPhone 18 Pro battery tests</a>, that 1% larger battery capacity added an hour of battery life, up to 16 hours and 17 minutes, compared to 15 hours and 17 minutes on the 17 Pro. Of course, those gains are also attributable to the iPhone 18 Pro's new A20 chip, which is more efficient than the A19 chip in last year's model.</p><p>iFixit also found the <strong>iPhone 18 Pro Max has a 5567 mAh battery</strong>, which is 9.41% larger than the iPhone 17 Pro Max, which has a 5088 mAh battery in the eSIM version. </p><p>Surprisingly, though, that didn't translate into a corresponding increase in battery life; on our tests, the <strong>iPhone 18 Pro Max lasted 18 hours and 27 minutes</strong>, which was barely half an hour longer than the iPhone 17 Pro Max (17:54). </p><p>Interestingly, the iFixit teardown appears to show a different capacity for the U.S. version of the iPhone 18 Pro compared to the EU versions. In Europe, all phones must have a publicly accessible Energy Label which list key details about the device including battery specs.</p><p><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-battery-capacity-confirmed-in-europe-heres-how-they-compare-to-iphone-17-pro">Per the listing we've seen</a>, <strong>iPhone 18 Pro will have </strong><a href="https://apple.sjv.io/c/338476/435410/7643?subId1=tomsguide-us-4874536680432199560&sharedId=tomsguide-us&u=https%3A%2F%2Fregulatoryinfo.apple.com%2Fcwt%2Fapi%2Fext%2Ffile%3FfileId%3DenergyLabels%2FA3714_V1%2FA3714%2FA3714_PIS_LotX_EU_English.pdf" target="_blank"><strong>a 4,056 mAh battery</strong></a>, while the <strong>iPhone 18 Pro Max will offer</strong><a href="https://apple.sjv.io/c/338476/435410/7643?subId1=tomsguide-us-1359959009751235892&sharedId=tomsguide-us&u=https%3A%2F%2Fregulatoryinfo.apple.com%2Fcwt%2Fapi%2Fext%2Ffile%3FfileId%3DenergyLabels%2FA3717_V1%2FA3717%2FA3717_PIS_LotX_EU_English.pdf" target="_blank"><strong> 5,391 mAh capacity. </strong></a>The EU iPhones will likely come with physical SIM card slots and not eSIMs only. This does mean the EU models could differ somewhat.</p><p>Unfortunately, it'll also cost you a bit <a href="https://www.tomsguide.com/phones/iphones/apple-increased-the-price-of-iphone-18-pro-battery-repairs-heres-how-much-youll-pay-now">more to repair the iPhone 18 Pro battery</a> compared to last year's iPhone.</p><p>Apple raised the prices of the iPhone 18 Pro and Pro Max by $100 for the base 256GB model. And if you need to repair the battery, Apple will charge you $129 (plus tax), $10 more than for the iPhone 17 Pro.</p><p>Other repairs appear to have remained the same, though the prices are still high, making <a href="https://www.tomsguide.com/news/what-is-applecare">AppleCare+</a> more enticing.</p><p>Notably, the last time Apple charged more for battery repairs was when it launched the iPhone 16 Pro, which also saw an overall price increase.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/airpods/apple-airpods-5-review"><strong>I tested the AirPods 5 — they're $50 cheaper than the AirPods 4 but 100% better</strong></a></li><li><a href="https://www.tomsguide.com/phones/iphones/siri-in-ios-27-actually-lives-up-to-the-hype-here-are-the-3-truly-unique-uses"><strong>Siri in iOS 27 actually lives up to the hype — here are 3 truly unique uses</strong></a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen"><strong>iPhone 18 Pro and Pro Max benchmarks: These are the fastest phones we've ever tested</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ iPhone 18 Pro and Pro Max deals are live — here's the biggest discounts at T-Mobile, Verizon and more ]]></title>
                                                                                                <dc:content><![CDATA[ <p>The 6.3-inch <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro</a> and 6.9-inch <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max</a> cost $1,199 and $1,299, respectively. That's $100 pricier than their predecessors. Fortunately, there are plenty of iPhone 18 Pro deals you can take advantage of right now. </p><p>I've been buying iPhones since the 6s, so when it comes to deals I know where to look. For example, right now <a href="https://tmobilepostpaid.pxf.io/c/1943169/4032247/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow">T-Mobile is offering the iPhone 18 Pro for free</a> when you bring your number and open an Experience Beyond plan. Or you can get it for free with trade-in and an Experience Beyond plan. That's one of the best iPhone 18 Pro deals around. </p><p>Prefer the bigger screen of the iPhone 18 Pro Max? <a href="https://www.verizon.com/smartphones/apple-iphone-18-pro-max/?isMyPlanFlow=true" target="_blank" rel="nofollow">Verizon is taking up to $1,200 off the iPhone 18 Pro Max</a> when you open a new line and trade-in an old phone. You'll even get NFL Sunday Ticket by YouTube for free with your account. </p><p>Below I've found all of the best iPhone 18 Pro deals at carriers and retailers alike. I'm also tracking all the <a href="https://www.tomsguide.com/phones/iphones/warning-here-are-all-the-iphone-18-pro-shipping-delays-at-t-mobile-verizon-at-and-t-and-more">iPhone 18 Pro delays</a>, so you know when you can expect your phone to arrive. If you're looking for deals on accessories, <a href="https://www.amazon.com/stores/page/7FF33670-28E4-48AA-9D38-3B9010BB6947" target="_blank" rel="nofollow">Amazon has iPhone accessories from $14</a> including cases, cables, chargers, AirPods, and more.</p><h3 class="article-body__section" id="section-quick-links"><span>Quick Links</span></h3><ul><li><strong>T-Mobile: </strong><a href="https://tmobilepostpaid.pxf.io/c/1943169/3726747/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow"><strong>free w/ new line + unlimited </strong></a><strong></strong></li><li><strong>Verizon: </strong><a href="https://www.verizon.com/smartphones/apple-iphone-18-pro/?isMyPlanFlow=true" target="_blank" rel="nofollow"><strong>free w/ new line + trade-in on eligible myPlan</strong></a><strong></strong></li><li><strong>AT&T: </strong><a href="https://www.att.com/buy/phones/apple-iphone-18-pro.html" target="_blank" rel="nofollow"><strong>up to $1,200 off w/ new line or trade</strong></a></li><li><strong>Xfinity Mobile: </strong><a href="https://www.xfinity.com/learn/mobile" target="_blank" rel="nofollow"><strong>up to $1,300 off any new iPhone w/ trade + unlimited</strong></a><strong></strong></li><li><strong>Mint Mobile: </strong><a href="https://www.mintmobile.com/phone-plans/3-month-plans/" target="_blank" rel="nofollow"><strong>up to 50% off 3-month data plans</strong></a><strong></strong></li><li><strong>Visible: </strong><a href="https://www.visible.com/shop/smartphones/iphone-18-pro?sku=MJQ54LL/A" target="_blank" rel="nofollow"><strong>$480 off any new iPhone purchase w/ unlimited</strong></a><strong></strong></li><li><strong>Walmart: </strong><a href="https://www.walmart.com/ip/AT-T-iPhone-18-Pro-256GB-Glacier/20973750630" target="_blank" rel="nofollow"><strong>from $31/month on select carriers</strong></a><strong></strong></li><li><strong>Red Pocket: </strong><a href="https://www.redpocket.com/shop/iphone/apple-iphone-18-pro-unlocked" target="_blank" rel="nofollow"><strong>$100 off iPhone 18 Pro or Pro Max</strong></a></li><li><strong>Apple Store: </strong><a href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow"><strong>up to $885 off w/ trade-in @ Apple</strong></a></li><li><strong>iPhone accessories: </strong><a href="https://www.amazon.com/stores/page/7FF33670-28E4-48AA-9D38-3B9010BB6947" target="_blank" rel="nofollow"><strong>from $7 @ Amazon</strong></a><strong></strong></li></ul><h3 class="article-body__section" id="section-iphone-18-pro"><span>iPhone 18 Pro</span></h3><div class="product"><a data-dimension112="82ce626a-b2dc-11f1-b0c3-a98753575a8a" data-action="Deal Block" data-label="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" href="https://tmobilepostpaid.pxf.io/c/1943169/4032247/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:50.00%;"><img id="Y26QJd7Ff7aeQmTHuW8nCP" name="NEW T-Mobile Logo" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Y26QJd7Ff7aeQmTHuW8nCP-1920-80.png" mos="" align="middle" fullscreen="" width="600" height="300" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro: </strong><a href="https://tmobilepostpaid.pxf.io/c/1943169/4032247/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow" data-dimension112="82ce626a-b2dc-11f1-b0c3-a98753575a8a" data-action="Deal Block" data-label="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension25=""><strong>free w/ trade-in + unlimited @ T-Mobile</strong></a><br>T-Mobile is offering the iPhone 18 Pro for free when you switch and bring your number or when you trade-in an eligible phone and sign up for T-Mobile's Experience Beyond plan. In our <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro review</a>, we said its the best phone money can buy. The iPhone 18 Pro features a 6.3-inch OLED 120Hz display (2622 x 1206), A20 Pro chipset, and 256GB of storage. You also get a 48MP main, 48MP ultrawide, and 48MP telephoto lens w/ 4x zoom. The front camera is 18MP. <a class="view-deal button" href="https://tmobilepostpaid.pxf.io/c/1943169/4032247/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow" data-dimension112="82ce626a-b2dc-11f1-b0c3-a98753575a8a" data-action="Deal Block" data-label="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce6332-b2dc-11f1-9875-45193ceb5368" data-action="Deal Block" data-label="iPhone 18 Pro: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension48="iPhone 18 Pro: up to $1,200 off w/ new line or trade @ AT&amp;T" href="https://www.att.com/buy/phones/apple-iphone-18-pro.html" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:225px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="o9PdShQsgAk95AN7C5UMNR" name="AT&T Logo.jpeg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/o9PdShQsgAk95AN7C5UMNR-1920-80.jpeg" mos="" align="middle" fullscreen="" width="225" height="225" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro: </strong><a href="https://www.att.com/buy/phones/apple-iphone-18-pro.html" target="_blank" rel="nofollow" data-dimension112="82ce6332-b2dc-11f1-9875-45193ceb5368" data-action="Deal Block" data-label="iPhone 18 Pro: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension48="iPhone 18 Pro: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension25=""><strong>up to $1,200 off w/ new line or trade @ AT&T</strong></a><br>New and existing AT&T customers can get up to $1,200 off the iPhone 18 Pro when you trade-in any iPhone in any condition. New customers can also get up to $800 to pay off any devices that are still in contract. <a class="view-deal button" href="https://www.att.com/buy/phones/apple-iphone-18-pro.html" target="_blank" rel="nofollow" data-dimension112="82ce6332-b2dc-11f1-9875-45193ceb5368" data-action="Deal Block" data-label="iPhone 18 Pro: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension48="iPhone 18 Pro: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce62ce-b2dc-11f1-ae85-25776ca81f9c" data-action="Deal Block" data-label="iPhone 18 Pro: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension48="iPhone 18 Pro: up to $1,200 off w/ new line + trade-in @ Verizon" href="https://www.verizon.com/smartphones/apple-iphone-18-pro/?isMyPlanFlow=true" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:400px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="bhuNLVbkmhJxHuYhoz9cuY" name="verizon-redesign-thumb.jpeg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/bhuNLVbkmhJxHuYhoz9cuY-1920-80.jpg" mos="" align="middle" fullscreen="" width="400" height="400" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro: </strong><a href="https://www.verizon.com/smartphones/apple-iphone-18-pro/?isMyPlanFlow=true" target="_blank" rel="nofollow" data-dimension112="82ce62ce-b2dc-11f1-ae85-25776ca81f9c" data-action="Deal Block" data-label="iPhone 18 Pro: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension48="iPhone 18 Pro: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension25=""><strong>up to $1,200 off w/ new line + trade-in @ Verizon</strong></a><br>Verizon will take up to $1,200 off your iPhone 18 Pro when you open a new line, trade-in an old phone, and open an eligible unlimited data plan. <a class="view-deal button" href="https://www.verizon.com/smartphones/apple-iphone-18-pro/?isMyPlanFlow=true" target="_blank" rel="nofollow" data-dimension112="82ce62ce-b2dc-11f1-ae85-25776ca81f9c" data-action="Deal Block" data-label="iPhone 18 Pro: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension48="iPhone 18 Pro: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce6404-b2dc-11f1-81bc-33559aee3d8f" data-action="Deal Block" data-label="iPhone 18 Pro: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension48="iPhone 18 Pro: free w/ trade-in + unlimited @ Xfinity Mobile" href="https://www.xfinity.com/learn/mobile" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1413px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="MEg942YDCTSzn9H3vsaqPj" name="xfinity-mobile.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/MEg942YDCTSzn9H3vsaqPj-1920-80.jpg" mos="" align="middle" fullscreen="" width="1413" height="1413" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro: </strong><a href="https://www.xfinity.com/learn/mobile" target="_blank" rel="nofollow" data-dimension112="82ce6404-b2dc-11f1-81bc-33559aee3d8f" data-action="Deal Block" data-label="iPhone 18 Pro: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension48="iPhone 18 Pro: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension25=""><strong>free w/ trade-in + unlimited @ Xfinity Mobile</strong></a><br>New and existing Xfinity Mobile Plus customers can get the iPhone 18 Pro for free when trade-in a device and open a new line with eligible data plan. New customers must activate a new Xfinity Mobile line within 30 days of purchase, whereas existing customers can upgrade one of their existing lines to receive the deal. <a class="view-deal button" href="https://www.xfinity.com/learn/mobile" target="_blank" rel="nofollow" data-dimension112="82ce6404-b2dc-11f1-81bc-33559aee3d8f" data-action="Deal Block" data-label="iPhone 18 Pro: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension48="iPhone 18 Pro: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce6396-b2dc-11f1-91f3-374d995ab367" data-action="Deal Block" data-label="Mint Mobile: $15 off any 3-month plan @ Mint Mobile" data-dimension48="Mint Mobile: $15 off any 3-month plan @ Mint Mobile" data-dimension25="$" href="https://www.mintmobile.com/phone-plans/3-month-plans/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:606px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="w2sEQkELQqB3oTd6G5arL5" name="mint-mobile-logo-recobox.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/w2sEQkELQqB3oTd6G5arL5-1920-80.jpg" mos="" align="middle" fullscreen="" width="606" height="606" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>Mint Mobile: </strong><a href="https://www.mintmobile.com/phone-plans/3-month-plans/" target="_blank" rel="nofollow" data-dimension112="82ce6396-b2dc-11f1-91f3-374d995ab367" data-action="Deal Block" data-label="Mint Mobile: $15 off any 3-month plan @ Mint Mobile" data-dimension48="Mint Mobile: $15 off any 3-month plan @ Mint Mobile" data-dimension25="$"><strong>$15 off any 3-month plan @ Mint Mobile</strong></a><br>It's not a preorder deal per se, but if you want to save on data — you'll want to check out this Mint Mobile offer. For a limited time, Mint Mobile is taking $15 off any 3-month plan. After discount, the 3-month Unlimited plan costs $15/month ($45 upfront). That's one of the best Mint Mobile deals I've seen. <a class="view-deal button" href="https://www.mintmobile.com/phone-plans/3-month-plans/" target="_blank" rel="nofollow" data-dimension112="82ce6396-b2dc-11f1-91f3-374d995ab367" data-action="Deal Block" data-label="Mint Mobile: $15 off any 3-month plan @ Mint Mobile" data-dimension48="Mint Mobile: $15 off any 3-month plan @ Mint Mobile" data-dimension25="$">View Deal</a></p></div><div class="product"><a data-dimension112="82ce64cc-b2dc-11f1-960c-09fe28238b7a" data-action="Deal Block" data-label="Visible: $480 off w/ new iPhone @ Visible" data-dimension48="Visible: $480 off w/ new iPhone @ Visible" href="https://www.visible.com/shop/smartphones/iphone-18-pro?sku=MJQ54LL/A" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1000px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="nXRVmdXfPxa8NUZ7ukyY7P" name="visible_logo_new.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/nXRVmdXfPxa8NUZ7ukyY7P-1920-80.jpg" mos="" align="middle" fullscreen="" width="1000" height="1000" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>Visible: </strong><a href="https://www.visible.com/shop/smartphones/iphone-18-pro?sku=MJQ54LL/A" target="_blank" rel="nofollow" data-dimension112="82ce64cc-b2dc-11f1-960c-09fe28238b7a" data-action="Deal Block" data-label="Visible: $480 off w/ new iPhone @ Visible" data-dimension48="Visible: $480 off w/ new iPhone @ Visible" data-dimension25=""><strong>$480 off w/ new iPhone @ Visible</strong></a><br>Visible's iPhone 18 Pro deal is pretty straightforward. Buy any new iPhone with the Visible+ Pro plan and you'll get $480 back via monthly credits over the span of 24 months. Visible+ Pro costs $45/month and includes unlimited premium data on Verizon's 5G Ultra Wideband network, smartwatch data plan service, and up to 4K UHD video streaming. <a class="view-deal button" href="https://www.visible.com/shop/smartphones/iphone-18-pro?sku=MJQ54LL/A" target="_blank" rel="nofollow" data-dimension112="82ce64cc-b2dc-11f1-960c-09fe28238b7a" data-action="Deal Block" data-label="Visible: $480 off w/ new iPhone @ Visible" data-dimension48="Visible: $480 off w/ new iPhone @ Visible" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="1b9144b6-b389-11f1-b4db-e5ff482b4ca5" data-action="Deal Block" data-label="iPhone 18 Pro" data-dimension48="iPhone 18 Pro" data-dimension25="$1099" href="https://www.redpocket.com/shop/iphone/apple-iphone-18-pro-unlocked" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:374px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="2Rb63M2Ym3t5t2s8BWCeLK" name="Red Pocket Mobile logo" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/2Rb63M2Ym3t5t2s8BWCeLK-1920-80.png" mos="" align="middle" fullscreen="" width="374" height="374" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>RedPocket Mobile is an MVNO that lets you choose between using AT&T's, T-Mobile's, or Verizon's network. Right now, you can get the iPhone 18 Pro for $1,099 ($100 off) with no port or trade-in required. Unlimited data plans start from $10/month or $100/year. <a class="view-deal button" href="https://www.redpocket.com/shop/iphone/apple-iphone-18-pro-unlocked" target="_blank" rel="nofollow" data-dimension112="1b9144b6-b389-11f1-b4db-e5ff482b4ca5" data-action="Deal Block" data-label="iPhone 18 Pro" data-dimension48="iPhone 18 Pro" data-dimension25="$1099">View Deal</a></p></div><div class="product"><a data-dimension112="1b91454c-b389-11f1-9076-917394898d0a" data-action="Deal Block" data-label="iPhone 18 Pro" data-dimension48="iPhone 18 Pro" data-dimension25="$999" href="https://www.boostmobile.com/shop/iphone-18-pro.html" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:713px;"><p class="vanilla-image-block" style="padding-top:38.85%;"><img id="UGYgmHB5HuHtAFmJHSMZnU" name="Boost Mobile logo 2024.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/UGYgmHB5HuHtAFmJHSMZnU-1920-80.jpg" mos="" align="middle" fullscreen="" width="713" height="277" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>Boost Mobile is offering the iPhone 18 Pro for $999 when you bring your line and sign up for Boost's Unlimited Premium plan ($60/month). The plan includes unlimited talk, text, and 50GB of premium/high-speed data as well as global talk/text and mobile hotspot. Or you can get it for $1,099 when you open a new Unlimited Premium plan. <a class="view-deal button" href="https://www.boostmobile.com/shop/iphone-18-pro.html" target="_blank" rel="nofollow" data-dimension112="1b91454c-b389-11f1-9076-917394898d0a" data-action="Deal Block" data-label="iPhone 18 Pro" data-dimension48="iPhone 18 Pro" data-dimension25="$999">View Deal</a></p></div><div class="product"><a data-dimension112="82ce6468-b2dc-11f1-97f9-8fc058d17290" data-action="Deal Block" data-label="iPhone 18 Pro: up to $600 off w/ unlimited @ Total Wireless" data-dimension48="iPhone 18 Pro: up to $600 off w/ unlimited @ Total Wireless" href="https://www.totalwireless.com/m/home" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="Z3gikFPLPLmWFv4RSSgxVh" name="total-square.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Z3gikFPLPLmWFv4RSSgxVh-1920-80.jpg" mos="" align="middle" fullscreen="" width="600" height="600" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro: </strong><a href="https://www.totalwireless.com/m/home" target="_blank" rel="nofollow" data-dimension112="82ce6468-b2dc-11f1-97f9-8fc058d17290" data-action="Deal Block" data-label="iPhone 18 Pro: up to $600 off w/ unlimited @ Total Wireless" data-dimension48="iPhone 18 Pro: up to $600 off w/ unlimited @ Total Wireless" data-dimension25=""><strong>up to $600 off w/ unlimited @ Total Wireless</strong></a><br>Total Wireless is taking up to $600 off the iPhone 18 Pro. You'll get a $25/monthly bill credit (over 24 months) when you stay on Total Wireless' All Access plan. <a class="view-deal button" href="https://www.totalwireless.com/m/home" target="_blank" rel="nofollow" data-dimension112="82ce6468-b2dc-11f1-97f9-8fc058d17290" data-action="Deal Block" data-label="iPhone 18 Pro: up to $600 off w/ unlimited @ Total Wireless" data-dimension48="iPhone 18 Pro: up to $600 off w/ unlimited @ Total Wireless" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce6530-b2dc-11f1-9df9-3f1c1e641363" data-action="Deal Block" data-label="iPhone 18 Pro: from $31/month @ Walmart" data-dimension48="iPhone 18 Pro: from $31/month @ Walmart" href="https://www.walmart.com/ip/AT-T-iPhone-18-Pro-256GB-Glacier/20973750630" 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:93.65%;"><img id="Bi2iDjTxUHTUQK9FHZ4W8D" name="Walmart logo.jpeg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Bi2iDjTxUHTUQK9FHZ4W8D-1920-80.jpeg" mos="" align="middle" fullscreen="" width="960" height="899" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro: </strong><a href="https://www.walmart.com/ip/AT-T-iPhone-18-Pro-256GB-Glacier/20973750630" target="_blank" rel="nofollow" data-dimension112="82ce6530-b2dc-11f1-9df9-3f1c1e641363" data-action="Deal Block" data-label="iPhone 18 Pro: from $31/month @ Walmart" data-dimension48="iPhone 18 Pro: from $31/month @ Walmart" data-dimension25=""><strong>from $31/month @ Walmart</strong></a><br>Walmart is offering the iPhone 18 Pro for AT&T, Verizon, or T-Mobile from $31/month. The phone is available in all colors and storage capacities, although some models are starting to sell out. <a class="view-deal button" href="https://www.walmart.com/ip/AT-T-iPhone-18-Pro-256GB-Glacier/20973750630" target="_blank" rel="nofollow" data-dimension112="82ce6530-b2dc-11f1-9df9-3f1c1e641363" data-action="Deal Block" data-label="iPhone 18 Pro: from $31/month @ Walmart" data-dimension48="iPhone 18 Pro: from $31/month @ Walmart" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce6594-b2dc-11f1-9bb3-6ff3d9e48857" data-action="Deal Block" data-label="iPhone 18 Pro: up to $480 off @ StraightTalk" data-dimension48="iPhone 18 Pro: up to $480 off @ StraightTalk" href="https://www.straighttalk.com/all-phones/apple-iphone-18-pro-256gb-prepaid" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:264px;"><p class="vanilla-image-block" style="padding-top:72.35%;"><img id="jg63LBik54HBQtDrbyFRh8" name="StraightTalk logo.png" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/jg63LBik54HBQtDrbyFRh8-1920-80.png" mos="" align="middle" fullscreen="" width="264" height="191" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro: </strong><a href="https://www.straighttalk.com/all-phones/apple-iphone-18-pro-256gb-prepaid" target="_blank" rel="nofollow" data-dimension112="82ce6594-b2dc-11f1-9bb3-6ff3d9e48857" data-action="Deal Block" data-label="iPhone 18 Pro: up to $480 off @ StraightTalk" data-dimension48="iPhone 18 Pro: up to $480 off @ StraightTalk" data-dimension25=""><strong>up to $480 off @ StraightTalk</strong></a><br>StraightTalk is taking up to $480 off the iPhone 18 Pro. You'll get $20 off your monthly bill over the span of 24 months when you activate a Gold Unlimited plan or higher. <a class="view-deal button" href="https://www.straighttalk.com/all-phones/apple-iphone-18-pro-256gb-prepaid" target="_blank" rel="nofollow" data-dimension112="82ce6594-b2dc-11f1-9bb3-6ff3d9e48857" data-action="Deal Block" data-label="iPhone 18 Pro: up to $480 off @ StraightTalk" data-dimension48="iPhone 18 Pro: up to $480 off @ StraightTalk" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="a1cee7fe-b5dc-11f1-a9da-c5e2fec625c8" data-action="Deal Block" data-label="iPhone 18 Pro" data-dimension48="iPhone 18 Pro" data-dimension25="$899" href="https://www.metrobyt-mobile.com/cell-phone/apple-iphone-18-pro" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:300px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="UrMF7jvSAWeMTgQPNEmbqD" name="metrobytmobilelogo.jpeg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/UrMF7jvSAWeMTgQPNEmbqD-1920-80.jpeg" mos="" align="middle" fullscreen="" width="300" height="300" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>Metro by T-Mobile is offering a handful of iPhone 18 Pro deals starting from $899. To get this price, you'll need to port your number to Metro by T-Mobile and set up AutoPay. You can also get it for $999 when you bring your number and opt for the $40 Period web plan. <a class="view-deal button" href="https://www.metrobyt-mobile.com/cell-phone/apple-iphone-18-pro" target="_blank" rel="nofollow" data-dimension112="a1cee7fe-b5dc-11f1-a9da-c5e2fec625c8" data-action="Deal Block" data-label="iPhone 18 Pro" data-dimension48="iPhone 18 Pro" data-dimension25="$899">View Deal</a></p></div><div class="product"><a data-dimension112="82ce65f8-b2dc-11f1-a8c6-7594da732413" data-action="Deal Block" data-label="iPhone 18 Pro: up to $885 w/ trade-in @ Apple Store" data-dimension48="iPhone 18 Pro: up to $885 w/ trade-in @ Apple Store" href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:66.67%;"><img id="4Y3oAjs2dPF6xp4nhVsVcc" name="Applelogo.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/4Y3oAjs2dPF6xp4nhVsVcc-1920-80.jpg" mos="" align="middle" fullscreen="" width="600" height="400" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro: </strong><a href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow" data-dimension112="82ce65f8-b2dc-11f1-a8c6-7594da732413" data-action="Deal Block" data-label="iPhone 18 Pro: up to $885 w/ trade-in @ Apple Store" data-dimension48="iPhone 18 Pro: up to $885 w/ trade-in @ Apple Store" data-dimension25=""><strong>up to $885 w/ trade-in @ Apple Store</strong></a><br>The Apple Store is offering up to a $885 credit when you trade-in your old smartphone for one of the new iPhone 18 Pro models. For example, an iPhone 15 will get you up to a $305 credit, whereas an iPhone 13 Pro will get you up to a $255 credit. The iPhone 18 Pro features a 6.3-inch OLED 120Hz display (2622 x 1206), A20 Pro chipset, and 256GB of storage. You also get a 48MP main, 48MP ultrawide, and 48MP telephoto lens w/ 4x zoom. The front camera is 18MP. <a class="view-deal button" href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow" data-dimension112="82ce65f8-b2dc-11f1-a8c6-7594da732413" data-action="Deal Block" data-label="iPhone 18 Pro: up to $885 w/ trade-in @ Apple Store" data-dimension48="iPhone 18 Pro: up to $885 w/ trade-in @ Apple Store" data-dimension25="">View Deal</a></p></div><h3 class="article-body__section" id="section-iphone-18-pro-max"><span>iPhone 18 Pro Max</span></h3><div class="product"><a data-dimension112="82ce6742-b2dc-11f1-a953-1dbfb96f129b" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" href="https://tmobilepostpaid.pxf.io/c/1943169/4032248/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:50.00%;"><img id="Y26QJd7Ff7aeQmTHuW8nCP" name="NEW T-Mobile Logo" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Y26QJd7Ff7aeQmTHuW8nCP-1920-80.png" mos="" align="middle" fullscreen="" width="600" height="300" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro Max: </strong><a href="https://tmobilepostpaid.pxf.io/c/1943169/4032248/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow" data-dimension112="82ce6742-b2dc-11f1-a953-1dbfb96f129b" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension25=""><strong>up to $1,200 off w/ trade-in + unlimited @ T-Mobile</strong></a><br>T-Mobile is taking up to $1,200 off the iPhone 18 Pro Max when you trade-in an old device and sign up for an eligible unlimited data plan. <a class="view-deal button" href="https://tmobilepostpaid.pxf.io/c/1943169/4032248/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow" data-dimension112="82ce6742-b2dc-11f1-a953-1dbfb96f129b" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce66de-b2dc-11f1-8e7a-f98b3d9ab0c5" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ new line + trade-in @ Verizon" href="https://www.verizon.com/smartphones/apple-iphone-18-pro-max/?isMyPlanFlow=true" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3321px;"><p class="vanilla-image-block" style="padding-top:40.98%;"><img id="R4vXmWQKAkSdQs7bVstjs8" name="Verizon logo 2024.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/R4vXmWQKAkSdQs7bVstjs8-1920-80.jpg" mos="" align="middle" fullscreen="" width="3321" height="1361" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro Max: </strong><a href="https://www.verizon.com/smartphones/apple-iphone-18-pro-max/?isMyPlanFlow=true" target="_blank" rel="nofollow" data-dimension112="82ce66de-b2dc-11f1-8e7a-f98b3d9ab0c5" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension25=""><strong>up to $1,200 off w/ new line + trade-in @ Verizon</strong></a><br>Verizon will take up to $1,200 off your iPhone 18 Pro Max when you open a new line, trade-in an old phone, and open an eligible unlimited data plan. In our <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max review</a>, we said the A20 chip raises the bar for performance in a smartphone. It features a 6.9-inch OLED 120Hz display (2868 x 1320), A20 Pro chipset, and 256GB of storage. You also get a 48MP main, 48MP ultrawide, and 48MP telephoto lens w/ 4x zoom. The front camera is 18MP. <a class="view-deal button" href="https://www.verizon.com/smartphones/apple-iphone-18-pro-max/?isMyPlanFlow=true" target="_blank" rel="nofollow" data-dimension112="82ce66de-b2dc-11f1-8e7a-f98b3d9ab0c5" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce67a6-b2dc-11f1-b48a-177831517a30" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ new line or trade @ AT&amp;T" href="https://www.att.com/buy/phones/apple-iphone-18-pro-max.html" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:225px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="o9PdShQsgAk95AN7C5UMNR" name="AT&T Logo.jpeg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/o9PdShQsgAk95AN7C5UMNR-1920-80.jpeg" mos="" align="middle" fullscreen="" width="225" height="225" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro Max: </strong><a href="https://www.att.com/buy/phones/apple-iphone-18-pro.html" target="_blank" rel="nofollow" data-dimension112="82ce67a6-b2dc-11f1-b48a-177831517a30" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension25=""><strong>up to $1,200 off w/ new line or trade @ AT&T</strong></a><br>New and existing AT&T customers can get up to $1,200 off the iPhone 18 Pro Max when you trade-in any iPhone in any condition. New customers can also get up to $800 to pay off any devices that are still in contract. <a class="view-deal button" href="https://www.att.com/buy/phones/apple-iphone-18-pro-max.html" target="_blank" rel="nofollow" data-dimension112="82ce67a6-b2dc-11f1-b48a-177831517a30" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce680a-b2dc-11f1-aa5a-d9c45db6d226" data-action="Deal Block" data-label="iPhone 18 Pro Max: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension48="iPhone 18 Pro Max: free w/ trade-in + unlimited @ Xfinity Mobile" href="https://www.xfinity.com/learn/mobile" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1413px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="MEg942YDCTSzn9H3vsaqPj" name="xfinity-mobile.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/MEg942YDCTSzn9H3vsaqPj-1920-80.jpg" mos="" align="middle" fullscreen="" width="1413" height="1413" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro Max: </strong><a href="https://www.xfinity.com/learn/mobile" target="_blank" rel="nofollow" data-dimension112="82ce680a-b2dc-11f1-aa5a-d9c45db6d226" data-action="Deal Block" data-label="iPhone 18 Pro Max: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension48="iPhone 18 Pro Max: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension25=""><strong>free w/ trade-in + unlimited @ Xfinity Mobile</strong></a><br>New and existing Xfinity Mobile customers can get the iPhone 18 Pro Max for free with a Mobile Plus plan and trade-in. New customers must activate a new Xfinity Mobile line within 30 days of purchase, whereas existing customers can upgrade one of their existing lines to receive the deal. <a class="view-deal button" href="https://www.xfinity.com/learn/mobile" target="_blank" rel="nofollow" data-dimension112="82ce680a-b2dc-11f1-aa5a-d9c45db6d226" data-action="Deal Block" data-label="iPhone 18 Pro Max: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension48="iPhone 18 Pro Max: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="1b91468c-b389-11f1-9e88-9394227d2ca7" data-action="Deal Block" data-label="iPhone 18 Pro Max" data-dimension48="iPhone 18 Pro Max" data-dimension25="$1199" href="https://www.redpocket.com/shop/iphone/apple-iphone-18-pro-max-unlocked" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:374px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="2Rb63M2Ym3t5t2s8BWCeLK" name="Red Pocket Mobile logo" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/2Rb63M2Ym3t5t2s8BWCeLK-1920-80.png" mos="" align="middle" fullscreen="" width="374" height="374" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>RedPocket Mobile is an MVNO that lets you choose between using AT&T's, T-Mobile's, or Verizon's network. Right now, you can get the iPhone 18 Pro Max for $1,199 ($100 off) with no port or trade-in required. Unlimited data plans start from $10/month or $100/year. <a class="view-deal button" href="https://www.redpocket.com/shop/iphone/apple-iphone-18-pro-max-unlocked" target="_blank" rel="nofollow" data-dimension112="1b91468c-b389-11f1-9e88-9394227d2ca7" data-action="Deal Block" data-label="iPhone 18 Pro Max" data-dimension48="iPhone 18 Pro Max" data-dimension25="$1199">View Deal</a></p></div><div class="product"><a data-dimension112="82ce686e-b2dc-11f1-8178-3d37da490693" data-action="Deal Block" data-label="Visible: $480 off w/ new iPhone @ Visible" data-dimension48="Visible: $480 off w/ new iPhone @ Visible" href="https://www.visible.com/shop/smartphones/iphone-18-pro-max?sku=MJW64LL/A" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1000px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="nXRVmdXfPxa8NUZ7ukyY7P" name="visible_logo_new.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/nXRVmdXfPxa8NUZ7ukyY7P-1920-80.jpg" mos="" align="middle" fullscreen="" width="1000" height="1000" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>Visible: </strong><a href="https://www.visible.com/shop/smartphones/iphone-18-pro-max?sku=MJW64LL/A" target="_blank" rel="nofollow" data-dimension112="82ce686e-b2dc-11f1-8178-3d37da490693" data-action="Deal Block" data-label="Visible: $480 off w/ new iPhone @ Visible" data-dimension48="Visible: $480 off w/ new iPhone @ Visible" data-dimension25=""><strong>$480 off w/ new iPhone @ Visible</strong></a><br>Buy any new iPhone with the Visible+ Pro plan and you'll get $480 back via monthly credits over the span of 24 months. Visible+ Pro costs $45/month and includes unlimited premium data on Verizon's 5G Ultra Wideband network, smartwatch data plan service, and up to 4K UHD video streaming. <a class="view-deal button" href="https://www.visible.com/shop/smartphones/iphone-18-pro-max?sku=MJW64LL/A" target="_blank" rel="nofollow" data-dimension112="82ce686e-b2dc-11f1-8178-3d37da490693" data-action="Deal Block" data-label="Visible: $480 off w/ new iPhone @ Visible" data-dimension48="Visible: $480 off w/ new iPhone @ Visible" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce68d2-b2dc-11f1-b6cc-9976746ccc61" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $600 off w/ unlimited @ Total Wireless" data-dimension48="iPhone 18 Pro Max: up to $600 off w/ unlimited @ Total Wireless" href="https://www.totalwireless.com/m/home" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="Z3gikFPLPLmWFv4RSSgxVh" name="total-square.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Z3gikFPLPLmWFv4RSSgxVh-1920-80.jpg" mos="" align="middle" fullscreen="" width="600" height="600" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro Max: </strong><a href="https://www.totalwireless.com/m/home" target="_blank" rel="nofollow" data-dimension112="82ce68d2-b2dc-11f1-b6cc-9976746ccc61" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $600 off w/ unlimited @ Total Wireless" data-dimension48="iPhone 18 Pro Max: up to $600 off w/ unlimited @ Total Wireless" data-dimension25=""><strong>up to $600 off w/ unlimited @ Total Wireless</strong></a><br>Total Wireless is taking up to $600 off the iPhone 18 Pro Max. You'll get a $25/monthly bill credit (over 24 months) when you stay on Total Wireless' All Access plan. <a class="view-deal button" href="https://www.totalwireless.com/m/home" target="_blank" rel="nofollow" data-dimension112="82ce68d2-b2dc-11f1-b6cc-9976746ccc61" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $600 off w/ unlimited @ Total Wireless" data-dimension48="iPhone 18 Pro Max: up to $600 off w/ unlimited @ Total Wireless" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce692c-b2dc-11f1-8b05-f3e8419612da" data-action="Deal Block" data-label="iPhone 18 Pro Max: from $34/month @ Walmart" data-dimension48="iPhone 18 Pro Max: from $34/month @ Walmart" href="https://www.walmart.com/ip/Verizon-iPhone-18-Pro-Max-256GB-Black/20995618639" 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:93.65%;"><img id="Bi2iDjTxUHTUQK9FHZ4W8D" name="Walmart logo.jpeg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Bi2iDjTxUHTUQK9FHZ4W8D-1920-80.jpeg" mos="" align="middle" fullscreen="" width="960" height="899" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro Max: </strong><a href="https://www.walmart.com/ip/Verizon-iPhone-18-Pro-Max-256GB-Black/20995618639" target="_blank" rel="nofollow" data-dimension112="82ce692c-b2dc-11f1-8b05-f3e8419612da" data-action="Deal Block" data-label="iPhone 18 Pro Max: from $34/month @ Walmart" data-dimension48="iPhone 18 Pro Max: from $34/month @ Walmart" data-dimension25=""><strong>from $34/month @ Walmart</strong></a><br>Walmart is offering the iPhone 18 Pro Max for AT&T, Verizon, or T-Mobile from $34/month. The phone is available in all colors and storage capacities, although some models are starting to sell out. <a class="view-deal button" href="https://www.walmart.com/ip/Verizon-iPhone-18-Pro-Max-256GB-Black/20995618639" target="_blank" rel="nofollow" data-dimension112="82ce692c-b2dc-11f1-8b05-f3e8419612da" data-action="Deal Block" data-label="iPhone 18 Pro Max: from $34/month @ Walmart" data-dimension48="iPhone 18 Pro Max: from $34/month @ Walmart" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="1b914768-b389-11f1-af80-2d0958ab4a44" data-action="Deal Block" data-label="iPhone 18 Pro Max" data-dimension48="iPhone 18 Pro Max" data-dimension25="$1099" href="https://www.boostmobile.com/shop/iphone-18-pro-max.html" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:713px;"><p class="vanilla-image-block" style="padding-top:38.85%;"><img id="UGYgmHB5HuHtAFmJHSMZnU" name="Boost Mobile logo 2024.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/UGYgmHB5HuHtAFmJHSMZnU-1920-80.jpg" mos="" align="middle" fullscreen="" width="713" height="277" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>Boost Mobile is offering the iPhone 18 Pro Max for $1,099 when you bring your line and sign up for Boost's Unlimited Premium plan ($60/month). The plan includes unlimited talk, text, and 50GB of premium/high-speed data as well as global talk/text and mobile hotspot. Or you can get it for $1,199 when you open a new Unlimited Premium plan. <a class="view-deal button" href="https://www.boostmobile.com/shop/iphone-18-pro-max.html" target="_blank" rel="nofollow" data-dimension112="1b914768-b389-11f1-af80-2d0958ab4a44" data-action="Deal Block" data-label="iPhone 18 Pro Max" data-dimension48="iPhone 18 Pro Max" data-dimension25="$1099">View Deal</a></p></div><div class="product"><a data-dimension112="82ce6990-b2dc-11f1-9036-e58cd9024ab9" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $480 off @ StraightTalk" data-dimension48="iPhone 18 Pro Max: up to $480 off @ StraightTalk" href="https://www.straighttalk.com/all-phones/apple-iphone-18-pro-max-512gb-prepaid" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:264px;"><p class="vanilla-image-block" style="padding-top:72.35%;"><img id="jg63LBik54HBQtDrbyFRh8" name="StraightTalk logo.png" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/jg63LBik54HBQtDrbyFRh8-1920-80.png" mos="" align="middle" fullscreen="" width="264" height="191" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro Max: </strong><a href="https://www.straighttalk.com/all-phones/apple-iphone-18-pro-max-512gb-prepaid" target="_blank" rel="nofollow" data-dimension112="82ce6990-b2dc-11f1-9036-e58cd9024ab9" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $480 off @ StraightTalk" data-dimension48="iPhone 18 Pro Max: up to $480 off @ StraightTalk" data-dimension25=""><strong>up to $480 off @ StraightTalk</strong></a><br>StraightTalk is taking up to $480 off the iPhone 18 Pro Max. You'll get $20 off your monthly bill over the span of 24 months when you activate a Gold Unlimited plan or higher. <a class="view-deal button" href="https://www.straighttalk.com/all-phones/apple-iphone-18-pro-max-512gb-prepaid" target="_blank" rel="nofollow" data-dimension112="82ce6990-b2dc-11f1-9036-e58cd9024ab9" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $480 off @ StraightTalk" data-dimension48="iPhone 18 Pro Max: up to $480 off @ StraightTalk" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce69f4-b2dc-11f1-97e1-9540a7192b09" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $885 w/ trade-in @ Apple Store" data-dimension48="iPhone 18 Pro Max: up to $885 w/ trade-in @ Apple Store" href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:66.67%;"><img id="4Y3oAjs2dPF6xp4nhVsVcc" name="Applelogo.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/4Y3oAjs2dPF6xp4nhVsVcc-1920-80.jpg" mos="" align="middle" fullscreen="" width="600" height="400" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro Max: </strong><a href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow" data-dimension112="82ce69f4-b2dc-11f1-97e1-9540a7192b09" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $885 w/ trade-in @ Apple Store" data-dimension48="iPhone 18 Pro Max: up to $885 w/ trade-in @ Apple Store" data-dimension25=""><strong>up to $885 w/ trade-in @ Apple Store</strong></a><br>The Apple Store is offering up to a $885 credit when you trade-in your old smartphone for one of the new iPhone 18 Pro Max models. For example, an iPhone 15 will get you up to a $305 credit, whereas an iPhone 13 Pro will get you up to a $255 credit. The iPhone 18 Pro Max features a 6.9-inch OLED 120Hz display (2868 x 1320), A20 Pro chipset, and 256GB of storage. You also get a 48MP main, 48MP ultrawide, and 48MP telephoto lens w/ 4x zoom. The front camera is 18MP. <a class="view-deal button" href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow" data-dimension112="82ce69f4-b2dc-11f1-97e1-9540a7192b09" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $885 w/ trade-in @ Apple Store" data-dimension48="iPhone 18 Pro Max: up to $885 w/ trade-in @ Apple Store" data-dimension25="">View Deal</a></p></div><h3 class="article-body__section" id="section-shop-more-deals"><span>Shop more deals</span></h3><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?brands=Apple&rows=6&view_mode=savings_squad&widget_title=Top+Deals+Handpicked+by+Our+Editors&widget_subtitle=Discover+the+best+discounts+currently+available%2C+curated+daily+by+the+Tom%27s+Guide+Savings+Squad.&bg_color=transparent" data-vizualizer-embed="true"></div>    <script>    /**     * Tom's Guide Deals Finder - Vanilla JS Encapsulated Engine     */    (function() {      // --- Freyr Analytics Adapter ---      function initAnalytics() {        window.dataLayer = window.dataLayer || [];        window.googletag = window.googletag || {};        window.googletag.cmd = window.googletag.cmd || [];        window.hawk = window.hawk || { analytics: { freyr: [] } };        window.hawk.analytics = window.hawk.analytics || { freyr: [] };        window.hawk.analytics.freyr = window.hawk.analytics.freyr || [];        window.freyr = window.freyr || { cmd: [] };        const scriptSrc = 'https://freyr.futurecdn.net/freyr.js';        const hostname = typeof window !== 'undefined' ? window.location.hostname : '';        const isTestEnv = typeof window.navigator !== 'undefined' && (window.navigator.webdriver || window.navigator.userAgent.includes('Headless'));        const shouldSendRealAnalytics = !isTestEnv && hostname && hostname !== 'localhost' && hostname !== '127.0.0.1' && !hostname.includes('run.app');        if (shouldSendRealAnalytics && !document.querySelector(`script[src="${scriptSrc}"]`)) {          const script = document.createElement('script');          script.src = scriptSrc;          script.async = true;          document.head.appendChild(script);        }      }      function storeEventForDebug(name, data) {        if (!window.hawk || !window.hawk.analytics || !window.hawk.analytics.freyr) return;        window.hawk.analytics.freyr.push({ name, data });        try {          if (typeof window !== 'undefined' && window.localStorage) {            window.localStorage.setItem("hawk", JSON.stringify(window.hawk));          }        } catch (e) {          // Ignore storage issues        }        try {          window.dispatchEvent(new CustomEvent("hawk-analytics-update"));        } catch (e) {}      }      function sendToFreyr(eventName, data) {        if (typeof window === 'undefined') return;        window.freyr = window.freyr || { cmd: [] };        window.freyr.cmd.push(() => {          if (window.freyr && window.freyr.pushAndUpdate) {            window.freyr.pushAndUpdate(eventName, data);          }        });      }      function sendEvent(event, skip = false) {        try {          storeEventForDebug(event.name, event.data);          if (!skip) {            sendToFreyr(event.name, event.data);          }        } catch (e) {          // Ensure tracking errors don't surface to the user        }      }      function getCookie(name) {        try {          const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));          return match ? match[2] : null;        } catch (e) {          return null;        }      }      function getTimeAgo(dateString) {        if (!dateString) return '';        const date = new Date(dateString);        const now = new Date();        const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);        if (diffInSeconds < 60) return 'Just now';        const diffInMinutes = Math.floor(diffInSeconds / 60);        if (diffInMinutes < 60) return `${diffInMinutes} min${diffInMinutes > 1 ? 's' : ''} ago`;        const diffInHours = Math.floor(diffInMinutes / 60);        if (diffInHours < 24) return `${diffInHours} hr${diffInHours > 1 ? 's' : ''} ago`;        const diffInDays = Math.floor(diffInHours / 24);        if (diffInDays < 30) return `${diffInDays} day${diffInDays > 1 ? 's' : ''} ago`;        const diffInMonths = Math.floor(diffInDays / 30);        if (diffInMonths < 12) return `${diffInMonths} mo${diffInMonths > 1 ? 's' : ''} ago`;        const diffInYears = Math.floor(diffInDays / 365);        return `${diffInYears} yr${diffInYears > 1 ? 's' : ''} ago`;      }      function normalizeCurrency(symbol) {        const map = {          '£': 'GBP',          '$': 'USD',          'A$': 'AUD',          'CA$': 'CAD',          '€': 'EUR'        };        return map[symbol] || symbol;      }      function trackElementInteraction(props) {        sendEvent({          name: 'elementInteraction',          data: {            element: {              action: props.action || "click",              id: props.id || undefined,              class: props.class || undefined,              name: props.name || undefined,              text: props.text || undefined,              label: props.label || undefined,              container: props.container || undefined,              url: props.url || undefined,              articleId: props.articleId || undefined            }          }        });      }      function generateRevenueId(url, productName, merchantName, modelId) {        const str = `${window.location.href}|${productName}|${merchantName}|${modelId || ''}|${new Date().toDateString()}|tomsguide`;        let hash = 0;        for (let i = 0; i < str.length; i++) {          const char = str.charCodeAt(i);          hash = ((hash << 5) - hash) + char;          hash = hash & hash;        }        let numericStr = Math.abs(hash).toString();        while (numericStr.length < 19) {          numericStr += Math.floor(Math.random() * 10).toString();        }        return numericStr.substring(0, 19);      }      function rewriteAffiliateLink(url, territory, revenueId) {        if (!url) return url;        const t = (territory || 'gb').toLowerCase();        return url.replace(/hawk-custom-tracking/g, `tomsguide-${t}-${revenueId}`);      }      function trackHawkEvent(params) {        const { clickType, widgetId, productCategoryName, product, productsArray, zeroBasedProductIndexOrNull, totalDealsOrProducts, areaClicked, merchant, revenueId, isoCurrencyCode, queryName, widgetTypeName } = params;        const data = {          event: "hawkEvent",          category: "Affiliates",          affiliate: {            action: {              type: clickType,              id: widgetId,              event: clickType === "appeared" ? "viewed" : "Click from",              timestamp: Date.now()            },            component: {              flag: "Editor",              product: productCategoryName || "deals",              category: `Signal Deal Finder ${widgetTypeName || "Carousel"} widget`,              type: clickType === "appeared" ? "review" : "signal product",              label: queryName || (product ? (product.name || "") : ""),              index: zeroBasedProductIndexOrNull === null || zeroBasedProductIndexOrNull === undefined ? -1 : zeroBasedProductIndexOrNull,              linkCount: totalDealsOrProducts || 0,              blockLayout: "",              areaClicked: areaClicked || ""            }          },          products: productsArray || (product && merchant ? [            {              product: {                primary: {                  id: product.id || product.matchId || null,                  name: product.name,                  type: "deal",                  price: product.price,                  previousPrice: product.previousPrice || null,                  currency: isoCurrencyCode || "USD",                  preorder: false,                  labels: [],                  link: product.link,                  originalLink: product.originalLink || null,                  revenueId: revenueId || null,                  startTime: null,                  endTime: null,                  voucherCode: null,                  voucherAudience: null,                  voucherPercentageSaving: null,                  voucherMoneySaving: null,                  voucherType: null,                  offerExclusive: false,                  offerScope: null,                  globalId: product.globalId || null,                  inStock: product.inStock !== false,                  contractProvider: null,                  contractMinutes: null,                  contractTexts: null,                  contractData: null,                  contractLength: null,                  contractMonthlyPrice: null,                  contractCurrency: isoCurrencyCode || "USD"                }              },              merchant: {                id: merchant.id || null,                name: merchant.name,                url: merchant.url || null,                network: merchant.network || null              },              model: {                id: product.modelId || null,                brand: product.brand || null,                name: product.name,                parent: product.parent || null              }            }          ] : []),          reviews: [],          _clear: true,          "gtm.uniqueEventId": Date.now() % 10000        };        sendEvent({ name: 'hawkEvent', data });      }      function trackDealClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Product Card" });      }      function trackViewSimilarClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Product Card View Similar" });      }      function trackPriceComparisonClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Price Comparison" });      }      function trackReviewClick(params) {        trackHawkEvent({ ...params, clickType: "review", areaClicked: "Signal Product Card Review Link" });      }      function trackShare(params) {        trackHawkEvent({ ...params, clickType: "share", areaClicked: "Signal Product Card Share" });      }      function trackDealsAppeared(widgetId, deals, revenueId, currency, queryName, widgetTypeName) {         if (!deals || deals.length === 0) return;                  const productsArray = deals.slice(0, 50).map((deal) => {            let voucherPct = null;            let rawPrice = parseFloat(deal.rawPrice) || parseFloat(deal.price) || null;            let rawMsrp = parseFloat(deal.rawMsrp) || parseFloat(deal.msrp) || null;            if (rawMsrp > rawPrice && rawPrice > 0) {              voucherPct = Math.round((1 - (rawPrice / rawMsrp)) * 100);            }            let numId = null;            if (deal.externalProductId && !isNaN(parseInt(deal.externalProductId))) {              numId = parseInt(deal.externalProductId);            } else if (deal.id && !isNaN(parseInt(deal.id))) {              numId = parseInt(deal.id);            } else {              numId = deal.matchId || null;            }            return {              product: {                primary: {                  id: numId,                  name: deal.productName || deal.title || "",                  type: "deal",                  price: rawPrice,                  previousPrice: rawMsrp,                  currency: currency || 'USD',                  preorder: false,                  labels: deal.modelBrand || deal.brand ? [                     { type: "brand", value: deal.modelBrand || deal.brand }                  ] : [],                  link: deal.url,                  originalLink: deal.url,                  revenueId: revenueId || null,                  startTime: null,                  endTime: null,                  voucherCode: null,                  voucherAudience: null,                  voucherPercentageSaving: voucherPct,                  voucherMoneySaving: null,                  voucherType: null,                  offerExclusive: false,                  offerScope: null,                  globalId: deal.productKey || null,                  inStock: deal.inStock !== false,                  contractProvider: null,                  contractMinutes: null,                  contractTexts: null,                  contractData: null,                  contractLength: null,                  contractMonthlyPrice: null,                  contractCurrency: currency || 'USD'                }              },              merchant: {                id: deal.merchantId ? parseInt(deal.merchantId) : null,                name: deal.merchant || "Retailer",                url: deal.merchantUrl || null,                network: deal.merchantNetwork || null              },              model: {                id: deal.modelId ? parseInt(deal.modelId) : null,                brand: deal.modelBrand || deal.brand || null,                name: deal.productName || deal.title || "",                parent: deal.modelParent || null              }            };         });                  trackHawkEvent({             clickType: "appeared",             widgetId: widgetId,             productCategoryName: "deals",             zeroBasedProductIndexOrNull: null,             totalDealsOrProducts: deals.length,             productsArray: productsArray,             queryName: queryName,             widgetTypeName: widgetTypeName         });      }      // 1. Setup Shadow DOM Sandbox      const currentScript = document.currentScript;      let hostContainer = null;      let template = null;            if (currentScript) {        let prev = currentScript.previousElementSibling;        while (prev) {          if (prev.tagName === 'TEMPLATE' && prev.classList.contains('tg-df-widget-template')) {            template = prev;          } else if (prev.tagName === 'DIV' && prev.classList.contains('tg-df-widget-host') && !prev.hasAttribute('data-initialized')) {            hostContainer = prev;            break;          }          prev = prev.previousElementSibling;        }      }            // Fallbacks in case script is deferred      if (!hostContainer) {        const hosts = document.querySelectorAll('.tg-df-widget-host:not([data-initialized])');        if (hosts.length > 0) hostContainer = hosts[0];      }            // Safely embedded template for CMS environments      const rawTemplate = `  \x3Cstyle>    /* --- Shadow DOM Base Reset --- */    *, *::before, *::after {      box-sizing: border-box;    }    img, picture, svg, video {      max-width: 100%;      height: auto;      display: block;    }    /*       1. Scoped CSS for Tom's Guide Deals Widget       All classes are prefixed with \`tg-df-\` to prevent CMS style leakage.    */    .tg-df-container {      container-type: inline-size;      container-name: tg-df;      --tg-df-blue: #1F69FF;      --tg-df-blue-hover: #004d8c;      --tg-df-text: #222222;      --tg-df-text-muted: #555555;      --tg-df-bg: #ffffff;      --tg-df-bg-secondary: #f4f4f4;      --tg-df-border: #e2e8f0;      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;      color: var(--tg-df-text);      background-color: transparent;       width: 100%;      max-width: 1200px;      margin: 0 auto;      padding-bottom: 24px;    }    .tg-df-container *, .tg-df-container *::before, .tg-df-container *::after {      margin: 0;      padding: 0;      box-sizing: border-box;    }    .tg-df-container img {      border: none;      margin: 0;      padding: 0;    }    .tg-df-container a {      text-decoration: none;      color: inherit;    }    /*       2. Search & Filter Bar    */    .tg-df-controls {      display: flex;      flex-direction: column;      align-items: center;      gap: 20px;      margin-bottom: 32px;      width: 100%;      position: relative;      z-index: 20;    }    .tg-df-top-bar {      display: flex;      width: 100%;      max-width: 760px;      gap: 12px;      margin: 0 auto;      align-items: center;    }    .tg-df-search-wrapper {      position: relative;      flex: 1;      width: 100%;      box-shadow: 0 8px 24px rgba(0,0,0,0.06);      border-radius: 40px;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      z-index: 100;    }    .tg-df-autocomplete-dropdown {      position: absolute;      top: calc(100% + 4px);      left: 0;      right: 0;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 12px;      box-shadow: 0 8px 32px rgba(0,0,0,0.12);      max-height: 300px;      overflow-y: auto;      z-index: 200;      display: none;    }    .tg-df-autocomplete-dropdown.active {      display: block;    }    .tg-df-autocomplete-item {      padding: 12px 24px;      cursor: pointer;      font-size: 14px;      color: var(--tg-df-text);      transition: background 0.1s ease;    }    .tg-df-autocomplete-item:hover {      background: var(--tg-df-bg-secondary);    }    .tg-df-search-input {      width: 100%;      padding: 16px 64px 16px 24px;      font-size: 16px;      border: 2px solid transparent;      border-radius: 40px;      outline: none;      transition: border-color 0.2s ease, box-shadow 0.2s ease;      color: var(--tg-df-text);      background: transparent;    }    .tg-df-search-input:focus {      border-color: transparent;      box-shadow: 0 0 0 3px rgba(0, 108, 196, 0.15);    }    .tg-df-search-input::placeholder {      color: #999999;    }        .tg-df-search-btn {      position: absolute;      right: 8px;      top: 50%;      transform: translateY(-50%);      width: 40px;      height: 40px;      border-radius: 50%;      background: #222;      border: none;      display: flex;      align-items: center;      justify-content: center;      cursor: pointer;      transition: background 0.2s ease;    }        .tg-df-search-btn:hover {      background: #000;    }    .tg-df-search-icon {      width: 16px;      height: 16px;      fill: #fff;    }    .tg-df-settings-wrapper {      position: relative;    }        .tg-df-settings-btn {      width: 48px;      height: 48px;      border-radius: 50%;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      box-shadow: 0 4px 12px rgba(0,0,0,0.04);      display: flex;      align-items: center;      justify-content: center;      cursor: pointer;      transition: all 0.2s ease;      color: var(--tg-df-text-muted);      flex-shrink: 0;    }    .tg-df-settings-btn:hover {      background: var(--tg-df-bg-secondary);      border-color: #0000ff;      color: var(--tg-df-text);    }    .tg-df-settings-btn svg {      width: 24px;      height: 24px;      fill: currentColor;    }    .tg-df-settings-dropdown {      position: absolute;      top: calc(100% + 8px);      right: 0;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 12px;      box-shadow: 0 8px 32px rgba(0,0,0,0.12);      width: 280px;      padding: 20px;      display: none;      z-index: 100;      flex-direction: column;      gap: 20px;    }    .tg-df-settings-dropdown.active {      display: flex;    }        .tg-df-settings-dropdown-backdrop {      display: none;      position: fixed;      inset: 0;      z-index: 99;    }        .tg-df-settings-dropdown-backdrop.active {      display: block;    }    .tg-df-setting-item {      display: flex;      flex-direction: column;      gap: 10px;    }    .tg-df-setting-label {      font-size: 11px;      font-weight: 700;      color: var(--tg-df-text-muted);      text-transform: uppercase;      letter-spacing: 0.5px;    }        .tg-df-region-select {        padding: 10px 12px;        border-radius: 8px;        border: 1px solid var(--tg-df-border);        font-size: 15px;        outline: none;        background: var(--tg-df-bg-secondary);        color: var(--tg-df-text);        cursor: pointer;        width: 100%;    }    .tg-df-toggle {        position: relative;        display: inline-block;        width: 44px;        height: 24px;        flex-shrink: 0;    }    .tg-df-toggle input {        opacity: 0;        width: 0;        height: 0;    }    .tg-df-slider {        position: absolute;        cursor: pointer;        top: 0; left: 0; right: 0; bottom: 0;        background-color: #ccc;        transition: .2s;        border-radius: 24px;    }    .tg-df-slider:before {        position: absolute;        content: "";        height: 18px;        width: 18px;        left: 3px;        bottom: 3px;        background-color: white;        transition: .2s;        border-radius: 50%;    }    .tg-df-toggle input:checked + .tg-df-slider {        background-color: #1F69FF;    }    .tg-df-toggle input:checked + .tg-df-slider:before {        transform: translateX(20px);    }    .tg-df-dl-row {        flex-direction: row;        align-items: center;        justify-content: space-between;    }    .tg-df-dl-row-text {        font-size: 14px;        font-weight: 600;        color: var(--tg-df-text);    }    .tg-df-dl-row-subtext {        font-size: 12px;        font-weight: 400;        line-height: 1.3;        color: var(--tg-df-text-muted);        margin-top: 4px;        display: block;    }    .tg-df-filters-container {      position: relative;      width: 100%;      max-width: 800px;    }    .tg-df-scroll-btn {      display: none;      position: absolute;      top: 50%;      transform: translateY(-50%);      width: 32px;      height: 32px;      background: white;      border: 1px solid var(--tg-df-border);      border-radius: 50%;      align-items: center;      justify-content: center;      cursor: pointer;      z-index: 10;      box-shadow: 0 2px 8px rgba(0,0,0,0.1);      color: var(--tg-df-text-primary);      padding: 0;    }    .tg-df-scroll-btn svg {      width: 16px;      height: 16px;    }    .tg-df-scroll-btn:hover {      background: #f4f4f4;    }    .tg-df-scroll-btn.left {      left: 0px;    }    .tg-df-scroll-btn.right {      right: 0px;    }    @container tg-df (max-width: 768px) {      .tg-df-scroll-btn {        display: flex;        top: 22px; /* vertically center within the 44px high filter buttons */      }    }    .tg-df-filters {      display: grid;      width: 100%;      grid-template-columns: repeat(4, 1fr);      gap: 12px;      margin: 0 auto;      max-width: 800px;    }                 .tg-df-sort-wrapper {      position: relative;      display: flex;      align-items: center;      width: 100%;    }        .tg-df-sort-icon {      position: absolute;      left: 14px;      width: 14px;      height: 14px;      fill: var(--tg-df-text-muted);      pointer-events: none;    }    .tg-df-sort-select, .tg-df-filter-select {      width: 100%;      padding: 10px 36px 10px 38px;      font-size: 14px;      border: 1px solid var(--tg-df-border);      border-radius: 100px;      outline: none;      appearance: none;      background-color: var(--tg-df-bg-secondary);      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12'%3E%3Cpath fill='%23555555' d='M6 8L1 3h10z'/%3E%3C/svg%3E");      background-repeat: no-repeat;      background-position: right 14px center;      color: var(--tg-df-text);      cursor: pointer;      font-weight: 500;      transition: all 0.2s ease;    }        .tg-df-price-input::-webkit-outer-spin-button,    .tg-df-price-input::-webkit-inner-spin-button {      -webkit-appearance: none;      margin: 0;    }    .tg-df-price-input {      -moz-appearance: textfield;    }    .tg-df-sort-select:hover, .tg-df-filter-select:hover {      background-color: #e2e8f0;    }    .tg-df-multiselect-container {      position: relative;    }    @container tg-df (max-width: 768px) {      .tg-df-filters-container {      position: relative;      width: 100%;      max-width: 800px;    }    .tg-df-scroll-btn {      display: none;      position: absolute;      top: 50%;      transform: translateY(-50%);      width: 32px;      height: 32px;      background: white;      border: 1px solid var(--tg-df-border);      border-radius: 50%;      align-items: center;      justify-content: center;      cursor: pointer;      z-index: 10;      box-shadow: 0 2px 8px rgba(0,0,0,0.1);      color: var(--tg-df-text-primary);      padding: 0;    }    .tg-df-scroll-btn svg {      width: 16px;      height: 16px;    }    .tg-df-scroll-btn:hover {      background: #f4f4f4;    }    .tg-df-scroll-btn.left {      left: 0px;    }    .tg-df-scroll-btn.right {      right: 0px;    }    @container tg-df (max-width: 768px) {      .tg-df-scroll-btn {        display: flex;        top: 22px; /* vertically center within the 44px high filter buttons */      }    }    .tg-df-filters {        width: 100%;        margin: 0;        margin-bottom: -320px;        padding: 0 16px 320px 16px;        display: flex;        flex-wrap: nowrap;        gap: 8px;        overflow-x: auto;        overflow-y: hidden;        pointer-events: none;        scrollbar-width: none;        -webkit-overflow-scrolling: touch;      }      .tg-df-filters::-webkit-scrollbar {        display: none;      }      .tg-df-sort-wrapper {        pointer-events: auto;        flex: 0 0 auto;        width: 175px;        min-width: 175px;      }    }        .tg-df-multiselect-trigger {      display: block;      background: #fff;      user-select: none;      width: 100%;      overflow: hidden;      white-space: nowrap;      text-overflow: ellipsis;    }        .tg-df-multiselect-dropdown {      display: none;      position: absolute;      top: calc(100% + 4px);      left: 0;      width: 100%;      min-width: 220px;      max-height: 300px;      overflow-y: auto;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 8px;      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);      z-index: 100;      padding: 8px 0;    }    .tg-df-multiselect-dropdown.active {      display: block;    }    .tg-df-ms-option {      padding: 8px 16px;      display: flex;      align-items: center;      gap: 8px;      cursor: pointer;      font-size: 14px;    }    .tg-df-ms-option:hover {      background-color: var(--tg-df-bg-secondary);    }        .tg-df-ms-option input {      cursor: pointer;      accent-color: #1f69ff;    }    .tg-df-sort-select:focus, .tg-df-filter-select:focus {      border-color: #0000ff;      box-shadow: 0 0 0 3px rgba(0, 0, 255, 0.2);      background-color: var(--tg-df-bg);    }    /*       3. Deal Grid Layout    */    .tg-df-grid.tg-df-grid-auto {      padding-top: 24px;    }    .tg-df-grid, .tg-df-grid.layout-grid {      display: grid;      grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));      gap: 10px;    }    .tg-df-grid.layout-row {      grid-template-columns: 1fr;      gap: 16px;    }        .tg-df-grid.layout-row .tg-df-card {      flex-direction: row;      align-items: stretch;      height: auto;      box-shadow: none;      border-bottom: 1px solid var(--tg-df-border);    }    .tg-df-grid.layout-row .tg-df-card:hover {      box-shadow: none;    }    .tg-df-grid.layout-row .tg-df-card-image-box {      width: 140px;      min-width: 140px;      aspect-ratio: 3/4;      border-right: none;      padding: 16px 16px 16px 32px;    }    .tg-df-grid.layout-row .tg-df-card-body {      padding: 16px;      justify-content: space-between;    }    .tg-df-grid.layout-row .tg-df-card-title {      font-size: 15px;      margin-bottom: 16px;    }    .tg-df-grid.layout-row .tg-df-card-stars { margin-bottom: 8px; }    .tg-df-grid.layout-row .tg-df-card-footer {      flex-direction: column;      align-items: flex-start;      gap: 0;    }    .tg-df-grid.layout-row .tg-df-card-merchant-pill {      margin-bottom: 4px;    }    .tg-df-grid.layout-row .tg-df-card-price-group {      margin-bottom: 8px;    }    .tg-df-grid.layout-row .tg-df-price-group {      width: auto;    }    .tg-df-grid.layout-row .tg-df-card-cta {      width: 100%;      max-width: 200px;      padding: 10px 24px;      font-size: 13px;      flex-shrink: 0;      text-align: center;      justify-content: center;    }    /*       4. Deal Card Design    */    .tg-df-card {      position: relative;      display: flex;      flex-direction: column;      background-color: #ffffff;      border-radius: 0;      overflow: hidden;      transition: transform 0.2s ease, box-shadow 0.2s ease;      text-decoration: none;      color: inherit;      height: 100%;      box-shadow: 0 0 16px rgba(0, 0, 0, 0.08);      border: 1px solid var(--tg-df-border);    }    .tg-df-card:hover {      box-shadow: 0 0 24px rgba(0, 0, 0, 0.12);    }    .tg-df-card-image-box {      width: 100%;      aspect-ratio: 3/4;      background-color: #f8f8f8;      display: flex;      align-items: center;      justify-content: center;      position: relative;      overflow: hidden;      padding: 32px;      flex: 0 0 auto;    }    .tg-df-card-image {      max-width: 100%;      max-height: 100%;      width: auto;      height: auto;      object-fit: contain;      mix-blend-mode: multiply; /* Helps white background images blend into secondary bg */      transition: transform 0.3s ease;    }    .tg-df-card:hover .tg-df-card-image {      transform: scale(1.05); /* Zoom in on hover */    }    .tg-df-card-discount-badge {      position: absolute;      top: 12px;      left: 12px;      background: #dc2626; /* Red */      color: #ffffff;      padding: 6px 8px;      font-size: 11px;      font-weight: 500;      text-transform: uppercase;      letter-spacing: 0.5px;      border-radius: 0;      z-index: 10;    }        .tg-df-card-merchant-pill {      display: block;      padding: 0;      font-size: 11px;      font-weight: 600;      text-transform: uppercase;      letter-spacing: 0.5px;      border-radius: 0;      color: var(--tg-df-text-muted);      margin-bottom: 8px;      white-space: nowrap;      overflow: hidden;      text-overflow: ellipsis;    }    .tg-df-card-body {      padding: 16px;      display: flex;      flex-direction: column;      flex-grow: 1;      min-width: 0;    }    .tg-df-card-badges {      display: flex;      flex-wrap: wrap;      gap: 6px;      margin-bottom: 8px;    }    .tg-df-tag {      display: inline-flex;      align-items: center;      padding: 4px 6px;      font-size: 11px;      font-weight: 700;      text-transform: uppercase;      border-radius: 4px;      gap: 4px;    }    .tg-df-tag-prime {      background-color: #00A8E1;      color: #fff;    }    .tg-df-tag-coupons {      background-color: #f1f5f9;      color: #334155;      border: 1px solid #cbd5e1;      cursor: pointer;      transition: background-color 0.2s;    }    .tg-df-tag-coupons:hover {      background-color: #e2e8f0;    }        .tg-df-tag-outline {      background-color: #f1f5f9;      color: #334155;      border: 1px solid #cbd5e1;      cursor: pointer;      transition: background-color 0.2s;    }    .tg-df-tag-outline:hover {      background-color: #e2e8f0;    }        @keyframes tg-df-spin {      0% { transform: rotate(0deg); }      100% { transform: rotate(360deg); }    }    .tg-df-coupon-spinner {      border: 2px solid #e2e8f0;      border-top: 2px solid #3b82f6;      border-radius: 50%;      width: 14px;      height: 14px;      animation: tg-df-spin 1s linear infinite;      margin: 4px 8px;      display: inline-block;    }        /* Vouchers Modal */    .tg-df-modal-backdrop {      position: fixed;      top: 0; left: 0; right: 0; bottom: 0;      background: rgba(0,0,0,0.5);      z-index: 10000;      display: flex;      align-items: center;      justify-content: center;      opacity: 0;      pointer-events: none;      transition: opacity 0.3s;    }    .tg-df-modal-backdrop.active {      opacity: 1;      pointer-events: auto;    }    .tg-df-modal {      background: #fff;      border-radius: 12px;      width: 90%;      max-width: 400px;      max-height: 80vh;      display: flex;      flex-direction: column;      box-shadow: 0 10px 40px rgba(0,0,0,0.2);      transform: translateY(20px);      transition: transform 0.3s;    }    .tg-df-modal-backdrop.active .tg-df-modal {      transform: translateY(0);    }    .tg-df-modal-header {      padding: 16px;      border-bottom: 1px solid #e2e8f0;      display: flex;      align-items: center;      justify-content: space-between;    }    .tg-df-modal-title {      font-size: 16px;      font-weight: 600;      margin: 0;    }    .tg-df-modal-close {      background: none;      border: none;      cursor: pointer;      padding: 4px;      color: #64748b;    }    .tg-df-modal-body {      padding: 16px;      overflow-y: auto;    }    .tg-df-voucher-item {      padding: 12px;      border: 1px dashed #cbd5e1;      border-radius: 8px;      margin-bottom: 10px;      background: #f8fafc;      display: flex;      align-items: center;      gap: 12px;      text-decoration: none;      color: inherit;      transition: background-color 0.2s, border-color 0.2s;    }    .tg-df-voucher-item:hover {      background: #f1f5f9;      border-color: #94a3b8;    }    .tg-df-voucher-item:last-child {      margin-bottom: 0;    }    .tg-df-voucher-logo {      width: 48px;      height: 48px;      object-fit: contain;      border-radius: 4px;      background: #fff;      border: 1px solid #e2e8f0;      flex-shrink: 0;    }    .tg-df-voucher-content {      flex: 1;      min-width: 0;    }    .tg-df-voucher-title {      font-size: 14px;      font-weight: 600;      margin: 0 0 4px 0;      line-height: 1.3;      color: #0f172a;    }    .tg-df-voucher-expiry {      font-size: 12px;      color: #64748b;      display: flex;      align-items: center;      gap: 4px;      margin-top: 6px;    }    .tg-df-voucher-code {      display: inline-flex;      align-items: center;      background: #f1f5f9;      border: 1px dashed #cbd5e1;      padding: 6px 10px;      font-family: monospace;      font-weight: 700;      font-size: 14px;      color: #0f172a;      border-radius: 4px;      margin-top: 8px;      cursor: pointer;      transition: all 0.2s ease;    }    .tg-df-voucher-code:hover {      background: #e2e8f0;      border-color: #94a3b8;    }    .tg-df-voucher-code.copied {      background: #ecfdf5;      border-color: #10b981;      color: #10b981;    }    .tg-df-voucher-cta {      display: inline-block;      margin-top: 8px;      font-size: 13px;      font-weight: 600;      color: #2563eb;      text-decoration: none;    }    .tg-df-card-title {      font-size: 15px;      font-weight: 400;      line-height: 1.4;      margin: 0 0 12px 0;      color: var(--tg-df-text);    }    .tg-df-card-footer {      margin-top: auto;      display: flex;      flex-direction: column;      width: 100%;    }    .tg-df-card-price-group {      display: flex;      flex-direction: row;      align-items: center;      gap: 8px;      margin-bottom: 12px;    }    .tg-df-card-price {      font-size: 16px;      font-weight: 700;      color: #dc2626; /* Red price */      line-height: 1;    }        .tg-df-card-msrp {      font-size: 13px;      color: var(--tg-df-text-muted);      text-decoration: line-through;    }    .tg-df-container .tg-df-card-cta {      display: flex;      align-items: center;      justify-content: center;      width: 100%;      box-sizing: border-box;      background-color: #1f69ff;      color: #ffffff;      font-size: 12px;      font-weight: 700;      text-transform: uppercase;      letter-spacing: 0.5px;      padding: 12px 16px;      border-radius: 0;      border: none;      cursor: pointer;      transition: background-color 0.2s ease;    }    .tg-df-card:hover .tg-df-card-cta,    .tg-df-card-cta:hover {      background-color: #1555cc;    }    /*       5. State & Skeleton Styles    */    .tg-df-message {      grid-column: 1 / -1;      text-align: center;      padding: 48px 24px;      color: var(--tg-df-text-muted);      font-size: 16px;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 8px;    }    @keyframes tg-df-shimmer {      0% { background-position: -200% 0; }      100% { background-position: 200% 0; }    }    .tg-df-skeleton {      background: linear-gradient(90deg, var(--tg-df-bg-secondary) 25%, #e2e8f0 50%, var(--tg-df-bg-secondary) 75%);      background-size: 200% 100%;      animation: tg-df-shimmer 1.5s infinite;      border-radius: 4px;    }    .tg-df-skeleton-img {      width: 100%;      height: 100%;      position: absolute;      top: 0; left: 0;    }        .tg-df-skeleton-text {      height: 16px;      margin-bottom: 8px;      width: 100%;    }    .tg-df-skeleton-text.short { width: 40%; }    .tg-df-skeleton-text.title { height: 20px; margin-bottom: 16px; }    /* Editor Floating Bar & Elements */    .tg-df-editor-bar {      position: sticky;      top: 120px;      z-index: 1000;      background: #111827;      color: #fff;      padding: 12px 16px;      border-radius: 8px;      margin-bottom: 16px;      display: flex;      align-items: center;      justify-content: space-between;      box-shadow: 0 4px 12px rgba(0,0,0,0.15);    }    .tg-df-editor-bar-text {      font-weight: 600;      font-size: 14px;    }    .tg-df-editor-copy-btn {      background: #10b981;      color: #fff;      padding: 6px 16px;      border: none;      border-radius: 4px;      font-weight: 600;      cursor: pointer;      display: flex;      align-items: center;      font-size: 13px;    }    .tg-df-editor-copy-btn:hover { background: #059669; }        .tg-df-deal-checkbox {      position: absolute;      top: 12px;      right: 12px;      z-index: 10;      width: 20px;      height: 20px;      cursor: pointer;      pointer-events: auto;    }    /*       6. Mobile List View (Stacks into a cleaner horizontal row/list)    */    @container tg-df (max-width: 599px) {      .tg-df-controls {        padding: 16px 16px 8px;      }            .tg-df-top-bar {        width: 100%;      }            .tg-df-settings-dropdown {        position: fixed;        top: auto;        bottom: 0;        left: 0;        right: 0;        width: 100%;        border-radius: 20px 20px 0 0;        padding: 24px;        box-shadow: 0 -8px 32px rgba(0,0,0,0.15);        z-index: 1000;        border: none;        border-top: 1px solid var(--tg-df-border);      }            .tg-df-settings-dropdown-backdrop.active {        background: rgba(0,0,0,0.4);      }            .tg-df-search-wrapper {        box-shadow: 0 0 16px rgba(0,0,0,0.08);      }                  .tg-df-sort-wrapper.tg-df-price-range-wrapper {        flex: 0 0 auto;        min-width: max-content;        width: auto;      }            .tg-df-sort-select, .tg-df-filter-select {        width: 100%;        text-align: left;        padding: 10px 24px 10px 32px;        background-position: right 8px center;        text-overflow: ellipsis;        white-space: nowrap;        overflow: hidden;      }      .tg-df-sort-icon {        left: 10px;      }      .tg-df-grid:not(.layout-grid):not(.layout-row),      .tg-df-grid.layout-row {        grid-template-columns: 1fr;        gap: 16px;      }            .tg-df-grid.tg-df-grid-auto {        padding-top: 24px;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card,      .tg-df-grid.layout-row .tg-df-card {        flex-direction: row;        align-items: stretch;        height: auto;        box-shadow: none; /* simple line on mobile if preferred, or keep */        border-bottom: 1px solid var(--tg-df-border);      }      .tg-df-grid.tg-df-grid-auto .tg-df-card:hover,      .tg-df-grid.layout-row .tg-df-card:hover {        box-shadow: none;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-image-box,      .tg-df-grid.layout-row .tg-df-card-image-box {        width: 120px;        min-width: 120px;        aspect-ratio: 3/4;        border-right: none;        padding: 12px;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-body,      .tg-df-grid.layout-row .tg-df-card-body {        padding: 12px;        justify-content: space-between;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-title,      .tg-df-grid.layout-row .tg-df-card-title {        font-size: 14px;        margin-bottom: 12px;      }      /* Single column mobile grid override */      .tg-df-grid.layout-grid {        grid-template-columns: 1fr;        gap: 16px;      }      .tg-df-grid.layout-grid .tg-df-card-image-box {        padding: 12px;      }      .tg-df-grid.layout-grid .tg-df-card-body {        padding: 10px;      }      .tg-df-grid.layout-grid .tg-df-card-title {        font-size: 13px;        margin-bottom: 8px;      }      .tg-df-grid.layout-grid .tg-df-card-price {        font-size: 14px;      }            .tg-df-card-footer {        flex-direction: column;        align-items: stretch;        gap: 0;        width: 100%;        min-width: 0;      }      .tg-df-card-merchant-pill {        margin-bottom: 4px;      }      .tg-df-card-price-group {        flex: 1 1 auto;        margin-bottom: 8px;      }      .tg-df-card-price {        font-size: 16px;      }      .tg-df-card-msrp {        display: block;       }      .tg-df-grid.layout-row .tg-df-card-cta,      .tg-df-container .tg-df-card-cta {        width: 100%;        max-width: none;        min-width: 0;        box-sizing: border-box;        padding: 8px 16px;        font-size: 12px;        flex: 0 0 auto;        text-align: center;        white-space: normal;        line-height: 1.2;      }    }    .tg-df-container.is-carousel {      min-height: 760px;      background-color: #E7F0FF;      padding: 0 0 24px 0;      border-radius: 24px;      width: 100vw;      max-width: 1200px;      position: relative;      left: 50%;      transform: translateX(-50%);    }    .tg-df-container.is-carousel.hide-header-details {      min-height: 480px;    }    /*       7. Carousel View Mode    */    .tg-df-container .tg-df-carousel-host {      /* Layout is now handled by container wrapper */    }    .tg-df-container .tg-df-carousel-eyebrow {      color: #1F69FF;      font-weight: 700;      font-size: 14px;      text-transform: uppercase;      letter-spacing: 1px;      padding: 24px 16px 0 16px;      display: none;    }    .tg-df-container .tg-df-carousel-query-title {      color: #011535;      font-size: 28px;      font-weight: 600;      padding: 0 16px 24px 16px;      line-height: 1.2;      display: none;    }    .tg-df-container .tg-df-carousel-blue-box {      background-color: transparent;      border-radius: 0;      padding: 24px 24px 0 24px;      margin: 0;      color: #1F69FF;          position: relative;      overflow: hidden;    }    .tg-df-container .tg-df-carousel-bg-circle-1 {      display: none;    }    .tg-df-container .tg-df-carousel-bg-circle-2 {      display: none;    }    .tg-df-container .tg-df-carousel-bg-circle-3 {      display: none;    }    .tg-df-container .tg-df-carousel-box-content {      position: relative;      z-index: 10;    }    .tg-df-container .tg-df-carousel-box-eyebrow {      background-color: transparent;      color: #1F69FF;      font-weight: 700;      font-size: 14px;      text-transform: uppercase;      letter-spacing: 1px;      display: inline-block;      padding: 0;      border-radius: 0;    }    .tg-df-container .tg-df-carousel-box-title {      font-size: 28px;      font-weight: 600;      line-height: 1.2;      margin-top: 8px;      color: #1e293b;    }    .tg-df-container .tg-df-countdown-wrapper {      position: absolute;      top: 0;      right: 0;      display: flex;      flex-direction: column;      align-items: flex-end;      gap: 12px;      transform: scale(0.67);      transform-origin: top right;    }    .tg-df-container .tg-df-countdown-title {      font-size: 14px;      font-weight: 600;      color: #011535;      margin: 0;    }    .tg-df-container .tg-df-countdown-blocks {      display: flex;      gap: 16px;    }    .tg-df-container .tg-df-countdown-item {      display: flex;      flex-direction: column;      align-items: center;      gap: 4px;    }    .tg-df-container .tg-df-countdown-box {      width: 59px;      height: 59px;      background: #03FE9E;      border-radius: 15px;      display: flex;      align-items: center;      justify-content: center;    }    .tg-df-container .tg-df-countdown-num {      font-family: 'Inter', sans-serif;      font-weight: 700;      font-size: 20px;      line-height: normal;      color: #011535;    }    .tg-df-container .tg-df-countdown-label {      font-family: 'Inter', sans-serif;      font-weight: 500;      font-size: 16px;      line-height: normal;      color: #1e293b;      text-transform: uppercase;    }    .tg-df-container .tg-df-carousel-box-subtitle {      font-size: 16px;      margin-top: 8px;      font-weight: 300;      color: #1e293b;      line-height: 24px;    }    .tg-df-container .tg-df-carousel-roundels-wrapper {      position: relative;      margin-top: 24px;      margin-left: -24px;      margin-right: -24px;    }    .tg-df-container .tg-df-carousel-roundels {      display: flex;      gap: 16px;      overflow-x: auto;            scrollbar-width: none;      padding-top: 12px;      padding-bottom: 24px;      padding-left: 24px;      padding-right: 24px;      margin-left: 0;      margin-right: 0;    }        .tg-df-container .tg-df-carousel-scroll-left,    .tg-df-container .tg-df-carousel-scroll-right {      position: absolute;      top: 50%;      transform: translateY(-50%);      height: 36px;      width: 36px;      display: flex;      align-items: center;      justify-content: center;      border-radius: 50%;      background-color: #ffffff;      border: 1px solid #e2e8f0;      box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);      color: #1F69FF;      cursor: pointer;      transition: all 0.2s;      margin-top: -4px;      z-index: 20;    }    .tg-df-container .tg-df-carousel-scroll-left { left: 8px; }    .tg-df-container .tg-df-carousel-scroll-right { right: 8px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-left { left: 0px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-right { right: 0px; }    .tg-df-carousel-filters-outer { margin-left: -24px; margin-right: -24px; padding-left: 24px; padding-right: 24px; }    .tg-df-grid-wrapper { position: relative; }    @container tg-df (max-width: 599px) { .tg-df-carousel-filters-outer { margin-left: -16px; margin-right: -16px; padding-left: 16px; padding-right: 16px; } }        .tg-df-container .tg-df-carousel-scroll-left:hover,    .tg-df-container .tg-df-carousel-scroll-right:hover {      background-color: rgba(255, 255, 255, 0.6);    }    .tg-df-container .tg-df-carousel-roundels::-webkit-scrollbar {      display: none;    }    .tg-df-container .tg-df-roundel {      display: flex;      flex-direction: column;      align-items: center;      gap: 8px;      cursor: pointer;      min-width: 120px;      flex-shrink: 0;    }    .tg-df-container .tg-df-roundel-img-box {      width: 120px;      height: 120px;      border-radius: 50%;      background: white;      display: flex;      align-items: center;      justify-content: center;      overflow: hidden;      box-shadow: 0px 3px 14px 0px rgba(30, 41, 59, 0.08);      transition: box-shadow 0.2s;    }    .tg-df-container .tg-df-roundel:hover .tg-df-roundel-img-box {      box-shadow: 0 0 0 2px #E7F0FF, 0 0 0 4px #1F69FF;    }    .tg-df-container .tg-df-roundel.active .tg-df-roundel-img-box {      box-shadow: 0 0 0 2px #E7F0FF, 0 0 0 4px #1F69FF;    }    .tg-df-container .tg-df-roundel:hover .tg-df-roundel-img-box img {      transform: scale(1.08);    }    .tg-df-container .tg-df-roundel-img-box img {      width: 100%;      height: 100%;      object-fit: contain;      padding: 10px;      box-sizing: border-box;      transition: transform 0.3s ease;    }    .tg-df-container .tg-df-roundel-label {      font-size: 13px;      font-weight: 400;      color: #1e293b;      text-align: center;    }    .tg-df-container .tg-df-carousel-filters-label {      font-size: 16px;      font-weight: 400;      color: #1e293b;      white-space: nowrap;      margin-right: 4px;    }    .tg-df-container .tg-df-carousel-filters-wrap {      display: flex;      align-items: center;      flex-wrap: nowrap;      gap: 8px;      margin-top: 8px;      overflow-x: auto;      scrollbar-width: none;      -webkit-overflow-scrolling: touch;      padding-bottom: 8px;      margin-left: -24px;      margin-right: -24px;      padding-left: 24px;      padding-right: 24px;    }    .tg-df-container .tg-df-carousel-filters-wrap::-webkit-scrollbar {      display: none;    }        .tg-df-container .tg-df-carousel-filter-btn img,    .tg-df-container .tg-df-carousel-filter-btn picture {      height: 20px;      width: 20px;      object-fit: contain;      object-position: center;      display: inline-flex;      align-items: center;      justify-content: center;      margin-right: 6px;    }    .tg-df-container .tg-df-carousel-filter-btn picture img {      margin-right: 0;      height: 100%;      width: 100%;    }    .tg-df-container .tg-df-carousel-filter-btn img.active-img,    .tg-df-container .tg-df-carousel-filter-btn picture:has(.active-img) {      display: none;    }    .tg-df-container .tg-df-carousel-filter-btn:hover img.inactive-img,    .tg-df-container .tg-df-carousel-filter-btn.active img.inactive-img,    .tg-df-container .tg-df-carousel-filter-btn:hover picture:has(.inactive-img),    .tg-df-container .tg-df-carousel-filter-btn.active picture:has(.inactive-img) {      display: none;    }    .tg-df-container .tg-df-carousel-filter-btn:hover img.active-img,    .tg-df-container .tg-df-carousel-filter-btn.active img.active-img,    .tg-df-container .tg-df-carousel-filter-btn:hover picture:has(.active-img),    .tg-df-container .tg-df-carousel-filter-btn.active picture:has(.active-img) {      display: inline-flex;    }    .tg-df-container .tg-df-carousel-filter-btn {      background: #ffffff;      border: 2px solid #1e293b;      color: #1e293b;      border-radius: 24px;      padding: 6px 16px;      font-size: 14px;      font-weight: 600;      cursor: pointer;      transition: all 0.2s;      flex-shrink: 0;      white-space: nowrap;    }    .tg-df-container .tg-df-carousel-filter-btn svg {      margin-right: 6px;    }    .tg-df-container .tg-df-carousel-filter-btn {      display: inline-flex;      align-items: center;    }    .tg-df-container .tg-df-carousel-filter-btn:hover {      background: #1e293b;      color: white;      border-color: #1e293b;    }    .tg-df-container .tg-df-carousel-filter-btn.active {      background: #1e293b;      color: white;      border-color: #1e293b;    }        .tg-df-grid.carousel-compact {      display: flex;      flex-wrap: nowrap;      overflow-x: auto;      gap: 16px;      padding: 16px 24px;      align-items: stretch;      scrollbar-width: none;    }    .tg-df-grid.carousel-compact::-webkit-scrollbar {      display: none;    }    .tg-df-grid.carousel-compact .tg-df-card {      flex: 0 0 auto;      width: 200px;      min-height: auto;      height: auto;      display: flex;      flex-direction: column;      border-radius: 15px;      border: none;      box-shadow: 0 0 16px rgba(0,0,0,0.08);      overflow: visible;    }    .tg-df-grid.carousel-compact .tg-df-card-image-box {      padding: 12px;      background-color: transparent;      border-radius: 15px 15px 0 0;      height: 130px;    }    .tg-df-grid.carousel-compact .tg-df-card-image {      mix-blend-mode: normal;    }    .tg-df-grid.carousel-compact .tg-df-card-discount-badge {      border-radius: 0;      top: 0px;      left: 0px;      padding: 4px 8px;      font-size: 11px;    }    .tg-df-grid.carousel-compact .tg-df-card-body {      padding: 8px 12px 12px 12px;    }    .tg-df-grid.carousel-compact .tg-df-card-title {      font-size: 14px;      font-weight: 400;      margin-bottom: 8px;      color: #011535;    }    .tg-df-grid.carousel-compact .tg-df-card-body:not(:has(.tg-df-card-stars)):not(:has(.tg-df-tag-prime)):not(:has(.tg-df-coupon-wrapper:not([style*="none"]))) > .tg-df-card-title,    .tg-df-grid.carousel-compact .tg-df-card-body:not(:has(.tg-df-card-stars)):has(> .tg-df-card-title:first-child) > .tg-df-card-title {    }    .tg-df-grid.carousel-compact .tg-df-card-cta {      border-radius: 5px;      padding: 8px 10px;      margin-top: 4px;      background-color: #1F69FF;    }    .tg-df-grid.carousel-compact .tg-df-card-price-group {      margin-bottom: 2px;    }    .tg-df-grid.carousel-compact .tg-df-card-merchant-pill {      margin-bottom: 2px;    }    @container tg-df (max-width: 599px) {      .tg-df-container .tg-df-carousel-blue-box-title {        font-size: 24px;      }      .tg-df-container .tg-df-countdown-title {        display: none;      }      .tg-df-container .tg-df-countdown-wrapper {        position: absolute;        top: 0;        right: 0;        align-items: flex-end;        transform: scale(0.40);        transform-origin: top right;      }      .tg-df-container .tg-df-roundel {        min-width: 88px;      }      .tg-df-container .tg-df-roundel-img-box {        width: 88px;        height: 88px;      }    }    /* REPLICA BLOCK STYLES */    .tg-df-grid.layout-replica-2 { grid-template-columns: repeat(2, 1fr) !important; gap: 20px; }    .tg-df-grid.layout-replica-1 { grid-template-columns: 1fr !important; gap: 20px; }        .tg-df-container .hawk-deal-widget-container { border-bottom: 1px solid #e5e7eb; display: flex; flex-direction: column; margin: 0; padding: 20px 0; box-sizing: border-box; font-family: inherit; }    .tg-df-container .hawk-deal-widget-wrap { display: flex; flex-direction: row; align-items: flex-start; width: 100%; gap: 24px; }    .tg-df-container .hawk-deal-widget-image-container { display: flex; flex-shrink: 0; justify-content: center; width: 160px; height: 160px; align-items: center; background: white; margin-bottom: 0px; }    .tg-df-container .hawk-deal-widget-title-product-title { color: #111827; font-size: 18px; font-weight: 700; line-height: 1.4; display: inline; }    .tg-df-container .hawk-deal-widget-title-price { font-size: 18px; font-weight: 700; line-height: 1.4; white-space: nowrap; color: #2563eb; }    .tg-df-container .hawk-deal-widget-title-price-now { font-weight: 700; }    .tg-df-container .hawk-deal-widget-title-retailer-price:hover { text-decoration: underline; }    .tg-df-container .hawk-deal-widget-title-retailer { font-size: 18px; font-weight: 700; line-height: 1.4; color: #2563eb; }    .tg-df-container .hawk-deal-widget-title-was-price { color: #dc2626; font-size: 16px; font-weight: 500; line-height: 1.4; text-decoration: line-through; white-space: nowrap; margin-left: 8px; margin-right: 8px; }    .tg-df-container .hawk-deal-widget-text-body-container { position: relative; width: 100%; box-sizing: border-box; }    .tg-df-container .hawk-deal-widget-text-body-main { font-size: 16px; width: 100%; margin-bottom: 12px; }    .tg-df-container .hawk-deal-widget-text-body-description { display: block; font-size: 15px; margin-top: 12px; color: #4b5563; line-height: 1.6; }    .tg-df-container .hawk-deal-widget-text-body-description p { margin: 0; line-height: 1.6; }    .tg-df-container .hawk-deal-widget-text-cta-container { display: flex; flex-direction: column; gap: 12px; width: 100%; flex: 1; min-width: 0; box-sizing: border-box; }    .tg-df-container .hawk-deal-widget-footer { display: flex; justify-content: flex-end; width: 100%; margin-top: auto; }    .tg-df-container .hawk-deal-widget-button-wrapper { display: flex; flex-direction: column; align-items: flex-end; justify-content: flex-end; width: 100%; }    .tg-df-container .hawk-deal-widget-preferred-partner-wrapper { display: flex; flex-direction: row; }        @container tg-df (min-width: 600px) {      .tg-df-mobile-only { display: none !important; }    }    @container tg-df (max-width: 599px) {      .tg-df-desktop-only { display: none !important; }      .tg-df-grid.layout-replica-2 { grid-template-columns: 1fr !important; }      .tg-df-grid.savings-squad-cards { grid-template-columns: 1fr !important; display: flex; flex-direction: column; }    }    .tg-df-grid.savings-squad-cards .tg-df-card-title {      -webkit-line-clamp: unset !important;      display: block !important;      overflow: visible !important;    }    @container tg-df (max-width: 500px) {      .tg-df-container .hawk-deal-widget-wrap { display: block; }      .tg-df-container .hawk-deal-widget-image-container { display: block; float: left; margin: 0 16px 8px 0; width: 120px; max-width: 120px; height: auto; align-items: normal; justify-content: normal; }      .tg-df-container .hawk-deal-widget-text-cta-container { display: block; text-align: left; }      .tg-df-container .hawk-deal-widget-footer { display: block; margin-top: 16px; clear: both; width: 100%; }      .tg-df-container .hawk-deal-widget-button-wrapper { display: block; width: 100%; }      .tg-df-container .hawk-deal-widget-button-wrapper .hawk-deal-widget-preferred-partner-wrapper { display: block; width: 100%; }      .tg-df-container .hawk-affiliate-link-deal-button { box-sizing: border-box !important; display: flex !important; max-width: none !important; width: 100% !important; margin: 0 !important; }    }        .tg-df-container .hawk-affiliate-link-deal-button {       align-items: center; background-color: #1f69ff; box-sizing: border-box; color: #ffffff !important; display: flex; font-size: 14px; font-weight: 700; justify-content: center; letter-spacing: 0.5px; line-height: 1; min-width: 160px; padding: 14px 24px; text-align: center; text-decoration: none; text-transform: uppercase; width: 100%; word-break: normal; border-radius: 4px; border: 0; transition: background-color 0.2s;     }    .tg-df-container .hawk-affiliate-link-deal-button:hover { background-color: #0056e0; text-decoration: none; }    .tg-df-container .hawk-lazy-image-deal-widget { display: block; height: auto; margin: auto; max-height: 160px; max-width: 100%; mix-blend-mode: multiply; object-fit: contain; }    .tg-df-container .hawk-deal-widget-text-cta-container a { color: #2563eb; text-decoration: none; display: inline; }    .tg-df-container .hawk-deal-widget-text-cta-container a:hover { text-decoration: underline; }    .tg-df-container .hawk-deal-widget-text-cta-container a:has(.hawk-deal-widget-title-product-title) { color: #111827; }    .tg-df-container .hawk-deal-widget-text-cta-container a:hover .hawk-deal-widget-title-product-title,    .tg-df-container .hawk-deal-widget-text-cta-container a:hover .hawk-deal-widget-title-retailer-price { text-decoration: underline; }    .tg-df-savings-squad-header { margin-bottom: 24px; text-align: center; display: none; }    .tg-df-banner-img-desktop { display: block; width: 100%; height: auto; margin-bottom: 32px; }    .tg-df-banner-img-mobile { display: none; width: 100%; height: auto; margin-bottom: 32px; }    @container tg-df (max-width: 600px) {      .tg-df-banner-img-desktop { display: none; }      .tg-df-banner-img-mobile { display: block; }    }    .tg-df-header-title { font-size: 28px; font-weight: 700; color: var(--tg-df-text); margin: 32px 0 12px 0; line-height: 1.3; }    .tg-df-header-subtitle { font-size: 16px; color: var(--tg-df-text-muted); margin: 0 0 32px 0; line-height: 1.5; }  \x3C/style>  \x3C!-- Widget Container --\x3E  \x3Cdiv class="tg-df-container" id="signal-deals-finder-root">    \x3Cdiv class="tg-df-savings-squad-header" id="tg-df-savings-squad-header">      \x3Cpicture>        \x3Cimg src="https://cdn.mos.cms.futurecdn.net/flexiimages/xkh2og7m3d1778189998.png" alt="Deals Banner" class="tg-df-banner-img-desktop" />        \x3Cimg src="https://cdn.mos.cms.futurecdn.net/flexiimages/gmak6rtdf41778245089.png" alt="Deals Banner Mobile" class="tg-df-banner-img-mobile" />      \x3C/picture>      \x3Cdiv class="tg-df-header-text">        \x3Ch2 class="tg-df-header-title" id="tg-df-header-title">Editor's Choice Deals\x3C/h2>        \x3Cp class="tg-df-header-subtitle" id="tg-df-header-subtitle">Discover the best discounts currently available, curated daily by the Tom's Guide Savings Squad.\x3C/p>      \x3C/div>    \x3C/div>    \x3C!-- Editor Floating Bar --\x3E    \x3Cdiv class="tg-df-editor-bar" id="tg-df-editor-bar" style="display:none;">      \x3Cdiv class="tg-df-editor-bar-text" style="display: flex; align-items: center;">        \x3Cspan id="tg-df-selected-count">0\x3C/span>\x26nbsp;Deals Selected        \x3Cbutton class="tg-df-editor-clear-btn" id="tg-df-editor-clear" type="button" style="margin-left: 12px; font-size: 13px; color: #9ca3af; background: none; border: none; cursor: pointer; text-decoration: underline;">Clear All\x3C/button>      \x3C/div>      \x3Cbutton class="tg-df-editor-copy-btn" id="tg-df-editor-copy" type="button">        \x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2">\x3C/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">\x3C/path>\x3C/svg>        Copy to CMS      \x3C/button>    \x3C/div>    \x3Cdiv class="tg-df-carousel-host" id="tg-df-carousel-host" style="display: none;">      \x3Cdiv class="tg-df-carousel-eyebrow">DEAL FINDER\x3C/div>      \x3Cdiv class="tg-df-carousel-query-title" id="tg-df-carousel-title-label">Best Deals\x3C/div>            \x3Cdiv class="tg-df-carousel-blue-box">        \x3Cdiv class="tg-df-carousel-bg-circle-1" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-bg-circle-2" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-bg-circle-3" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-box-content">          \x3Cdiv class="tg-df-countdown-wrapper" id="tg-df-countdown-wrapper" style="display:none;">            \x3Cdiv class="tg-df-countdown-title" id="tg-df-countdown-title">Prime Day starts in\x3C/div>            \x3Cdiv class="tg-df-countdown-blocks">              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-days">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">DAYS\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-hrs">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">HRS\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-min">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">MIN\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-sec">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">SEC\x3C/div>\x3C/div>            \x3C/div>          \x3C/div>          \x3Cdiv class="tg-df-carousel-box-eyebrow">DEAL FINDER\x3C/div>          \x3Cdiv class="tg-df-carousel-box-title">Find Deals Fast\x3C/div>          \x3Cdiv class="tg-df-carousel-box-subtitle">The latest deals from the biggest retailers, all in one place\x3C/div>                    \x3Cdiv class="tg-df-carousel-roundels-wrapper">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-roundels').scrollBy({left: -200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \x3Cdiv class="tg-df-carousel-roundels">                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Televisions" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/wcMxTsHgqu3roMbAx7RLnT-132-100.png" alt="TVs" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">TVs\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Phones" data-pr="over50">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/G3KGaRGzj24F6PUsw4bWpT-132-100.png" alt="Phones" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Phones\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Computing" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/znNvsLzx8NEgNkD9HSFSnT-132-100.png" alt="Computing" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Computing\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Gaming" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/Pgew8yaRQeZFHqHjTzvBnT-132-100.png" alt="Gaming" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Gaming\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Mattresses" data-pr="over500">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/cW7xsaLyesxkHFVSiC4kmT-132-100.png" alt="Mattresses" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Mattresses\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Audio" data-pr="over30">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/pCvBVHuhaQVjKt3VgCjbqT-132-100.png" alt="Audio" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Audio\x3C/span>            \x3C/div>                  \x3C/div>        \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" onclick="this.parentElement.querySelector('.tg-df-carousel-roundels').scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>        \x3C/div>        \x3C/div>        \x3Cdiv class="tg-df-carousel-filters-outer" style="position: relative;">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').scrollBy({left: -200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \x3Cdiv class="tg-df-carousel-filters-wrap">                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="0">All\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-ot="amazon_lightning">              \x3Cimg src="https://cdn.mos.cms.futurecdn.net/HqAui7w97ft2NPqBtQ5r38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/yWPQ5yyQRhUwVKzGwYbh38-600-100.png" class="active-img" alt="" /> Lightning deals\x3C/button>            \x3Cbutton class="tg-df-carousel-filter-btn" data-ot="amazon_prime">              \x3Cimg src="https://cdn.mos.cms.futurecdn.net/fwoVXvL79turN3Ph535m38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/u75QjVpt3w2EsMimJiRo38-600-100.png" class="active-img" alt="" /> Prime deals\x3C/button>            \x3Cbutton class="tg-df-carousel-filter-btn" data-d="10">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 10% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="15">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 15% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="25">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 25% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-pr="under50">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-badge-dollar-sign">\x3Cpath d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z">\x3C/path>\x3Cpath d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8">\x3C/path>\x3Cpath d="M12 18V6">\x3C/path>\x3C/svg>            Under $50\x3C/button>        \x3C/div>        \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>      \x3C/div>    \x3C/div>    \x3C/div>      \x3C!-- Search & Filter Controls --\x3E      \x3Cdiv class="tg-df-top-bar" id="tg-df-top-bar" style="position: relative; z-index: 100; margin: 0 auto 20px;">        \x3Cdiv class="tg-df-search-wrapper">          \x3Cinput type="text" class="tg-df-search-input" placeholder="Search for deals, products, or brands...">          \x3Cbutton type="button" class="tg-df-search-btn" aria-label="Search">              \x3Csvg class="tg-df-search-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">                \x3Cpath d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>              \x3C/svg>          \x3C/button>          \x3Cdiv class="tg-df-autocomplete-dropdown" id="tg-df-autocomplete">\x3C/div>        \x3C/div>      \x3C/div>    \x3Cdiv class="tg-df-controls" id="tg-df-controls" style="display:flex;">              \x3Cdiv class="tg-df-filters-container" style="position: relative; width: 100%; max-width: 800px; margin: 0 auto;">          \x3Cbutton class="tg-df-scroll-btn left" style="display: none;" onclick="this.parentElement.querySelector('.tg-df-filters').scrollBy({left: -200, behavior: 'smooth'})">            \x3Csvg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\x3Cpath d="M15 18l-6-6 6-6"/>\x3C/svg>          \x3C/button>          \x3Cbutton class="tg-df-scroll-btn right" style="display: none;" onclick="this.parentElement.querySelector('.tg-df-filters').scrollBy({left: 200, behavior: 'smooth'})">            \x3Csvg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\x3Cpath d="M9 18l6-6-6-6"/>\x3C/svg>          \x3C/button>          \x3Cdiv class="tg-df-filters">          \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-category-filter-wrapper" style="display: none;">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-category-filter" aria-label="Category">            \x3Coption value="all">All Categories\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper tg-df-multiselect-container" id="tg-df-brand-filter-wrapper" style="display:none;">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M4.25 5.61C6.27 8.2 10 13 10 13v6c0 .55.45 1 1 1h2c.55 0 1-.45 1-1v-6s3.72-4.8 5.74-7.39A.998.998 0 0 0 18.95 4H5.04c-.83 0-1.3.95-.79 1.61z"/>          \x3C/svg>          \x3Cdiv class="tg-df-filter-select tg-df-multiselect-trigger" id="tg-df-brand-trigger" tabindex="0">            Any Brand          \x3C/div>          \x3Cdiv class="tg-df-multiselect-dropdown" id="tg-df-brand-dropdown">            \x3C!-- Populated via script --\x3E          \x3C/div>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper tg-df-price-range-wrapper" id="tg-df-custom-price-wrapper" style="display: flex; align-items:center; justify-content:center; padding: 10px 20px; gap: 8px; border: 1px solid var(--tg-df-border); border-radius: 100px; background-color: var(--tg-df-bg);">          \x3Cspan style="font-size:14px; font-weight:500; color:var(--tg-df-text-primary);">Price\x3C/span>          \x3Cinput type="number" class="tg-df-price-input" id="tg-df-custom-price-min" placeholder="Min" style="width: 48px; background: transparent; border: none; color: var(--tg-df-text-primary); outline: none; font-size: 14px; text-align: center; padding: 0;">          \x3Cspan style="color:var(--tg-df-text-muted)">-\x3C/span>          \x3Cinput type="number" class="tg-df-price-input" id="tg-df-custom-price-max" placeholder="Max" style="width: 48px; background: transparent; border: none; color: var(--tg-df-text-primary); outline: none; font-size: 14px; text-align: center; padding: 0;">        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-legacy-price-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-price-filter" aria-label="Filter Prices">            \x3Coption value="all">All Prices\x3C/option>            \x3Coption value="under50">Under $50\x3C/option>            \x3Coption value="50_100">$50 - $100\x3C/option>            \x3Coption value="100_200">$100 - $200\x3C/option>            \x3Coption value="200_500">$200 - $500\x3C/option>            \x3Coption value="over500">Over $500\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-discount-filter-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">            \x3Cpath d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-discount-filter" aria-label="Discount Amount">            \x3Coption value="all">Any discount\x3C/option>            \x3Coption value="5">Min 5%\x3C/option>            \x3Coption value="10">Min 10%\x3C/option>            \x3Coption value="15">Min 15%\x3C/option>            \x3Coption value="20">Min 20%\x3C/option>            \x3Coption value="25">Min 25%\x3C/option>            \x3Coption value="30">Min 30%\x3C/option>            \x3Coption value="40">Min 40%\x3C/option>            \x3Coption value="50">Min 50%\x3C/option>            \x3Coption value="60">Min 60%\x3C/option>            \x3Coption value="70">Min 70%\x3C/option>          \x3C/select>          \x3C/div>        \x3C/div>        \x3C/div>      \x3C/div>    \x3C!-- Deals Grid Wrapper --\x3E    \x3Cdiv class="tg-df-grid-wrapper tg-df-carousel-cards-wrapper" id="tg-df-grid-wrapper">      \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').scrollBy({left: -200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>      \x3Cdiv class="tg-df-grid" id="tg-df-grid">        \x3C!-- Content populated by JavaScript --\x3E      \x3C/div>      \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>    \x3C/div>        \x3C!-- Vouchers Modal --\x3E    \x3Cdiv class="tg-df-modal-backdrop" id="tg-df-vouchers-modal">      \x3Cdiv class="tg-df-modal">        \x3Cdiv class="tg-df-modal-header">          \x3Ch3 class="tg-df-modal-title" id="tg-df-vouchers-title">Available Coupons & Deals\x3C/h3>          \x3Cbutton class="tg-df-modal-close" id="tg-df-vouchers-close">            \x3Csvg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">              \x3Cline x1="18" y1="6" x2="6" y2="18">\x3C/line>              \x3Cline x1="6" y1="6" x2="18" y2="18">\x3C/line>            \x3C/svg>          \x3C/button>        \x3C/div>        \x3Cdiv class="tg-df-modal-body" id="tg-df-vouchers-content">          \x3C!-- Vouchers injected here --\x3E        \x3C/div>      \x3C/div>    \x3C/div>  \x3C/div>`;      if (!template) {        template = document.createElement('template');        template.innerHTML = rawTemplate;      }      let shadowRoot = null;      if (hostContainer && template) {        hostContainer.setAttribute('data-initialized', 'true');        shadowRoot = hostContainer.attachShadow({ mode: 'open' });        shadowRoot.appendChild(template.content.cloneNode(true));      }      class DealsFinderWidget {        constructor(config) {          this.rootNode = config.rootNode || document;          this.hostContainer = config.hostContainer || null;          this.rootId = config.rootId || 'signal-deals-finder-root';          this.root = this.rootNode.querySelector('#' + this.rootId);          if (!this.root) return;          this.widgetId = (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : 'widget-' + Date.now() + '-' + Math.random().toString(36).slice(2);          this.grid = this.root.querySelector('#tg-df-grid');          this.tagsContainer = this.root.querySelector('#tg-df-tags-container');          this.categoryFilter = this.root.querySelector('#tg-df-category-filter');          this.categoryFilterWrapper = this.root.querySelector('#tg-df-category-filter-wrapper');          this.searchInput = this.root.querySelector('.tg-df-search-input');          this.autocompleteDropdown = this.root.querySelector('#tg-df-autocomplete');          this.sortSelect = this.root.querySelector('.tg-df-sort-select');          this.searchBtn = this.root.querySelector('.tg-df-search-btn');                    this.settingsToggle = this.root.querySelector('#tg-df-settings-toggle');          this.settingsPanel = this.root.querySelector('#tg-df-settings-panel');          this.settingsBackdrop = this.root.querySelector('#tg-df-settings-backdrop');          this.regionSelect = this.root.querySelector('#tg-df-region-select');          this.retailerSelect = this.root.querySelector('#tg-df-retailer-select');          this.offerTypeSelect = this.root.querySelector('#tg-df-offer-type-select');          this.viewModeSelect = this.root.querySelector('#tg-df-view-mode-select');          this.rowsSelect = this.root.querySelector('#tg-df-rows-select');          this.dealModeToggle = this.root.querySelector('#tg-df-deal-mode');          this.editorModeToggle = this.root.querySelector('#tg-df-editor-mode');          this.priceFilter = this.root.querySelector('#tg-df-price-filter');          this.discountFilter = this.root.querySelector('#tg-df-discount-filter');                    this.editorBar = this.root.querySelector('#tg-df-editor-bar');          this.editorSelectedCount = this.root.querySelector('#tg-df-selected-count');          this.editorCopyBtn = this.root.querySelector('#tg-df-editor-copy');          this.editorClearBtn = this.root.querySelector('#tg-df-editor-clear');                    this.apiUrl = 'https://search-api.fie.future.net.uk/widget.php';          this.deals = [];          this.displayLimit = 12;          this.airedaleArticles = null;          this.airedaleTags = [];          this.airedaleTagCounts = {};          this.activeDealTag = null;          this.selectedBrands = [];          this.currentQuery = '';          this.editorMode = this.hostContainer ? this.hostContainer.hasAttribute('data-editor-mode') : false;          this.viewModeOverride = this.hostContainer ? this.hostContainer.getAttribute('data-view-mode') : null;          this.selectedDeals = new Map();                    this.brandFilterWrapper = this.root.querySelector('#tg-df-brand-filter-wrapper');          this.brandTrigger = this.root.querySelector('#tg-df-brand-trigger');          this.brandDropdown = this.root.querySelector('#tg-df-brand-dropdown');                    this.customPriceWrapper = this.root.querySelector('#tg-df-custom-price-wrapper');          this.customPriceMin = this.root.querySelector('#tg-df-custom-price-min');          this.customPriceMax = this.root.querySelector('#tg-df-custom-price-max');          this.legacyPriceWrapper = this.root.querySelector('#tg-df-legacy-price-wrapper');          this.discountFilterWrapper = this.root.querySelector('#tg-df-discount-filter-wrapper');          this.initResizeObserver();          this.init();        }        getViewMode() {          console.log("DEBUG getViewMode -> override:", this.viewModeOverride, "editorMode:", this.editorMode);          if (this.viewModeOverride && (!this.editorMode || !this.viewModeSelect)) {            return this.viewModeOverride;          }          return (this.viewModeSelect && this.viewModeSelect.value) ? this.viewModeSelect.value : (this.viewModeOverride || 'auto');        }        applyLayoutMode() {          if (!this.grid) return;          const mode = this.getViewMode();          console.log("[DEBUG] applyLayoutMode CALLED! mode=", mode);          this.grid.classList.remove('layout-row', 'layout-grid', 'tg-df-grid-auto', 'carousel-compact', 'layout-replica-1', 'layout-replica-2');                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          const showHeaderDetails = params.get('show_header_details') !== 'false';          const carouselHost = this.root.querySelector('#tg-df-carousel-host');          const controlsDiv = this.root.querySelector('#tg-df-controls');          const topBarDiv = this.root.querySelector('#tg-df-top-bar');          const headerElement = this.root.querySelector('#tg-df-savings-squad-header');          if (headerElement) {             headerElement.style.display = (mode === 'savings_squad' && showHeaderDetails) ? 'block' : 'none';          }          if (mode === 'carousel') {             this.grid.classList.add('carousel-compact');             if (carouselHost) carouselHost.style.display = 'block';             if (controlsDiv) controlsDiv.style.display = 'none';             if (topBarDiv) topBarDiv.style.display = 'none';             if (this.root.classList.contains('tg-df-container')) {               this.root.classList.add('is-carousel');             }          } else {             if (carouselHost) carouselHost.style.display = 'none';             if (controlsDiv) controlsDiv.style.display = 'flex';             if (topBarDiv) topBarDiv.style.display = 'block';             if (this.root.classList.contains('tg-df-container')) {               this.root.classList.remove('is-carousel');             }          }          if (mode === 'grid') {            this.grid.classList.add('layout-grid');          } else if (mode === 'row') {            this.grid.classList.add('layout-row');          } else if (mode === 'savings_squad') {            this.grid.classList.add('tg-df-grid-auto', 'savings-squad-cards');          } else if (mode !== 'carousel') {            this.grid.classList.add('tg-df-grid-auto');          }                    const settingsWrapper = this.root.querySelector('.tg-df-settings-wrapper');          if (settingsWrapper) {            settingsWrapper.style.display = mode === 'auto' ? 'none' : 'block';          }          if (this.customPriceWrapper) {             this.customPriceWrapper.style.display = mode === 'auto' ? 'flex' : 'none';          }          if (this.legacyPriceWrapper) {             this.legacyPriceWrapper.style.display = mode === 'auto' ? 'none' : 'flex';          }          if (this.discountFilterWrapper) {             this.discountFilterWrapper.style.display = mode === 'auto' ? 'none' : 'flex';          }        }        initResizeObserver() {          try {            if (window.parent === window) return;          } catch (e) {            // cross origin frame check threw          }          const emitHeight = () => {            try {              const height = document.documentElement.scrollHeight || document.body.scrollHeight;              const msg = { type: 'embed-size', height: height };              if (window.parent && window.parent !== window) {                window.parent.postMessage(msg, '*');                window.parent.postMessage(JSON.stringify({ ...msg, sentinel: 'amp' }), '*');              }            } catch (e) {}          };                    if (window.ResizeObserver) {            try {              const ro = new ResizeObserver(() => emitHeight());              ro.observe(document.body);              if (this.root) ro.observe(this.root);            } catch(e){ console.warn(e); }          }          window.addEventListener('resize', emitHeight);          setTimeout(emitHeight, 300);        }        initCountdown() {          this.cdWrapper = this.root.querySelector('#tg-df-countdown-wrapper');                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          this.showCountdown = params.get('show_countdown') === 'true';          const showHeaderDetails = params.get('show_header_details') !== 'false';          const eyebrow = this.root.querySelector('.tg-df-carousel-box-eyebrow');          const title = this.root.querySelector('.tg-df-carousel-box-title');          const subtitle = this.root.querySelector('.tg-df-carousel-box-subtitle');          if (!showHeaderDetails) {            let containerElement = this.root.classList.contains('tg-df-container') ? this.root : this.root.querySelector('.tg-df-container');            if (containerElement) containerElement.classList.add('hide-header-details');            if (eyebrow) eyebrow.style.display = 'none';            if (title) title.style.display = 'none';            if (subtitle) subtitle.style.display = 'none';          }          if (!this.cdWrapper) return;          this.cdTitle = this.root.querySelector('#tg-df-countdown-title');          this.cdDays = this.root.querySelector('#tg-df-cd-days');          this.cdHrs = this.root.querySelector('#tg-df-cd-hrs');          this.cdMin = this.root.querySelector('#tg-df-cd-min');          this.cdSec = this.root.querySelector('#tg-df-cd-sec');          this.updateCountdown();          this.cdInterval = setInterval(() => this.updateCountdown(), 1000);        }        updateCountdown() {          if (!this.cdWrapper) return;          if (!this.showCountdown) {            this.cdWrapper.style.display = 'none';            return;          }          const area = this.getAreaCode();          let offset = '-04:00';          if (['DE', 'FR', 'IT', 'ES', 'NL'].includes(area)) {             offset = '+02:00';          } else if (['GB', 'IE', 'UK'].includes(area)) {             offset = '+01:00';          }          const startTime = new Date('2026-06-23T00:00:00' + offset).getTime();          const endTime = new Date('2026-06-26T00:00:00' + offset).getTime();          const now = Date.now();          let targetTime = 0;          if (now < startTime) {             targetTime = startTime;             if (this.cdTitle) this.cdTitle.textContent = 'Prime Day starts in';             this.cdWrapper.style.display = 'flex';          } else if (now < endTime) {             targetTime = endTime;             if (this.cdTitle) this.cdTitle.textContent = 'Prime Day ends in';             this.cdWrapper.style.display = 'flex';          } else {             this.cdWrapper.style.display = 'none';             if (this.cdInterval) clearInterval(this.cdInterval);             return;          }          const diff = Math.max(0, targetTime - now);          const d = Math.floor(diff / (1000 * 60 * 60 * 24));          const h = Math.floor((diff / (1000 * 60 * 60)) % 24);          const m = Math.floor((diff / 1000 / 60) % 60);          const s = Math.floor((diff / 1000) % 60);          if (this.cdDays) this.cdDays.textContent = d;          if (this.cdHrs) this.cdHrs.textContent = h;          if (this.cdMin) this.cdMin.textContent = m;          if (this.cdSec) this.cdSec.textContent = s;        }        init() {          this.initCountdown();          try {            initAnalytics();          } catch (e) {            console.warn('Deals Widget Analytics Error:', e);          }                    this.bindEvents();                    let initialQuery = '';                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          let initialViewMode = params.get('view_mode');          if (!this.viewModeOverride && initialViewMode) {            this.viewModeOverride = initialViewMode;          }          if (!params.has('search') && !params.has('q') && !params.has('query') && initialViewMode !== 'savings_squad') {             initialQuery = 'Gaming laptops';          }          const website = params.get('website') || 'tomsguide';          this.website = website;          if (website === 'techradar') {            const squadHeader = this.root.querySelector('.tg-df-savings-squad-header');            if (squadHeader) {               const pic = squadHeader.querySelector('picture');               if (pic) pic.style.display = 'none';            }            const style = document.createElement('style');            style.innerHTML = `              .tg-df-container .hawk-affiliate-link-deal-button, .tg-df-container .tg-df-card-cta { background-color: #5DAF08 !important; }              .tg-df-container .hawk-affiliate-link-deal-button:hover, .tg-df-container .tg-df-card-cta:hover { background-color: #4a8c06 !important; }            `;            this.root.appendChild(style);          }                    if (this.regionSelect) {            this.regionSelect.value = params.get('region') || 'auto';            this.updatePriceDropdownCurrency();          }                    if (this.retailerSelect && params.has('retailer')) {            this.retailerSelect.value = params.get('retailer');          }                    if (params.has('brands')) {            const b = params.get('brands');            if (b) {              this.selectedBrands = b.split(',');            }          }                    if (this.offerTypeSelect && params.has('offer_type')) {            this.offerTypeSelect.value = params.get('offer_type');          }          if (this.viewModeSelect && params.has('view_mode')) {            this.viewModeSelect.value = params.get('view_mode');          }          if (this.rowsSelect && params.has('rows')) {            this.rowsSelect.value = params.get('rows');          }          if (params.has('price')) {            const priceVal = params.get('price');            if (this.priceFilter) {               // Try assigning it directly to select. If it's not present implicitly ignores               this.priceFilter.value = priceVal;            }            if (priceVal.includes('_')) {               const parts = priceVal.split('_');               if (this.customPriceMin && parts[0]) this.customPriceMin.value = parts[0];               if (this.customPriceMax && parts[1]) this.customPriceMax.value = parts[1];            }          }          if (this.discountFilter && params.has('min_discount_ratio')) {            // Need to convert back from ratio (e.g. 0.8) to select value (e.g. "20")            const ratioStr = params.get('min_discount_ratio');            const ratioFloat = parseFloat(ratioStr);            if (!isNaN(ratioFloat)) {               const percentage = Math.round((1 - ratioFloat) * 100);               this.discountFilter.value = percentage.toString();            }          }          if (this.sortSelect) {            this.sortSelect.value = params.get('sort') || 'date_desc';          }          if (this.dealModeToggle && params.has('deal_mode')) {            this.dealModeToggle.checked = params.get('deal_mode') === 'true' || params.get('deal_mode') === '1';          }          const headerTitleEl = this.root.querySelector('#tg-df-header-title');          const headerSubtitleEl = this.root.querySelector('#tg-df-header-subtitle');          if (params.has('widget_title') && headerTitleEl) {             headerTitleEl.textContent = params.get('widget_title');          }          if (params.has('widget_subtitle') && headerSubtitleEl) {             headerSubtitleEl.textContent = params.get('widget_subtitle');          }                    // Re-apply layout after params have updated control values          this.applyLayoutMode();                    if (params.get('search')) {            initialQuery = params.get('search');          } else if (params.get('q')) {            initialQuery = params.get('q');          } else if (params.get('query')) {            initialQuery = params.get('query');          }                    this.currentQuery = initialQuery;          if (this.searchInput) {            if (this.getViewMode() === 'savings_squad') {              this.searchInput.value = '';            } else {              this.searchInput.value = this.currentQuery;            }          }                    if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {            this.fetchDeals(this.currentQuery);          } else {            this.render();          }        }        updatePriceDropdownCurrency() {          if (!this.priceFilter || !this.regionSelect) return;          const currencySymbols = {            'US': '$',            'GB': '£',            'CA': '$CA',            'AU': '$AU',            'DE': '€',            'FR': '€',            'IT': '€',          };          const area = this.getAreaCode();          const cur = currencySymbols[area || 'US'] || '$';                    const options = this.priceFilter.options;          for (let i = 0; i < options.length; i++) {            const opt = options[i];            if (opt.value === 'all') {              opt.innerText = 'All Prices';            } else if (opt.value === 'under50') {              opt.innerText = `Under ${cur}50`;            } else if (opt.value === '50_100') {              opt.innerText = `${cur}50 - ${cur}100`;            } else if (opt.value === '100_200') {              opt.innerText = `${cur}100 - ${cur}200`;            } else if (opt.value === '200_500') {              opt.innerText = `${cur}200 - ${cur}500`;            } else if (opt.value === 'over500') {              opt.innerText = `Over ${cur}500`;            }          }        }        populateBrandDropdown(values) {          if (!this.brandDropdown || !this.brandFilterWrapper) return;          this.brandFilterWrapper.style.display = 'flex'; // show the wrapper                    let html = '';          const allChecked = this.selectedBrands.length === 0 ? 'checked' : '';          const _div = '<' + '/div>';          const _span = '<' + '/span>';          html += `\x3Cdiv class="tg-df-ms-option">\x3Cinput type="checkbox" value="" ${allChecked} class="tg-df-brand-chk"> Any Brand${_div}`;                    values.forEach(v => {             if (!v.formatted_value || v.formatted_value === 'Any Brand') return;             const isChecked = this.selectedBrands.includes(v.formatted_value) ? 'checked' : '';             html += `\x3Cdiv class="tg-df-ms-option">\x3Cinput type="checkbox" value="${this.escapeHTML(v.formatted_value)}" ${isChecked} class="tg-df-brand-chk"> ${this.escapeHTML(v.formatted_value)} \x3Cspan style="color:var(--tg-df-text-muted);font-size:12px">(${v.count || 0})${_span}${_div}`;          });                    this.brandDropdown.innerHTML = html;                    // Re-bind listeners          const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');          chks.forEach(chk => {            chk.addEventListener('change', (e) => {              const val = e.target.value;              if (val === '') {                this.selectedBrands = [];              } else {                if (e.target.checked) {                   if (!this.selectedBrands.includes(val)) this.selectedBrands.push(val);                } else {                   this.selectedBrands = this.selectedBrands.filter(b => b !== val);                }              }                            if (this.selectedBrands.length === 0) {                 this.brandTrigger.innerText = 'Any Brand';              } else if (this.selectedBrands.length === 1) {                 this.brandTrigger.innerText = this.selectedBrands[0];              } else {                 this.brandTrigger.innerText = `${this.selectedBrands.length} Brands selected`;              }                            // Only call API if changed from UI interactions              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                 this.updateURLParams();                 this.fetchDeals(this.currentQuery);              }            });          });                    // Update button text on load          if (this.selectedBrands.length === 0) {             this.brandTrigger.innerText = 'Any Brand';          } else if (this.selectedBrands.length === 1) {             this.brandTrigger.innerText = this.selectedBrands[0];          } else {             this.brandTrigger.innerText = `${this.selectedBrands.length} Brands selected`;          }        }        updateURLParams() {          const url = new URL(window.location);          if (this.currentQuery && this.currentQuery !== 'Gaming laptops') {            url.searchParams.set('q', this.currentQuery);          } else {            url.searchParams.delete('q');            url.searchParams.delete('search');            url.searchParams.delete('query');          }                    if (this.regionSelect && this.regionSelect.value !== 'auto') {            url.searchParams.set('region', this.regionSelect.value);          } else {            url.searchParams.delete('region');          }                    if (this.retailerSelect && this.retailerSelect.value) {            url.searchParams.set('retailer', this.retailerSelect.value);          } else {            url.searchParams.delete('retailer');          }                    if (this.selectedBrands && this.selectedBrands.length > 0) {            url.searchParams.set('brands', this.selectedBrands.join(','));          } else {            url.searchParams.delete('brands');          }                    if (this.offerTypeSelect && this.offerTypeSelect.value) {            url.searchParams.set('offer_type', this.offerTypeSelect.value);          } else {            url.searchParams.delete('offer_type');          }                    if (this.viewModeSelect && this.viewModeSelect.value !== 'auto') {            url.searchParams.set('view_mode', this.viewModeSelect.value);          } else {            url.searchParams.delete('view_mode');          }                    if (this.rowsSelect && this.rowsSelect.value !== '12') {            url.searchParams.set('rows', this.rowsSelect.value);          } else {            url.searchParams.delete('rows');          }                    const min = this.customPriceMin ? this.customPriceMin.value : '';          const max = this.customPriceMax ? this.customPriceMax.value : '';          if (min || max) {             url.searchParams.set('price', `${min}_${max}`);          } else if (this.priceFilter && this.priceFilter.value !== 'all') {            url.searchParams.set('price', this.priceFilter.value);          } else {            url.searchParams.delete('price');          }                    if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {            const v = parseInt(this.discountFilter.value);            if (!isNaN(v) && v > 0) {               const ratio = (100 - v) / 100;               url.searchParams.set('min_discount_ratio', ratio.toString());            }          } else {            url.searchParams.delete('min_discount_ratio');          }                    if (this.sortSelect && this.sortSelect.value !== 'date_desc') {            url.searchParams.set('sort', this.sortSelect.value);          } else {            url.searchParams.delete('sort');          }                    if (this.dealModeToggle && this.dealModeToggle.checked) {            url.searchParams.set('deal_mode', 'true');          } else {            url.searchParams.delete('deal_mode');          }                    window.history.replaceState({}, '', url);        }        bindEvents() {          const handleFiltersScroll = () => {            const filters = this.root.querySelector('.tg-df-filters');            const leftBtn = this.root.querySelector('.tg-df-scroll-btn.left');            const rightBtn = this.root.querySelector('.tg-df-scroll-btn.right');            if (filters && leftBtn && rightBtn) {              const { scrollLeft, scrollWidth, clientWidth } = filters;              leftBtn.style.display = scrollLeft > 0 ? 'flex' : 'none';              rightBtn.style.display = Math.ceil(scrollLeft + clientWidth) < scrollWidth - 5 ? 'flex' : 'none';            }          };          const filters = this.root.querySelector('.tg-df-filters');          if (filters) {            filters.addEventListener('scroll', handleFiltersScroll);            window.addEventListener('resize', handleFiltersScroll);            setTimeout(handleFiltersScroll, 100);                        // Also call after rendering dropdowns            const origRenderCategories = this.renderCategories;            if (origRenderCategories) {               this.renderCategories = (...args) => {                 origRenderCategories.apply(this, args);                 setTimeout(handleFiltersScroll, 50);               };            }          }                const roundels = this.root.querySelectorAll('.tg-df-carousel-cat');          roundels.forEach(r => {             r.addEventListener('click', () => {                const q = r.getAttribute('data-query');                const pr = r.getAttribute('data-pr');                if (typeof trackHawkEvent !== 'undefined') {                     trackHawkEvent({                         clickType: "CC",                         widgetId: this.widgetId,                         productCategoryName: "deals",                         zeroBasedProductIndexOrNull: null,                         totalDealsOrProducts: null,                         areaClicked: "Category Roundel",                         revenueId: this.revenueId,                         isoCurrencyCode: typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD',                         queryName: q,                         widgetTypeName: this.widgetTypeName                     });                 }                this.currentQuery = q;                const label = this.root.querySelector('#tg-df-carousel-title-label');                if (label) label.textContent = 'Best ' + q;                if (this.priceFilter) this.priceFilter.value = pr || 'all';                if (this.discountFilter) this.discountFilter.value = '5';                if (this.searchInput) this.searchInput.value = q;                                roundels.forEach(ro => ro.classList.remove('active'));                r.classList.add('active');                this.fetchDeals(this.currentQuery);             });          });          const discBtns = this.root.querySelectorAll('.tg-df-carousel-filter-btn');          discBtns.forEach(b => {             b.addEventListener('click', () => {                const d = b.getAttribute('data-d');                const pr = b.getAttribute('data-pr');                const ot = b.getAttribute('data-ot');                let label = b.innerText ? b.innerText.trim() : '';                let filterType = 'unknown';                let filterVal = 'unknown';                if (d !== null) { filterType = 'discount'; filterVal = d; }                else if (pr !== null) { filterType = 'price'; filterVal = pr; }                else if (ot !== null) { filterType = 'offertype'; filterVal = ot; }                if (typeof trackElementInteraction === 'function') trackElementInteraction({ id: `filter-${filterType}-${filterVal}`, name: 'Filter Button', label: label });                                if (d !== null) {                   if (this.discountFilter) this.discountFilter.value = this.discountFilter.value === d ? '0' : d;                } else if (pr !== null) {                   if (this.priceFilter) this.priceFilter.value = this.priceFilter.value === pr ? 'all' : pr;                } else if (ot !== null) {                   if (this.offerTypeSelect) this.offerTypeSelect.value = this.offerTypeSelect.value === ot ? 'all' : ot;                } else {                   if (this.discountFilter) this.discountFilter.value = '0';                   if (this.priceFilter) this.priceFilter.value = 'all';                   if (this.offerTypeSelect) this.offerTypeSelect.value = 'all';                }                if (d === null && pr === null && ot === null && b.getAttribute("data-type") !== "custom") {                   discBtns.forEach(ro => ro.classList.remove('active'));                   b.classList.add('active');                } else if (b.getAttribute("data-type") !== "custom") {                   // Only operate on hardcoded buttons (those without data-type)                   discBtns.forEach(ro => {                      if (!ro.getAttribute('data-d') && !ro.getAttribute('data-pr') && !ro.getAttribute('data-ot') && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active');                   });                                      let makeActive = true;                   if (d !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-d') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   } else if (pr !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-pr') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   } else if (ot !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-ot') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   }                                      if (makeActive) b.classList.add('active');                                      // Check if anything is active, if not activate "All"                   let anyActive = false;                   discBtns.forEach(ro => { if (ro.classList.contains('active') && ro.getAttribute('data-type') !== 'custom') anyActive = true; });                   if (!anyActive) {                       discBtns.forEach(ro => { if (!ro.getAttribute('data-d') && !ro.getAttribute('data-pr') && !ro.getAttribute('data-ot') && ro.getAttribute('data-type') !== 'custom') ro.classList.add('active'); });                   }                }                                this.fetchDeals(this.currentQuery);             });          });          if (this.brandTrigger && this.brandDropdown) {            this.brandTrigger.addEventListener('click', () => {              this.brandDropdown.classList.toggle('active');            });            document.addEventListener('click', (e) => {              if (this.brandFilterWrapper && !e.composedPath().includes(this.brandFilterWrapper)) {                this.brandDropdown.classList.remove('active');              }            });          }          const showAutocomplete = () => {             if (this.getViewMode() !== 'savings_squad' || !this.autocompleteDropdown || !this.airedaleTags) return;                          let terms = this.airedaleTags;             if (this.airedaleBrands) {                terms = terms.concat(this.airedaleBrands.map(b => b.formatted_value));             }             terms = [...new Set(terms)];                          const query = this.searchInput.value.trim();             let matches = [];             if (query.length > 0) {                 matches = terms.filter(t => t.toLowerCase().includes(query.toLowerCase()) && t.toLowerCase() !== query.toLowerCase());             } else {                 matches = terms;             }                          if (matches.length > 0) {                 this.autocompleteDropdown.innerHTML = matches.map(m => `\x3Cdiv class="tg-df-autocomplete-item" data-tag="${this.escapeHTML(m)}">${this.escapeHTML(m)}<` + `/div>`).join('');                 this.autocompleteDropdown.classList.add('active');             } else {                 this.autocompleteDropdown.classList.remove('active');             }          };          let debounceTimer;          if(this.searchInput) {            this.searchInput.addEventListener('focus', showAutocomplete);            this.searchInput.addEventListener('input', (e) => {              clearTimeout(debounceTimer);              const query = e.target.value.trim();              this.currentQuery = query;              showAutocomplete();              debounceTimer = setTimeout(() => {                this.updateURLParams();                if (query.length > 2) {                  this.fetchDeals(query);                } else if (query.length === 0) {                  if (this.getViewMode() === 'savings_squad') {                    this.activeDealTag = null;                    this.currentQuery = '';                    if (this.categoryFilter) this.categoryFilter.value = 'all';                    this.fetchDeals('');                  } else {                    this.deals = [];                    this.render();                  }                }              }, 400);            });            this.searchInput.addEventListener('keypress', (e) => {              if (e.key === 'Enter') {                if (this.autocompleteDropdown) this.autocompleteDropdown.classList.remove('active');                clearTimeout(debounceTimer);                const query = e.target.value.trim();                this.currentQuery = query;                                let isTag = false;                if (this.airedaleTags && this.airedaleTags.includes(query)) isTag = true;                if (this.airedaleBrands && this.airedaleBrands.some(b => b.formatted_value === query)) isTag = true;                this.activeDealTag = isTag ? query : null;                                trackElementInteraction({ id: 'search-submit', name: 'Ask', label: 'Ask (main search)', text: query });                this.updateURLParams();                if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                   if (query.length === 0 && this.getViewMode() === 'savings_squad') {                       if (this.categoryFilter) this.categoryFilter.value = 'all';                   }                   this.fetchDeals(query);                }              }            });          }          if (this.autocompleteDropdown) {             this.autocompleteDropdown.addEventListener('click', (e) => {                const item = e.target.closest('.tg-df-autocomplete-item');                if (item) {                   const tag = item.getAttribute('data-tag');                   this.currentQuery = tag;                   if (this.searchInput) this.searchInput.value = tag;                   this.activeDealTag = tag;                   if (this.categoryFilter && this.airedaleTags.includes(tag)) {                       this.categoryFilter.value = tag;                   }                   this.autocompleteDropdown.classList.remove('active');                   this.updateURLParams();                   this.fetchDeals(tag);                }             });             document.addEventListener('click', (e) => {               if (this.autocompleteDropdown && this.searchInput && !e.composedPath().includes(this.searchInput) && !e.composedPath().includes(this.autocompleteDropdown)) {                 this.autocompleteDropdown.classList.remove('active');               }             });          }          if (this.searchBtn) {            this.searchBtn.addEventListener('click', () => {              if (this.autocompleteDropdown) this.autocompleteDropdown.classList.remove('active');              clearTimeout(debounceTimer);              const query = this.searchInput.value.trim();              trackElementInteraction({ id: 'search-submit', name: 'Ask', label: 'Ask (main search)', text: query });                            let isTag = false;              if (this.airedaleTags && this.airedaleTags.includes(query)) isTag = true;              if (this.airedaleBrands && this.airedaleBrands.some(b => b.formatted_value === query)) isTag = true;              this.activeDealTag = isTag ? query : null;                            this.currentQuery = query;              this.updateURLParams();              if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                 if (query.length === 0 && this.getViewMode() === 'savings_squad') {                     if (this.categoryFilter) this.categoryFilter.value = 'all';                 }                 this.fetchDeals(query);              }            });          }          if(this.sortSelect && this.sortSelect.querySelector('option[value="date_desc"]') === null) {              const option = document.createElement('option');              option.value = "date_desc";              option.text = "Newest First";              this.sortSelect.insertBefore(option, this.sortSelect.firstChild);          }          if(this.sortSelect) this.sortSelect.addEventListener('change', () => {            trackElementInteraction({ id: `sort-option-${this.sortSelect.value}`, name: 'Sort', label: `Sort: ${this.sortSelect.options[this.sortSelect.selectedIndex].text}` });            this.updateURLParams();            if (this.deals.length > 0) {              this.sortData();              this.render();            }          });                    const priceFilter = this.root.querySelector('#tg-df-price-filter');          if (priceFilter) {            this.priceFilter = priceFilter;            this.priceFilter.addEventListener('change', () => {              trackElementInteraction({ id: `filter-price-${this.priceFilter.value}`, name: 'Price', label: this.priceFilter.options[this.priceFilter.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }            });          }          const updateCustomPrice = () => {             this.updateURLParams();             if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);             } else {                this.render();             }          };          if (this.customPriceMin) {             this.customPriceMin.addEventListener('change', updateCustomPrice);             this.customPriceMin.addEventListener('keypress', (e) => {                if (e.key === 'Enter') updateCustomPrice();             });          }          if (this.customPriceMax) {             this.customPriceMax.addEventListener('change', updateCustomPrice);             this.customPriceMax.addEventListener('keypress', (e) => {                if (e.key === 'Enter') updateCustomPrice();             });          }          const discountFilter = this.root.querySelector('#tg-df-discount-filter');          if (discountFilter) {            this.discountFilter = discountFilter;            this.discountFilter.addEventListener('change', () => {              trackElementInteraction({ id: `filter-discount-${this.discountFilter.value}`, name: 'Discount', label: this.discountFilter.options[this.discountFilter.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }            });          }          if (this.categoryFilter) {            this.categoryFilter.addEventListener('change', (e) => {               const val = e.target.value === 'all' ? null : e.target.value;               this.activeDealTag = val;               if (val) {                 this.currentQuery = val;               } else {                 if (this.searchInput && this.currentQuery === document.querySelector('#tg-df-brand-trigger')?.getAttribute('data-active-brand')) {                     // don't clear current query if a brand is selected                 } else if (this.searchInput) {                     this.currentQuery = '';                     this.searchInput.value = '';                 }               }               this.fetchSavingsSquad();            });          }                    if (this.settingsToggle) {            this.settingsToggle.addEventListener('click', () => {              const o = this.settingsPanel.classList.toggle('active');              this.settingsBackdrop.classList.toggle('active');              if (o) trackElementInteraction({ id: 'filter-open', name: 'Filters', label: 'Open filters' });            });          }                    if (this.settingsBackdrop) {            this.settingsBackdrop.addEventListener('click', () => {              this.settingsPanel.classList.remove('active');              this.settingsBackdrop.classList.remove('active');            });          }                    if (this.regionSelect) {            this.regionSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-region-${this.regionSelect.value}`, name: 'Region', label: this.regionSelect.options[this.regionSelect.selectedIndex].text });              this.updateURLParams();              this.updatePriceDropdownCurrency();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.retailerSelect) {            this.retailerSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-merchant-${this.retailerSelect.value}`, name: 'Retailer', label: this.retailerSelect.options[this.retailerSelect.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.offerTypeSelect) {            this.offerTypeSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-offertype-${this.offerTypeSelect.value}`, name: 'Offer Type', label: this.offerTypeSelect.options[this.offerTypeSelect.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.viewModeSelect) {            this._prevViewMode = this.viewModeSelect.value;            this.viewModeSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-viewmode-${this.viewModeSelect.value}`, name: 'View Mode', label: this.viewModeSelect.options[this.viewModeSelect.selectedIndex].text });                            // Reset all active toggles and filters to prevent config carry-over              this.selectedBrands = [];              if (this.brandTrigger) this.brandTrigger.innerText = 'Select Brands';              if (this.brandDropdown) {                const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                chks.forEach(chk => { chk.checked = false; });              }              if (this.priceFilter) this.priceFilter.value = 'all';              if (this.customPriceMin) this.customPriceMin.value = '';              if (this.customPriceMax) this.customPriceMax.value = '';              if (this.sortSelect) this.sortSelect.value = 'date_desc';              if (this.discountFilter) this.discountFilter.value = '0';              if (this.retailerSelect) this.retailerSelect.value = '';              if (this.offerTypeSelect) this.offerTypeSelect.value = '';              if (this.rowsSelect) this.rowsSelect.value = '12';              if (this.categoryFilter) this.categoryFilter.value = 'all';              this.activeDealTag = null;              this.updateURLParams();              this.applyLayoutMode();                            if (this.getViewMode() === 'savings_squad' || this._prevViewMode === 'savings_squad') {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }              this._prevViewMode = this.viewModeSelect.value;            });          }                    if (this.rowsSelect) {            this.rowsSelect.addEventListener('change', () => {              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.dealModeToggle) {            this.dealModeToggle.addEventListener('change', () => {              this.updateURLParams();              this.render();            });          }          if (this.editorModeToggle) {             this.editorModeToggle.addEventListener('change', (e) => {                this.editorMode = e.target.checked;                this.render();                this.updateFloatingCopyBar();             });          }          if (this.editorCopyBtn) {             this.editorCopyBtn.addEventListener('click', () => {                this.copySelectedDealsToCMS();             });          }          if (this.editorClearBtn) {             this.editorClearBtn.addEventListener('click', () => {                this.selectedDeals.clear();                this.render();                this.updateFloatingCopyBar();             });          }          if (this.grid) {            this.grid.addEventListener('change', (e) => {               if (e.target.classList.contains('tg-df-deal-checkbox')) {                  const dealId = e.target.getAttribute('data-id');                  if (e.target.checked) {                     const dealObj = this.deals.find(d => d.id === dealId);                     if (dealObj) this.selectedDeals.set(dealId, dealObj);                  } else {                     this.selectedDeals.delete(dealId);                  }                  this.updateFloatingCopyBar();               }            });            this.grid.addEventListener('click', (e) => {              const dealCard = e.target.closest('[data-action="deal-click"]');              const similarCard = e.target.closest('[data-action="view-similar-click"]');              const cardLink = dealCard || similarCard;              if (cardLink) {                const productName = cardLink.getAttribute('data-product-name');                const merchantName = cardLink.getAttribute('data-merchant-name');                const productId = cardLink.getAttribute('data-analytics-id');                const price = parseFloat(cardLink.getAttribute('data-price')) || null;                const prevPriceStr = cardLink.getAttribute('data-previous-price');                const previousPrice = prevPriceStr ? parseFloat(prevPriceStr) : null;                const originalLink = cardLink.getAttribute('data-original-link');                const rewrittenLink = cardLink.getAttribute('href');                const revenueId = cardLink.getAttribute('data-revenue-id');                const index = parseInt(cardLink.getAttribute('data-index'), 10) || 0;                const inStock = cardLink.getAttribute('data-in-stock') === 'true';                const totalText = cardLink.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: cardLink.getAttribute('data-model-id') || null,                    matchId: cardLink.getAttribute('data-match-id') || null,                    brand: cardLink.getAttribute('data-model-brand') || null,                    parent: cardLink.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: cardLink.getAttribute('data-merchant-id') || null,                    network: cardLink.getAttribute('data-merchant-network') || null,                    url: cardLink.getAttribute('data-merchant-url') || null,                    name: merchantName                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: normalizeCurrency(this.escapeHTML(cardLink.getAttribute('data-currency') || '$'))                };                if (dealCard) {                  trackDealClick(trackingParams);                } else {                  trackViewSimilarClick(trackingParams);                }              }              const couponsBtn = e.target.closest('[data-action="coupons-click"]');              if (couponsBtn) {                trackElementInteraction({                  id: 'product-card-show-coupons',                  name: 'Coupons',                  label: `Product card coupons: ${couponsBtn.getAttribute('data-merchant')}`                });              }            });          }          this.setupScrollListeners();        }        setupScrollListeners() {          const containers = [             this.root.querySelector('.tg-df-carousel-roundels'),             this.root.querySelector('.tg-df-carousel-filters-wrap'),             this.root.querySelector('#tg-df-grid')          ];                    containers.forEach(container => {             if (!container) return;                          const checkScroll = () => {                if (!container.parentElement) return;                const leftBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-left');                const rightBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-right');                                if (leftBtn) {                   if (container.scrollLeft <= 5) leftBtn.style.display = 'none';                   else leftBtn.style.display = 'flex';                }                                if (rightBtn) {                   if (container.scrollWidth <= container.clientWidth) {                       rightBtn.style.display = 'none';                   } else if (container.scrollLeft >= container.scrollWidth - container.clientWidth - 5) {                       rightBtn.style.display = 'none';                   } else {                       rightBtn.style.display = 'flex';                   }                }             };                          container.addEventListener('scroll', checkScroll);             checkScroll();                          window.addEventListener('resize', checkScroll);                          const observer = new MutationObserver(checkScroll);             observer.observe(container, { childList: true, subtree: true, characterData: false });          });        }        get widgetTypeName() {          const mode = this.viewModeSelect ? this.viewModeSelect.value : (this.viewModeOverride || 'auto');          switch(mode) {              case 'carousel': return 'Carousel';              case 'savings_squad': return 'Savings Squad';              case 'grid': return 'Grid';              case 'row': return 'Row';              default: return 'Auto Collection';          }        }        getRowsLimit() {          if (this.rowsSelect && this.rowsSelect.value) return parseInt(this.rowsSelect.value, 10);          let configSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {             configSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {             configSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(configSource);          if (params.has('rows')) return parseInt(params.get('rows'), 10) || 12;          return 12;        }        getAreaCode() {          if (this.regionSelect && this.regionSelect.value) {            if (this.regionSelect.value === 'auto') return null;            return this.regionSelect.value;          }          let area = null;          try {            const locale = window.navigator.language || window.navigator.userLanguage;            if (locale && locale.includes('-')) {              area = locale.split('-')[1].toUpperCase();            } else if (locale && locale.length === 2) {              if (locale.toUpperCase() === 'EN') { area = 'US'; }              else { area = locale.toUpperCase(); }            }          } catch (e) { /* Ignore */ }                    // Map to known valid options or fallback to US          const valid = ['US', 'GB', 'CA', 'AU', 'DE', 'FR', 'IT'];          if (area === 'UK') area = 'GB';          if (valid.includes(area)) {             return area;          }          return 'US';        }        async fetchDeals(query) {          this.showLoading();          this.deals = [];          this.displayLimit = this.getRowsLimit();                    try {            console.log("getViewMode returns:", this.getViewMode());            if (this.getViewMode() === 'savings_squad') {               await this.fetchSavingsSquad();            } else {               if (this.isBroadQuery(query)) {                 await this.fetchAdviserDeals(query);               } else {                 await this.fetchHawkDeals(query);                 if (this.deals.length === 0) {                   await this.fetchAdviserDeals(query);                 }               }            }          } catch (error) {            console.warn("[Tom's Guide Widget] Fetch error:", error);            this.showError();          }        }        async fetchSavingsSquad() {          let topArticles = this.airedaleArticles;          if (!topArticles) {            const siteParam = this.website || 'tomsguide';            const airedaleUrl = `https://airedale.futurecdn.net/feeds/feed_1781000519267.json?site=${siteParam}&articleType=deals&limit=50`;            let res;            try {               res = await fetch(airedaleUrl);            } catch(e) {               try { res = await fetch(`https://airedale.futurecdn.net/feeds/feed_1776420579726.json?site=${siteParam}&articleType=deals&limit=50`); } catch (err) { console.warn("Fallback fetch failed", err); return; }            }            if (!res.ok) throw new Error('Airedale API Error');            const articles = await res.json();            topArticles = Array.isArray(articles) ? articles.slice(0, 50) : ((articles.data && Array.isArray(articles.data)) ? articles.data.slice(0, 50) : []);            this.airedaleArticles = topArticles;                        let tagCounts = {};            topArticles.forEach((a) => {              let articleTags = new Set();              if (a.articlecategory && Array.isArray(a.articlecategory)) {                 a.articlecategory.forEach((t) => articleTags.add(t));              }              articleTags.forEach(t => {                 tagCounts[t] = (tagCounts[t] || 0) + 1;              });            });                        this.airedaleTags = Object.keys(tagCounts).sort((a, b) => tagCounts[b] - tagCounts[a]);            this.airedaleTagCounts = tagCounts;          }                    let targetArticles = topArticles;          if (!this.activeDealTag && this.currentQuery) {             const tagMatch = this.airedaleTags.find(t => t.toLowerCase() === this.currentQuery.toLowerCase());             if (tagMatch) {                this.activeDealTag = tagMatch;             }          }          if (this.activeDealTag) {             const cleanTag = this.activeDealTag.toLowerCase().replace(/&/g, '').replace(/[^a-z0-9]+/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');             const encodedTag = encodeURIComponent(cleanTag);             const siteParam = this.website || 'tomsguide';             const url = `https://airedale.futurecdn.net/feeds/feed_1781000519267.json?site=${siteParam}&articleType=deals&limit=50&articleCategoryHandle=${encodedTag}`;             try {                const res = await fetch(url);                if (res.ok) {                   const articles = await res.json();                   targetArticles = Array.isArray(articles) ? articles.slice(0, 50) : ((articles.data && Array.isArray(articles.data)) ? articles.data.slice(0, 50) : []);                }             } catch(e) {                console.warn("Failed to fetch by activeDealTag", e);             }          }          let extractedDeals = [];          let seenUrls = new Set();                    let overallBrandsCounts = {};                    // First pass: extract ALL brands from topArticles so the dropdown has all options          topArticles.forEach((article) => {             if (!article.articlepage) return;             let pageData = [];             try { pageData = JSON.parse(article.articlepage[0]); } catch(e){ console.warn(e); }             const savingsSquad = pageData.filter((p) => p.type === 'deal' || p.type === 'featured-product');             savingsSquad.forEach((block) => {                const data = block.data || {};                if (data.brand) {                   const cleanBrand = data.brand.replace(/^\d+\.\s*/, '').trim();                   overallBrandsCounts[cleanBrand] = (overallBrandsCounts[cleanBrand] || 0) + 1;                }             });          });          targetArticles.forEach((article) => {             if (!article.articlepage) return;                          let pageData = [];             try {                pageData = JSON.parse(article.articlepage[0]);             } catch(e){ console.warn(e); }                          const savingsSquad = pageData.filter((p) => p.type === 'deal' || p.type === 'featured-product');                          savingsSquad.forEach((block, idx) => {                const data = block.data || {};                const isFeatured = block.type === 'featured-product';                                const link = data.link || {};                const priceObj = data.price || {};                const image = data.image || {};                                if (data.brand) {                   data.brand = data.brand.replace(/^\d+\.\s*/, '').trim();                }                const externalUrl = isFeatured ? data.url : (link.href || null);                let summaryTitle = isFeatured ? (data.name || data.brand) : (data.productName || link.label || article.articlename);                let description = isFeatured ? (data.strapline || '') : (data.text || '');                                if (!isFeatured && !data.productName && data.text) {                   const brSplit = data.text.split(new RegExp('\x3Cbr\\s*\\/?\\x3E', 'i'));                   if (brSplit.length > 1) {                     summaryTitle = brSplit[0].replace(/<[^>]+>/g, '').trim();                     description = brSplit.slice(1).join(' ').replace(/<br\s*\/?>/gi, ' ').replace(/<\/?(p|div)[^>]*>/gi, ' ').replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').trim();                   } else {                     const match = data.text.match(/\x3Cstrong>(.*?)<\/strong>/);                     if (match) {                       summaryTitle = match[1].replace(/<[^>]+>/g, '').trim();                       if (summaryTitle.endsWith(':')) summaryTitle = summaryTitle.slice(0, -1);                     }                   }                }                                let imageUrl = isFeatured ? image.mos : (image.src || null);                if (imageUrl && imageUrl.startsWith('//')) imageUrl = 'https:' + imageUrl;                                description = description.replace(/<br\s*\/?>/gi, ' ').replace(/<\/?(p|div)[^>]*>/gi, ' ').replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').replace(/View Deal$/i, '').trim();                                let merchantName = data.retailer || '';                if (!merchantName && externalUrl) {                   try {                     merchantName = new URL(externalUrl).hostname.replace('www.', '').split('.')[0];                     merchantName = merchantName.charAt(0).toUpperCase() + merchantName.slice(1);                   }catch(e){ console.warn(e); }                }                if (!merchantName) merchantName = 'Retailer';                const q = (this.currentQuery || '').toLowerCase();                const activeTagLogic = (this.activeDealTag || '').toLowerCase();                if (q.length > 2 && q !== activeTagLogic) {                   const searchTarget = `${summaryTitle || ''} ${description || ''}`.toLowerCase();                   if (!searchTarget.includes(q)) return;                }                let rawPrice = 0;                let rawMsrp = 0;                let currencyStr = '$';                if (isFeatured) {                   rawPrice = typeof data.salePrice === 'number' && data.salePrice > 0 ? data.salePrice : (typeof data.price === 'number' ? data.price : 0);                   rawMsrp = typeof data.salePrice === 'number' && typeof data.price === 'number' && data.price > data.salePrice ? data.price : 0;                   currencyStr = data.currency === 'GBP' ? '£' : '$';                } else {                   rawPrice = priceObj.amount ? parseFloat(priceObj.amount) : 0;                   rawMsrp = priceObj.amountWas ? parseFloat(priceObj.amountWas) : 0;                   currencyStr = priceObj.currency === 'GBP' ? '£' : '$';                }                                let savingAmt = 0;                let savingLabel = '';                if (rawPrice > 0 && rawMsrp > rawPrice) {                   savingAmt = parseFloat((rawMsrp - rawPrice).toFixed(2));                   savingLabel = `Save ${currencyStr}${savingAmt}`;                }                                // Apply Brand filter                if (this.selectedBrands && this.selectedBrands.length > 0) {                   const itemBrand = (data.brand || '').toLowerCase();                   const hasMatch = this.selectedBrands.some(sb => sb.toLowerCase() === itemBrand);                   if (!hasMatch) return;                }                // Apply Price filter                let priceFilterVal = null;                const min = this.customPriceMin ? this.customPriceMin.value : '';                const max = this.customPriceMax ? this.customPriceMax.value : '';                if (min || max) {                   priceFilterVal = `${min}_${max}`;                } else if (this.priceFilter && this.priceFilter.value !== 'all') {                   priceFilterVal = this.priceFilter.value;                }                if (priceFilterVal && rawPrice > 0) {                   if (priceFilterVal === 'under50' && rawPrice >= 50) return;                   if (priceFilterVal === 'over50' && rawPrice <= 50) return;                   if (priceFilterVal === 'over30' && rawPrice <= 30) return;                   if (priceFilterVal === 'over500' && rawPrice <= 500) return;                   if (priceFilterVal.includes('_')) {                      const parts = priceFilterVal.split('_');                      const min = parseFloat(parts[0]);                      const max = parseFloat(parts[1]);                      if (!isNaN(min) && rawPrice < min) return;                      if (!isNaN(max) && rawPrice > max) return;                   }                }                // Apply Discount filter                if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {                   const requiredDiscount = parseInt(this.discountFilter.value);                   if (!isNaN(requiredDiscount) && requiredDiscount > 0) {                      if (!rawMsrp || rawMsrp <= rawPrice) return;                      const ratio = Math.round((1 - (rawPrice / rawMsrp)) * 100);                      if (ratio < requiredDiscount) return;                   }                }                                if (externalUrl) {                   if (seenUrls.has(externalUrl)) return;                  seenUrls.add(externalUrl);                }                                extractedDeals.push({                   id: `airedale-${article.id || Math.random()}-${idx}`,                   url: externalUrl,                   image: imageUrl,                   fallbackImage: imageUrl,                   title: summaryTitle,                   brand: data.brand || '',                   productName: data.productName || '',                   merchant: merchantName,                   rawPrice: rawPrice,                   rawMsrp: rawMsrp,                   price: rawPrice > 0 ? rawPrice.toString() : '',                   msrp: rawMsrp > 0 ? rawMsrp.toString() : '',                   currency: currencyStr,                   isCheckPrice: !rawPrice,                   savingLabel: savingLabel,                   savingType: rawMsrp > rawPrice ? 'amount' : 'none',                   isPrime: false,                   starRating: null,                   description: description,                   text: data.text || '',                   authorName: article.articleauthortext ? article.articleauthortext[0] : (article.articleauthor ? article.articleauthor[0] : ''),                   authorRole: article.articleauthorrole ? article.articleauthorrole[0] : '',                   authorImage: article.articleauthormedia ? article.articleauthormedia[0] : '',                   documentUrl: article.documenturl ? article.documenturl[0] : '',                   modifiedDate: article.contentmodifieddate || article.modifieddate || ''                });             });          });                    const airedaleBrandsList = Object.keys(overallBrandsCounts).map(b => ({              formatted_value: b,              count: overallBrandsCounts[b]          })).sort((a,b) => b.count - a.count);                    if (this.getViewMode() === 'savings_squad') {             this.populateBrandDropdown(airedaleBrandsList.slice(0, 15));             if (this.brandFilterWrapper) {                if (airedaleBrandsList.length === 0) {                    this.brandFilterWrapper.style.display = 'none';                } else {                    this.brandFilterWrapper.style.display = 'flex';                }             }          }                    this.deals = extractedDeals;          this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        isBroadQuery(query) {          const q = query.toLowerCase();          const intentModifiers = ['deals', 'best', 'sale', 'under', 'cheap', 'offers', 'discount'];          return intentModifiers.some(term => q.includes(term));        }        async fetchHawkDeals(query) {          const url = new URL(this.apiUrl);          url.searchParams.append('model_name', query);          const areaCode = this.getAreaCode();          if (areaCode) {            url.searchParams.append('area', areaCode);          }                    if (this.retailerSelect && this.retailerSelect.value) {            url.searchParams.append('filter_merchant_name', this.retailerSelect.value);          }                    if (this.selectedBrands && this.selectedBrands.length > 0) {            url.searchParams.append('filter_label[text_brand]', this.selectedBrands.join(','));          }                    let priceVal = null;          const min = this.customPriceMin ? this.customPriceMin.value : '';          const max = this.customPriceMax ? this.customPriceMax.value : '';          if (min || max) {             priceVal = `${min}_${max}`;          } else if (this.priceFilter && this.priceFilter.value !== 'all') {             priceVal = this.priceFilter.value;          }          if (priceVal) {            if (priceVal === 'under50') {              url.searchParams.append('filter_max_price', '50');            } else if (priceVal === 'over50') {              url.searchParams.append('filter_min_price', '50');            } else if (priceVal === 'over30') {              url.searchParams.append('filter_min_price', '30');            } else if (priceVal === 'over500') {              url.searchParams.append('filter_min_price', '500');            } else if (priceVal.includes('_')) {              const parts = priceVal.split('_');              if (parts[0]) url.searchParams.append('filter_min_price', parts[0]);              if (parts[1]) url.searchParams.append('filter_max_price', parts[1]);            }          }                    if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {            const v = parseInt(this.discountFilter.value);            if (!isNaN(v) && v > 0) {              const ratio = (100 - v) / 100;              url.searchParams.append('min_discount_ratio', ratio.toString());            }          }                    if (this.offerTypeSelect && this.offerTypeSelect.value) {            url.searchParams.append('offer', this.offerTypeSelect.value);          }                    url.searchParams.append('filter_product_types', 'deals');                    url.searchParams.append('rows', this.getRowsLimit().toString());          let response;          try {             response = await fetch(url.toString());          } catch(e) {             if (window.location.protocol === 'file:') {                console.warn("[Tom's Guide Widget] fetch from file:// blocked by local CORS policy, falling back to Adviser mock.");                await this.fetchAdviserDeals(query);                return;             }             console.warn("Hawk fetch failed", e);             this.deals = [];             this.render();             return;          }          if (!response.ok) {            throw new Error('Hawk API Response Error');          }          const rawData = await response.json();          // Safely locate data array from potentially wrapped response          let offers = [];          let modelInfoArray = [];                    let brandFilterData = null;          if (rawData && rawData.widget && rawData.widget.data && Array.isArray(rawData.widget.data.filters)) {             brandFilterData = rawData.widget.data.filters.find(f => f.type === 'label_text_brand');          } else if (rawData && rawData.data && Array.isArray(rawData.data.filters)) {             brandFilterData = rawData.data.filters.find(f => f.type === 'label_text_brand');          }          if (brandFilterData && Array.isArray(brandFilterData.values) && brandFilterData.values.length > 0) {             this.populateBrandDropdown(brandFilterData.values);          } else {             if (this.brandFilterWrapper && this.selectedBrands.length === 0) {                this.brandFilterWrapper.style.display = 'none';             }          }                    if (rawData && rawData.widget && rawData.widget.data) {            if (Array.isArray(rawData.widget.data.offers)) offers = rawData.widget.data.offers;            if (rawData.widget.data.model_info && typeof rawData.widget.data.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.widget.data.model_info) ? rawData.widget.data.model_info : Object.values(rawData.widget.data.model_info);            }          } else if (rawData && rawData.data) {            if (Array.isArray(rawData.data.offers)) offers = rawData.data.offers;            if (rawData.data.model_info && typeof rawData.data.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.data.model_info) ? rawData.data.model_info : Object.values(rawData.data.model_info);            }          } else {            if (Array.isArray(rawData)) offers = rawData;            else if (rawData && Array.isArray(rawData.offers)) offers = rawData.offers;            else if (rawData && rawData.offers && Array.isArray(rawData.offers.offer)) offers = rawData.offers.offer;            else if (rawData && rawData.offers) offers = [].concat(rawData.offers);                        if (rawData && rawData.model_info && typeof rawData.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.model_info) ? rawData.model_info : Object.values(rawData.model_info);            }          }          let modelDetails = {};          modelInfoArray.forEach(m => {            const mId = m.model_id || m.id;            if (mId) {              modelDetails[mId] = {                score: m.score != null ? parseFloat(m.score) : null,                brand: m.brand || null,                parent: (m.parents && Array.isArray(m.parents) && m.parents.length > 0) ? m.parents[0].name : null              };            }          });          offers.forEach(item => {            let data = { ...item };            const mId = data.model_id;            if (mId && modelDetails[mId]) {              data.review_score = modelDetails[mId].score;              data.model_brand = modelDetails[mId].brand;              data.model_parent = modelDetails[mId].parent;            } else {              data.review_score = null;            }                        let itemOffers = [];            if (Array.isArray(item.offers)) itemOffers = item.offers;            else if (Array.isArray(item.offer)) itemOffers = item.offer;            else if (item.offers && typeof item.offers === 'object') itemOffers = [item.offers];            else if (item.offer && typeof item.offer === 'object') itemOffers = [item.offer];            if (itemOffers.length > 0) {              itemOffers.forEach(subItem => {                let subData = { ...item, ...subItem };                const subId = subData.model_id;                if (subId && modelDetails[subId]) {                  subData.review_score = modelDetails[subId].score;                  subData.model_brand = modelDetails[subId].brand;                  subData.model_parent = modelDetails[subId].parent;                } else if (data.review_score != null) {                  subData.review_score = data.review_score;                }                if (subData.merchant && typeof subData.merchant === 'object') {                  subData.merchant_name = subData.merchant.name;                }                this.deals.push(this.extractDealData(subData));              });              return;            }                        if (item.merchant && typeof item.merchant === 'object') {              data.merchant_name = item.merchant.name;            }                        this.deals.push(this.extractDealData(data));          });                    this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        async fetchAdviserDeals(query) {          // ======================================================================          // TODO: ADVISER API REPLACEMENT          // The code below simulates the Adviser API response using mock data.          // Once the real endpoint is ready, remove getAdviserMockData() and           // perform an actual fetch() request similar to fetchHawkDeals().          // Example:          // const area = this.getAreaCode();          // let apiUrl = `https://your-adviser-api.com/search?q=${query}&area=${area}`;          // if (this.priceFilter && this.priceFilter.value !== 'all') {          //   const val = this.priceFilter.value;          //   if (val === 'under50') apiUrl += '&filter_max_price=50';          //   else if (val === '50_100') apiUrl += '&filter_max_price=100';          //   else if (val === '100_200') apiUrl += '&filter_max_price=200';          //   else if (val === '200_500') apiUrl += '&filter_max_price=500';          // }          // const res = await fetch(apiUrl);          // const rawData = await res.json();          // ======================================================================          // Simulating network latency          await new Promise(resolve => setTimeout(resolve, 400));                    const rawData = this.getAdviserMockData();          let offers = [];                    if (rawData && rawData.data && rawData.data.Get && Array.isArray(rawData.data.Get.Deal)) {            offers = rawData.data.Get.Deal;          }                    // Basic client-side filtering for the mock if we want it to react to the query          const q = query.toLowerCase();          const selectedRetailer = (this.retailerSelect && this.retailerSelect.value) ? this.retailerSelect.value.toLowerCase() : null;                    offers.forEach(item => {            const dataObj = item;                        // Apply retailer filter            const itemRetailer = (dataObj.dataRetailer || '').toLowerCase();            if (selectedRetailer && itemRetailer !== selectedRetailer && !itemRetailer.includes(selectedRetailer)) {              return;            }                        // Apply mock price filter            let price = dataObj.dataDiscountedPrice || 0;            if (typeof price === 'string') {              price = parseFloat(price.replace(/[^0-9.]/g, ''));            }            let priceVal = null;            const min = this.customPriceMin ? this.customPriceMin.value : '';            const max = this.customPriceMax ? this.customPriceMax.value : '';            if (min || max) {               priceVal = `${min}_${max}`;            } else if (this.priceFilter && this.priceFilter.value !== 'all') {               priceVal = this.priceFilter.value;            }            if (priceVal) {              if (priceVal === 'under50' && price >= 50) return;              if (priceVal === 'over50' && price <= 50) return;              if (priceVal === 'over30' && price <= 30) return;              if (priceVal === 'over500' && price <= 500) return;              if (priceVal.includes('_')) {                 const parts = priceVal.split('_');                 if (parts[0] && price < parseFloat(parts[0])) return;                 if (parts[1] && price > parseFloat(parts[1])) return;              }            }                        // Map Adviser schema to our widget's expected schema            const mappedData = {              url: dataObj.linkHREF || dataObj.dataLink || '#',              image: dataObj.imageURL || (dataObj.image && dataObj.image.src) || '',              title: dataObj.dataProduct || (dataObj.product && dataObj.product.name) || 'Product Deal',              merchant: dataObj.dataRetailer || 'Retailer',              price: dataObj.dataDiscountedPrice || 0,              currency: dataObj.dataCurrency === 'USD' ? '$' : (dataObj.dataCurrency || '$'),              msrp: dataObj.dataOriginalPrice || null            };                        const titleLow = mappedData.title.toLowerCase();            const merchLow = mappedData.merchant.toLowerCase();                        // Smarter mock filtering            let isMatch = false;            if (q === '' || this.isBroadQuery(q)) {              isMatch = true;            } else if (titleLow.includes(q) || merchLow.includes(q)) {              isMatch = true;            } else if ((q.includes('laptop') || q.includes('mac') || q.includes('pc')) && (titleLow.includes('macbook') || titleLow.includes('laptop'))) {              isMatch = true;            } else if ((q.includes('tv') || q.includes('television')) && (titleLow.includes('tv') || titleLow.includes('oled') || titleLow.includes('qled'))) {              isMatch = true;            } else if ((q.includes('phone') || q.includes('smartphone')) && (titleLow.includes('galaxy') || titleLow.includes('phone'))) {              isMatch = true;            } else if ((q.match(/watch|fitness|run|shoe/)) && (titleLow.includes('forerunner') || titleLow.includes('saucony') || titleLow.includes('watch'))) {              isMatch = true;            }                        if (isMatch) {               this.deals.push(this.extractDealData(mappedData));            }          });                    let rowLimit = this.getRowsLimit();          // Intentionally omitting the slice here to allow "Load More" to work if the API returns more                    this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        getAdviserMockData() {          return {            "data": {              "Get": {                "Deal": [                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 300,                    "dataOriginalPrice": 399,                    "dataProduct": "Samsung Galaxy A36",                    "dataRetailer": "Samsung",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/MqDYsukV3JBG54te6dEs7j.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 14,                    "dataOriginalPrice": 24,                    "dataProduct": "Blink Mini",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/3JurmAjHsDa5tPdaHAwEV8.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 59,                    "dataOriginalPrice": 99,                    "dataProduct": "Ring Video Doorbell",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/rAh4uR7AsAsALCCLTXnLNJ.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 10,                    "dataOriginalPrice": 599,                    "dataProduct": "MacBook Neo",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/Lg4Dvg68j9SbB5CPNrTEpH.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 749,                    "dataOriginalPrice": 849,                    "dataProduct": "65\\\" Fire TV Omni 4K QLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/SG34ZWodUkLTxJvMTbjPYR.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 71,                    "dataOriginalPrice": 160,                    "dataProduct": "Saucony Hurricane 24",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/vxf7UD5T2Am7guVzFoFcZ4.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 649,                    "dataOriginalPrice": 749,                    "dataProduct": "Garmin Forerunner 970",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/3GKnEu7CdhtxPMfnPCMCiA.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1049,                    "dataOriginalPrice": 1499,                    "dataProduct": "LG 48\\\" C4 4K OLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/imvwZV9zoMD6fn9Afuge35.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1499,                    "dataOriginalPrice": 2199,                    "dataProduct": "Samsung 49\\\" Odyssey Neo G9 4K Gaming Monitor",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/XWDEJ5dUAE2nhK8k3Jk7k7.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 299,                    "dataOriginalPrice": 699,                    "dataProduct": "EGOHOME Black Memory Foam Mattress (queen)",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/hMUemtAejNETLVYxNrktzm.jpg"                  }                ]              }            }          };        }        decodeHTML(html) {          if (!html) return '';          const txt = document.createElement("textarea");          txt.innerHTML = String(html);          return txt.value;        }        extractDealData(item) {          const priceRawStr = String(item.price || item.current_price || '0');          const msrpRawStr = String(item.was_price || item.msrp || item.original_price || '0');          const rawPrice = parseFloat(priceRawStr.replace(/[^\d.]/g, '')) || 0;          const rawMsrp = parseFloat(msrpRawStr.replace(/[^\d.]/g, '')) || 0;          const isCheckPrice = rawPrice === 0 || priceRawStr === '0.00' || priceRawStr === '0';                    let originalImageUrl = item.image || item.image_url || item.product_image || '';          let imageUrl = originalImageUrl;          if ((!imageUrl || isCheckPrice) && item.model_image_url) {             imageUrl = item.model_image_url;             originalImageUrl = imageUrl;          } else if ((!imageUrl || isCheckPrice) && item.model_image) {             imageUrl = item.model_image;             originalImageUrl = imageUrl;          }                    if (imageUrl) {            imageUrl = imageUrl.replace(/-(\d+)-(\d+)(\.[a-z.]+)$/i, '$3');          }                    let fallbackImage = '';          if (originalImageUrl && originalImageUrl !== imageUrl) {             fallbackImage = originalImageUrl;          } else if (item.model_image && item.model_image !== imageUrl) {             fallbackImage = item.model_image;          } else if (item.model_image_url && item.model_image_url !== imageUrl) {             fallbackImage = item.model_image_url;          }                    const rawCurrency = item.currency || item.currency_symbol || '$';                    let savingLabel = item.percentage_saving_label || '';          if (!savingLabel && rawMsrp > rawPrice && rawPrice > 0) {            const pct = Math.round(((rawMsrp - rawPrice) / rawMsrp) * 100);            if (pct > 0) {              savingLabel = `${pct}% OFF`;            }          }                    const isPrime = item.shipping && item.shipping.prime === true;                    let scoreRaw = (item.review_score !== undefined && item.review_score !== null && item.review_score > 0) ? parseFloat(item.review_score) : null;          let starRating = 0;          if (scoreRaw !== null) {            starRating = Math.round((scoreRaw > 10 ? scoreRaw / 20 : scoreRaw / 2) * 2) / 2;          }                    return {            id: item.offer_id || item.link || item.url || item.offer_link || Math.random().toString(),            url: item.link || item.url || item.offer_link || '#',            image: imageUrl,            fallbackImage: fallbackImage,            title: item.name || item.title || item.model_name || item.product_name || 'Unknown Product',            brand: item.brand || '',            productName: item.model_name || item.product_name || item.name || '',            merchant: item.merchant_name || item.merchant || item.retailer || 'Retailer',            price: item.price !== undefined ? String(item.price) : '0.00',            currency: this.decodeHTML(rawCurrency),            msrp: item.was_price || item.msrp || item.original_price || null,            rawPrice: rawPrice,            rawMsrp: rawMsrp,            hasWasPrice: (item.was_price !== undefined && item.was_price !== null),            isCheckPrice: isCheckPrice,            savingLabel: savingLabel,            isPrime: isPrime,            starRating: starRating > 0 ? starRating : null,            modelId: item.model_id || '',            productKey: item.product_key || '',            merchantId: (item.merchant && typeof item.merchant === 'object') ? item.merchant.id || '' : '',            matchId: item.match_id || '',            merchantNetwork: (item.merchant && typeof item.merchant === 'object') ? item.merchant.an || '' : '',            merchantUrl: (item.merchant && typeof item.merchant === 'object') ? item.merchant.url || '' : '',            modelBrand: item.model_brand || item.brand || '',            modelParent: item.model_parent || ''          };        }        sortData() {          const sortVal = this.sortSelect ? this.sortSelect.value : 'date_desc';          if (sortVal === 'price_asc') {            this.deals.sort((a, b) => a.rawPrice - b.rawPrice);          } else if (sortVal === 'price_desc') {            this.deals.sort((a, b) => b.rawPrice - a.rawPrice);          } else if (sortVal === 'discount_desc') {            this.deals.sort((a, b) => {              const aDiscount = a.rawMsrp > a.rawPrice ? (a.rawMsrp - a.rawPrice) : 0;              const bDiscount = b.rawMsrp > b.rawPrice ? (b.rawMsrp - b.rawPrice) : 0;              return bDiscount - aDiscount;            });          } else if (sortVal === 'date_desc') {             this.deals.sort((a, b) => {                let dateA = 0;                let dateB = 0;                if (a && a.modifiedDate) {                   const valA = Array.isArray(a.modifiedDate) ? a.modifiedDate[0] : a.modifiedDate;                   dateA = new Date(valA).getTime();                   if (isNaN(dateA)) dateA = 0;                }                if (b && b.modifiedDate) {                   const valB = Array.isArray(b.modifiedDate) ? b.modifiedDate[0] : b.modifiedDate;                   dateB = new Date(valB).getTime();                   if (isNaN(dateB)) dateB = 0;                }                return dateB - dateA;             });          }        }        getFilteredDeals() {          let filteredDeals = [...this.deals];                    if (this.dealModeToggle && this.dealModeToggle.checked) {            filteredDeals = filteredDeals.filter(d => d.hasWasPrice || (d.msrp && d.rawMsrp > d.rawPrice));          }                    return filteredDeals;        }        showLoading() {          const _div = '<' + '/div>';          const skeletonCardHtml = `            \x3Cdiv class="tg-df-card">              \x3Cdiv class="tg-df-card-image-box">                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-img">${_div}              ${_div}              \x3Cdiv class="tg-df-card-body">                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short">${_div}                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text title">${_div}                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text title">${_div}                \x3Cdiv class="tg-df-card-footer mt-auto">                  \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="height:24px;">${_div}                ${_div}              ${_div}              \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text" style="height:44px; margin:0; border-radius:0;">${_div}            ${_div}`;          this.grid.innerHTML = Array(4).fill(skeletonCardHtml).join('');        }        showError() {          const _div = '<' + '/div>';          this.grid.innerHTML = `\x3Cdiv class="tg-df-message">            An error occurred while finding deals. Please check your connection and try again.          ${_div}`;        }        escapeHTML(str) {          if (!str) return '';          return String(str).replace(/[&<>'"]/g, tag => ({              '&': '&', '<': '<', '>': '>', "'": ''', '"': '"'          }[tag] || tag));        }                bindCouponButtons() {          const btns = this.root.querySelectorAll('.tg-df-tag-coupons');          btns.forEach(btn => {            btn.addEventListener('click', (e) => {              e.preventDefault();              e.stopPropagation();              const merchant = btn.getAttribute('data-merchant');              this.openVouchersModal(merchant);            });          });                    const closeBtn = this.root.querySelector('#tg-df-vouchers-close');          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          if (closeBtn) {            closeBtn.onclick = () => this.closeVouchersModal();          }          if (backdrop) {            backdrop.onclick = (e) => {              if (e.target === backdrop) this.closeVouchersModal();            };          }        }                closeVouchersModal() {          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          if (backdrop) backdrop.classList.remove('active');        }                async checkMerchantsCouponsBulk(merchants) {          if (!merchants || merchants.length === 0) return {};          const controller = new AbortController();          const timeoutId = setTimeout(() => controller.abort(), 4000);          try {            const area = this.getAreaCode();            const url = new URL('https://search-api.fie.future.net.uk/widget.php');            url.searchParams.append('model_name', 'Everything');            url.searchParams.append('language', 'en-GB');            if (area) url.searchParams.append('area', area);            url.searchParams.append('combine_product_types', '1');            url.searchParams.append('filter_merchant_name', merchants.join(','));            url.searchParams.append('all_filters', 'false');            url.searchParams.append('exclude_unlabelled', 'false');            url.searchParams.append('include_specs', 'false');            url.searchParams.append('sort', 'voucher');            url.searchParams.append('distinct_merchants', 'natural');            url.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');            url.searchParams.append('rows', '120');            url.searchParams.append('origin', 'widgets-clientside');                        let res; try { res = await fetch(url.toString(), { signal: controller.signal }); } catch (e) { return {}; }            clearTimeout(timeoutId);            if (!res.ok) return {};            const data = await res.json();                        let offers = [];            if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {              offers = data.widget.data.offers;            } else if (data && data.data && Array.isArray(data.data.offers)) {              offers = data.data.offers;            } else if (Array.isArray(data)) {              offers = data;            } else if (data && Array.isArray(data.offers)) {              offers = data.offers;            } else if (data && data.offers && Array.isArray(data.offers.offer)) {              offers = data.offers.offer;            } else if (data && Array.isArray(data.data)) {              offers = data.data;            }                        const foundMerchants = new Set();            offers.forEach(o => {              let mName = o.merchant_name || o.merchant || o.retailer;              if (mName && typeof mName === 'object') mName = mName.name;              if (mName) foundMerchants.add(String(mName).toLowerCase());            });            const resultMap = {};            merchants.forEach(m => {              if (m) resultMap[m] = foundMerchants.has(String(m).toLowerCase());            });            return resultMap;          } catch (e) {            return {};          }        }                async openVouchersModal(merchantName) {          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          const title = this.root.querySelector('#tg-df-vouchers-title');          const content = this.root.querySelector('#tg-df-vouchers-content');                    if (!backdrop || !content) return;                    // HACK: Hide closing tags          const _div = '<' + '/div>';          const _span = '<' + '/span>';          const _a = '<' + '/a>';          const _h4 = '<' + '/h4>';          const _svg = '<' + '/svg>';          const _circle = '<' + '/circle>';          const _polyline = '<' + '/polyline>';          const _rect = '<' + '/rect>';          const _path = '<' + '/path>';                    title.innerText = `${merchantName} Coupons & Deals`;          content.innerHTML = `\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text">${_div}                               \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text">${_div}`;          backdrop.classList.add('active');                    try {            const area = this.getAreaCode();            const url = new URL('https://search-api.fie.future.net.uk/widget.php');            url.searchParams.append('model_name', 'Everything');            url.searchParams.append('language', 'en-GB');            if (area) url.searchParams.append('area', area);            url.searchParams.append('combine_product_types', '1');            url.searchParams.append('filter_merchant_name', merchantName);            url.searchParams.append('all_filters', 'false');            url.searchParams.append('exclude_unlabelled', 'false');            url.searchParams.append('include_specs', 'false');            url.searchParams.append('sort', 'voucher');            url.searchParams.append('distinct_merchants', 'natural');            url.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');            url.searchParams.append('rows', '50');            url.searchParams.append('origin', 'widgets-clientside');                        const res = await fetch(url.toString());            if (!res.ok) throw new Error('API Error');            const data = await res.json();                        let offers = [];            if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {              offers = data.widget.data.offers;            } else if (data && data.data && Array.isArray(data.data.offers)) {              offers = data.data.offers;            } else if (Array.isArray(data)) {              offers = data;            } else if (data && Array.isArray(data.offers)) {              offers = data.offers;            } else if (data && data.offers && Array.isArray(data.offers.offer)) {              offers = data.offers.offer;            } else if (data && Array.isArray(data.data)) {              offers = data.data;            }                        if (offers.length === 0) {              content.innerHTML = `\x3Cdiv class="tg-df-message">No vouchers currently available for ${this.escapeHTML(merchantName)}.${_div}`;              return;            }                        content.innerHTML = offers.map((v, idx) => {              let offerObj = v;              if (v.offers && v.offers.offer) {                offerObj = Array.isArray(v.offers.offer) ? v.offers.offer[0] : v.offers.offer;              } else if (v.offer) {                offerObj = Array.isArray(v.offer) ? v.offer[0] : v.offer;              }              let logoUrl = v.logo_url || offerObj.logo_url || '';              if (!logoUrl && v.merchant) {                if (Array.isArray(v.merchant) && v.merchant.length > 0) logoUrl = v.merchant[0].logo_url || '';                else logoUrl = v.merchant.logo_url || '';              }                            const offerName = offerObj.name || offerObj.title || v.name || v.title || 'Special Offer';              const endTime = offerObj.end_time || v.end_time || '';              const linkUrl = offerObj.link || offerObj.url || v.link || v.url || '#';                            let foundVoucherCode = '';              const findVoucherCode = (obj) => {                if (!obj || typeof obj !== 'object') return;                if (obj.type === 'voucher_code' && obj.display_value) {                  foundVoucherCode = obj.display_value;                  return;                }                if (Array.isArray(obj)) {                  for (const item of obj) {                    findVoucherCode(item);                    if (foundVoucherCode) return;                  }                } else {                  for (const k in obj) {                    if (Object.prototype.hasOwnProperty.call(obj, k)) {                      findVoucherCode(obj[k]);                      if (foundVoucherCode) return;                    }                  }                }              };              findVoucherCode(offerObj);              if (!foundVoucherCode) findVoucherCode(v);                            const voucherCode = foundVoucherCode || offerObj.voucher_code || v.voucher_code || '';              const codeHtml = voucherCode ? `\x3Cspan class="tg-df-voucher-code" data-action="copy-code" data-code="${this.escapeHTML(voucherCode)}" title="Copy to clipboard">                \x3Cspan class="tg-df-voucher-code-text">${this.escapeHTML(voucherCode)}${_span}                \x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-left:6px;flex-shrink:0;" class="tg-df-voucher-copy-icon">                  \x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2">${_rect}                  \x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">${_path}                ${_svg}              ${_span}` : '';                            const logoHtml = logoUrl                 ? `\x3Cimg src="${this.escapeHTML(logoUrl)}" alt="${this.escapeHTML(offerName)}" class="tg-df-voucher-logo" />`                 : `\x3Cdiv class="tg-df-voucher-logo" style="background:#e2e8f0;">${_div}`;                            let expiryHtml = '';              if (endTime) {                let dStr = endTime;                if (!isNaN(dStr) && String(dStr).length === 10) dStr = Number(dStr) * 1000;                const d = new Date(dStr);                if (!isNaN(d.getTime())) {                  const options = { year: 'numeric', month: 'short', day: 'numeric' };                  expiryHtml = `                    \x3Cdiv class="tg-df-voucher-expiry">                      \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">                        \x3Ccircle cx="12" cy="12" r="10">${_circle}                        \x3Cpolyline points="12 6 12 12 16 14">${_polyline}                      ${_svg}                      Expires ${d.toLocaleDateString(undefined, options)}                    ${_div}`;                }              }              const revenueIdVal = generateRevenueId(linkUrl, offerName, merchantName, null);              const rewrittenLinkUrl = rewriteAffiliateLink(linkUrl, area, revenueIdVal);              return `                \x3Ca href="${this.escapeHTML(rewrittenLinkUrl)}" target="_blank" rel="noopener nofollow" class="tg-df-voucher-item"                  data-action="voucher-click"                  data-product-name="${this.escapeHTML(offerName)}"                  data-merchant-name="${this.escapeHTML(merchantName)}"                  data-analytics-id="${this.escapeHTML(offerObj.offer_id || offerObj.id || v.id || '')}"                  data-price=""                  data-previous-price=""                  data-original-link="${this.escapeHTML(linkUrl)}"                  data-revenue-id="${revenueIdVal}"                  data-index="${idx}"                  data-total="${offers.length}"                  data-in-stock="true"                  data-currency="USD"                  data-model-id="${this.escapeHTML(offerObj.model_id || v.model_id || offerObj.id || v.id || '')}"                  data-merchant-id="${this.escapeHTML(offerObj.merchant_id || offerObj.merchant?.id || '')}"                >                  ${logoHtml}                  \x3Cdiv class="tg-df-voucher-content">                    \x3Ch4 class="tg-df-voucher-title">${this.escapeHTML(offerName)}${_h4}                    ${codeHtml}                    ${expiryHtml}                  ${_div}                ${_a}              `;            }).join('');                        // Attach copy functionality            const copyBtns = content.querySelectorAll('[data-action="copy-code"]');            copyBtns.forEach(btn => {              btn.addEventListener('click', async (e) => {                e.preventDefault();                e.stopPropagation();                                const code = btn.getAttribute('data-code');                if (!code) return;                                try {                  const copyToClipboard = async (text) => {                     if (window.navigator.clipboard && window.isSecureContext) {                        try { await window.navigator.clipboard.writeText(text); return; } catch (e) {}                     }                     const textArea = document.createElement("textarea");                     textArea.value = text;                     textArea.style.position = "fixed";                     document.body.appendChild(textArea);                     textArea.focus();                     textArea.select();                     document.execCommand('copy');                     textArea.remove();                  };                  await copyToClipboard(code);                                    // Visual feedback                  btn.classList.add('copied');                  const textSpan = btn.querySelector('.tg-df-voucher-code-text');                  const iconSvg = btn.querySelector('.tg-df-voucher-copy-icon');                                    const origText = textSpan.innerText;                  const origIcon = iconSvg.innerHTML;                                    textSpan.innerText = 'Copied!';                  iconSvg.innerHTML = `\x3Cpolyline points="20 6 9 17 4 12">${_polyline}`;                                    setTimeout(() => {                    if (btn) {                      btn.classList.remove('copied');                      if (textSpan) textSpan.innerText = origText;                      if (iconSvg) iconSvg.innerHTML = origIcon;                    }                  }, 2000);                                    trackElementInteraction({                    id: 'voucher-code-copy',                    name: 'Copy Voucher Code',                    label: `Copied ${code} for ${merchantName}`                  });                } catch (err) {                  console.warn('Failed to copy text: ', err);                }              });            });            // Attach voucher click tracking            const voucherBtns = content.querySelectorAll('[data-action="voucher-click"]');            voucherBtns.forEach(btn => {              btn.addEventListener('click', (e) => {                if (e.target.closest('[data-action="copy-code"]')) return;                                const productName = btn.getAttribute('data-product-name');                const merchantNameAttr = btn.getAttribute('data-merchant-name');                const productId = btn.getAttribute('data-analytics-id');                const price = parseFloat(btn.getAttribute('data-price')) || null;                const prevPriceStr = btn.getAttribute('data-previous-price');                const previousPrice = prevPriceStr ? parseFloat(prevPriceStr) : null;                const originalLink = btn.getAttribute('data-original-link');                const rewrittenLink = btn.getAttribute('href');                const revenueId = btn.getAttribute('data-revenue-id');                const index = parseInt(btn.getAttribute('data-index'), 10) || 0;                const inStock = btn.getAttribute('data-in-stock') === 'true';                const totalText = btn.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: btn.getAttribute('data-model-id') || null,                    matchId: btn.getAttribute('data-match-id') || null,                    brand: btn.getAttribute('data-model-brand') || null,                    parent: btn.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: btn.getAttribute('data-merchant-id') || null,                    network: btn.getAttribute('data-merchant-network') || null,                    url: btn.getAttribute('data-merchant-url') || null,                    name: merchantNameAttr                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: btn.getAttribute('data-currency') || 'USD'                };                if (typeof trackDealClick === 'function') {                  trackDealClick(trackingParams);                }              });            });                                  } catch (e) {            console.warn(e);            content.innerHTML = `\x3Cdiv class="tg-df-message">Failed to load vouchers.${_div}`;          }        }        render() {          try {            if (this.getViewMode() === 'savings_squad' && this.airedaleTags.length > 0) {              if (this.categoryFilterWrapper) {                 this.categoryFilterWrapper.style.display = 'flex';              }              if (this.categoryFilter) {                 const _option = '<' + '/option>';                 let optionsHtml = `\x3Coption value="all">All Categories${_option}`;                 this.airedaleTags.forEach(tag => {                    const isSelected = this.activeDealTag === tag ? 'selected' : '';                    optionsHtml += `\x3Coption value="${this.escapeHTML(tag)}" ${isSelected}>${this.escapeHTML(tag)}${_option}`;                 });                 this.categoryFilter.innerHTML = optionsHtml;                 this.categoryFilter.value = this.activeDealTag || 'all';              }            } else {               if (this.categoryFilterWrapper) {                  this.categoryFilterWrapper.style.display = 'none';               }            }            const displayDeals = this.getFilteredDeals();          // HACK: Hide closing tags from the CMS HTML sanitizer so it doesn't strip them during in-page injection          const _div = '<' + '/div>';          const _span = '<' + '/span>';          const _a = '<' + '/a>';          const _h3 = '<' + '/h3>';          const _p = '<' + '/p>';          const _strong = '<' + '/strong>';          const _sup = '<' + '/sup>';          const _button = '<' + '/button>';          if (displayDeals.length === 0) {            if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {              if (this.deals.length > 0) {                 this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                  No deals match your selected filters.                ${_div}`;              } else if (this.getViewMode() === 'savings_squad' && this.currentQuery.length <= 2) {                 // Do not show "no exact matches" if query is empty for savings_squad                 this.grid.innerHTML = '';              } else {                 this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                  No exact matches found for "\x3Cstrong>${this.escapeHTML(this.currentQuery)}${_strong}". Try adjusting your search term.                ${_div}`;              }            } else {              this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                Search product or category names to discover the best deals from across the web.              ${_div}`;            }            return;          }          let dealsHtml = displayDeals.slice(0, this.displayLimit).map((deal, index) => {            try {               const currencySym = this.escapeHTML(deal.currency);               const isoCurrencyCode = normalizeCurrency(currencySym);               const escapedPrice = this.escapeHTML(deal.price);               const escapedMsrp = this.escapeHTML(deal.msrp);               const areaCode = this.getAreaCode();                              const revenueId = generateRevenueId(deal.url, deal.title, deal.merchant, null);               const originalLink = deal.url;               const rewrittenLink = rewriteAffiliateLink(deal.url, areaCode, revenueId);                        const productCategoryName = 'deals';            const dataAttr = `              data-action="${deal.isCheckPrice ? 'view-similar-click' : 'deal-click'}"              data-analytics-id="${this.escapeHTML(deal.externalProductId || deal.id || '')}"              data-product-name="${this.escapeHTML(deal.title)}"              data-merchant-name="${this.escapeHTML(deal.merchant)}"              data-price="${deal.rawPrice || ''}"              data-previous-price="${deal.rawMsrp || ''}"              data-original-link="${this.escapeHTML(originalLink)}"              data-revenue-id="${revenueId}"              data-index="${index}"              data-total="${displayDeals.length}"              data-in-stock="${deal.inStock !== false}"              data-currency="${this.escapeHTML(isoCurrencyCode)}"              data-model-id="${this.escapeHTML(deal.modelId || '')}"              data-product-key="${this.escapeHTML(deal.productKey || '')}"              data-merchant-id="${this.escapeHTML(deal.merchantId || '')}"            `;                        let priceGroupHtml = '';            let isSavingsSquadMode = this.getViewMode() === 'savings_squad';            let ctaText = 'View Deal';            let formattedPrice = '';            let msrpHtml = '';                        if (deal.isCheckPrice) {              ctaText = 'View Deal';              if (isSavingsSquadMode) {                priceGroupHtml = ``;              } else {                priceGroupHtml = `                  \x3Cdiv class="tg-df-card-price-group">                    \x3Cspan class="tg-df-card-price" style="font-size: 15px; font-weight: 500; font-style: italic;">See price at retailer${_span}                  ${_div}                `;              }            } else {              // Format Price              formattedPrice = escapedPrice.includes(currencySym)                 ? escapedPrice                 : `${currencySym}${escapedPrice}`;                              // Format MSRP              msrpHtml = deal.msrp && deal.rawMsrp > deal.rawPrice                ? `\x3Cspan class="tg-df-card-msrp">${escapedMsrp.includes(currencySym) ? escapedMsrp : currencySym + escapedMsrp}${_span}`                : '';                              priceGroupHtml = isSavingsSquadMode ? `` : `                \x3Cdiv class="tg-df-card-price-group">                  \x3Cspan class="tg-df-card-price">${formattedPrice}${_span}                  ${msrpHtml}                ${_div}              `;            }                        const discountBadgeHtml = deal.savingLabel && !deal.isCheckPrice              ? `\x3Cspan class="tg-df-card-discount-badge">${this.escapeHTML(deal.savingLabel)}${_span}`              : '';                          // HACK for CMS            const _button = '<' + '/button>';            const _svg = '<' + '/svg>';            const _path = '<' + '/path>';            const _rect = '<' + '/rect>';            const _circle = '<' + '/circle>';            const _polyline = '<' + '/polyline>';            const _line = '<' + '/line>';                        let badgesHtml = '';            const primeBadge = deal.isPrime ? `              \x3Cspan class="tg-df-tag tg-df-tag-prime">                \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">                  \x3Cpath d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z">${_path}                ${_svg} Prime              ${_span}            ` : '';                        const couponsBadge = deal.merchant && deal.merchant.toLowerCase().includes('amazon') ? '' : `              \x3Cdiv class="tg-df-coupon-wrapper" data-merchant="${this.escapeHTML(deal.merchant)}" style="display:inline-flex; align-items:center;">                \x3Cdiv class="tg-df-coupon-spinner">${_div}                \x3Cbutton type="button" class="tg-df-tag tg-df-tag-coupons" data-action="coupons-click" data-merchant="${this.escapeHTML(deal.merchant)}" style="display:none;">                  \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">                    \x3Cpath d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z">${_path}                    \x3Cline x1="7" y1="7" x2="7.01" y2="7">${_line}                  ${_svg} Coupons                ${_button}              ${_div}            `;                        // Note: We always add coupons badge if there's a chance, but to allow 3-line titles we check wrapper display state            badgesHtml = `              \x3Cdiv class="tg-df-card-badges">                ${primeBadge}                ${couponsBadge}              ${_div}            `;            const _linearGradient = '<' + '/linearGradient>';            const _polygon = '<' + '/polygon>';            const _stop = '<' + '/stop>';            const _defs = '<' + '/defs>';                        let starHtml = '';            if (deal.starRating) {              let rating = deal.starRating;                            if (rating > 0) {                const fullStars = Math.floor(rating);                const halfStar = (rating - fullStars) >= 0.5 ? 1 : 0;                const emptyStars = Math.max(0, 5 - fullStars - halfStar);                const blue = '#1f69ff'; // Tom's guide brand color from VIEW DEAL button                const gray = '#cbd5e1';                                const starSvgFull = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="${blue}" stroke="${blue}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26">${_polygon}${_svg}`;                                const gradId = 'half_grad_' + Math.floor(Math.random()*1000000);                const starSvgHalf = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" stroke="${blue}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cdefs>\x3ClinearGradient id="${gradId}" x1="0" x2="1" y1="0" y2="0">\x3Cstop offset="50%" stop-color="${blue}">${_stop}\x3Cstop offset="50%" stop-color="transparent">${_stop}${_linearGradient}${_defs}                  \x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26" fill="url(#${gradId})">${_polygon}${_svg}`;                                  const starSvgEmpty = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="${gray}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26">${_polygon}${_svg}`;                                let stars = [];                for (let i=0; i<fullStars; i++) stars.push(starSvgFull);                if (halfStar) stars.push(starSvgHalf);                for (let i=0; i<emptyStars; i++) stars.push(starSvgEmpty);                                starHtml = `\x3Cdiv class="tg-df-card-stars" style="display:flex;align-items:center;margin-bottom:8px;font-size:13px;font-weight:600;color:var(--tg-df-text-muted);">                  \x3Cspan style="margin-right:6px;">Tom's Guide:${_span}                  \x3Cdiv style="display:flex;gap:2px;">                    ${stars.join('')}                  ${_div}                ${_div}`;              }            }            let htmlOutput = '';            if (isSavingsSquadMode) {              htmlOutput += `              \x3Cdiv class="hawk-deal-widget-container tg-df-mobile-only" data-collapsible="true">                ${this.editorMode ? `\x3Cinput type="checkbox" class="tg-df-deal-checkbox" data-id="${this.escapeHTML(deal.id)}" ${this.selectedDeals.has(deal.id) ? 'checked' : ''} style="margin-bottom: 10px;">` : ''}                \x3Cdiv class="hawk-deal-widget-wrap">                  \x3Cdiv class="hawk-deal-widget-image-container">                    \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" rel="sponsored noopener" target="_blank" class="hawk-affiliate-link-deal-widget" ${dataAttr}>                      \x3Cimg ${deal.image ? `src="${this.escapeHTML(deal.image)}"` : ''} alt="${this.escapeHTML(deal.title)}" class="hawk-lazy-image-deal-widget" loading="lazy" width="140" height="160" onerror="${deal.fallbackImage ? `if(!this.dataset.fb) { this.dataset.fb='1'; this.src='${this.escapeHTML(deal.fallbackImage)}'; } else { this.style.opacity='0'; }` : `this.style.opacity='0';`}">                    ${_a}                  ${_div}                  \x3Cdiv class="hawk-deal-widget-text-cta-container">                    \x3Cdiv class="hawk-deal-widget-text-body-container">                      \x3Cdiv class="hawk-deal-widget-text-body-main">                        \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                          ${deal.isCheckPrice ? `                            \x3Cspan class="hawk-deal-widget-title-product-title">${this.escapeHTML(deal.title)}${_span}                          ` : `                            \x3Cspan class="hawk-deal-widget-title-product-title">${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_span}                          `}                        ${_a}                        ${!deal.isCheckPrice && deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `                          \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                            \x3Cspan class="hawk-deal-widget-title-was-price">was ${currencySym}${escapedMsrp}${_span}                          ${_a}                        ` : ''}                        \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                          \x3Cspan class="hawk-deal-widget-title-retailer-price">                            ${!deal.isCheckPrice ? `                              \x3Cspan class="hawk-deal-widget-title-price">now ${formattedPrice}${_span}                              \x3Cspan class="hawk-deal-widget-title-retailer"> at ${this.escapeHTML(deal.merchant)}${_span}                            ` : `                              \x3Cspan class="hawk-deal-widget-title-price">See price at ${this.escapeHTML(deal.merchant)}${_span}                            `}                          ${_span}                        ${_a}                        ${deal.description ? `\x3Cdiv class="hawk-deal-widget-text-body-description tg-df-card-desc-container" style="margin-bottom: 12px; position: relative;">                          \x3Cp class="tg-df-card-desc-content" style="font-size: 13px; color: var(--tg-df-text-muted); margin-bottom: 0; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;">${this.escapeHTML(deal.description)}${_p}                          \x3Cbutton type="button" class="tg-df-card-desc-btn" style="display: none; appearance: none; border: none; color: #000000; font-size: 11px; font-weight: 700; text-transform: uppercase; cursor: pointer; font-family: inherit; position: absolute; bottom: 2px; right: 0; background: linear-gradient(to right, transparent, #fff 20%, #fff); padding: 0 0 0 16px;" onclick="                            var c = this.parentNode;                            if (this.dataset.expanded === 'true') {                              var pd = (c.tagName === 'P') ? c : this.previousElementSibling;                              if (c.tagName === 'P') { c.parentNode.appendChild(this); pd = c; }                              pd.style.display = '-webkit-box';                              pd.style.webkitLineClamp = '3';                              this.textContent = 'READ MORE';                              this.style.position = 'absolute';                              this.style.background = 'linear-gradient(to right, transparent, #fff 20%, #fff)';                              this.style.paddingLeft = '16px';                              this.dataset.expanded = 'false';                            } else {                              var pd = this.previousElementSibling;                              pd.style.display = 'inline';                              pd.style.webkitLineClamp = 'unset';                              this.textContent = 'READ LESS';                              this.style.position = 'static';                              this.style.background = 'transparent';                              this.style.paddingLeft = '4px';                              this.dataset.expanded = 'true';                              pd.appendChild(this);                            }                          ">READ MORE${_button}                        \x3C/div>` : ''}                      ${_div}                    ${_div}                    ${deal.authorName ? `                      \x3Cdiv class="tg-df-author-line-mobile" style="padding: 0 0 12px 0; background: transparent;">                         \x3Cdiv style="display: flex; align-items: center; gap: 12px;">                            ${deal.authorImage ? `\x3Cimg src="${this.escapeHTML(deal.authorImage)}" alt="${this.escapeHTML(deal.authorName)}" class="tg-df-author-img" width="40" height="40" style="border-radius: 50%; object-fit: cover; flex-shrink: 0; aspect-ratio: 1 / 1; min-width: 40px; min-height: 40px;">` : ''}                            \x3Cdiv style="display: flex; flex-direction: column;">                               \x3Cdiv style="font-size: 10px; color: var(--tg-df-text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 2px; font-weight: 600;">\x3Cspan style="color: #FF6600;">${this.escapeHTML(deal.merchant)}${_span} deal recommended by:${_div}                               \x3Cdiv style="font-size: 11px; color: var(--tg-df-text); line-height: 1.3;">                                  \x3Cstrong>\x3Ca href="https://www.tomsguide.com/${this.escapeHTML(deal.documentUrl || '').replace(/^\/+/, '')}" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit; border-bottom: 1px dotted var(--tg-df-text-muted);">${this.escapeHTML(deal.authorName)}${_a}${_strong}                                  ${deal.authorRole && !['null', 'nul', 'undefined'].includes(String(deal.authorRole).toLowerCase()) ? ` • ${this.escapeHTML(deal.authorRole)}` : ''}                                  ${deal.modifiedDate ? `\x3Cdiv style="color: var(--tg-df-text-muted); margin-top: 2px;">${getTimeAgo(deal.modifiedDate)}${_div}` : ''}                               ${_div}                            ${_div}                         ${_div}                      ${_div}                    ` : ''}                    \x3Cdiv class="hawk-deal-widget-footer">                      \x3Cdiv class="hawk-deal-widget-button-wrapper">                        \x3Cdiv class="hawk-deal-widget-preferred-partner-wrapper">                          \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-deal-button" rel="sponsored noopener" target="_blank" ${dataAttr}>                            \x3Cspan>View Deal${_span}                          ${_a}                        ${_div}                      ${_div}                    ${_div}                  ${_div}                ${_div}              ${_div}              `;            }            htmlOutput += `              \x3Cdiv class="tg-df-card ${isSavingsSquadMode ? 'tg-df-desktop-only' : ''}">                ${this.editorMode ? `\x3Cinput type="checkbox" class="tg-df-deal-checkbox" data-id="${this.escapeHTML(deal.id)}" ${this.selectedDeals.has(deal.id) ? 'checked' : ''}>` : ''}                \x3Cdiv class="tg-df-card-image-box">                  ${discountBadgeHtml}                  \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" style="display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;">                    \x3Cimg ${deal.image ? `src="${this.escapeHTML(deal.image)}"` : ''} alt="${this.escapeHTML(deal.title)}" class="tg-df-card-image" loading="lazy" onerror="${deal.fallbackImage ? `if(!this.dataset.fb) { this.dataset.fb='1'; this.src='${this.escapeHTML(deal.fallbackImage)}'; } else { this.style.opacity='0'; }` : `this.style.opacity='0';`}">                  ${_a}                  \x3Cdiv class="tg-df-card-merchant-wrapper" style="position: absolute; bottom: 0; right: 0; background: transparent; padding: 8px 12px; z-index: 10;">                     \x3Cspan class="tg-df-card-merchant-pill" style="text-align: right; margin-bottom: 0;" title="${this.escapeHTML(deal.merchant)}">${this.escapeHTML(deal.merchant)}${_span}                  ${_div}                ${_div}                \x3Cdiv class="tg-df-card-body">                  ${starHtml}                  ${badgesHtml}                  \x3Ch3 class="tg-df-card-title tg-df-custom-savings-squad-title" title="${this.escapeHTML(deal.title)}">                    \x3Ca href="${this.escapeHTML(rewrittenLink)}" disable-tracking="true" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit;">                      ${isSavingsSquadMode                         ? (deal.isCheckPrice                             ? (deal.title && deal.title.includes(':')                                 ? `\x3Cstrong>${this.escapeHTML(deal.title.substring(0, deal.title.indexOf(':') + 1))}${_strong}\x3Cspan style="color: #1f69ff; font-weight: normal;">${this.escapeHTML(deal.title.substring(deal.title.indexOf(':') + 1))}${_span}`                                : this.escapeHTML(deal.title)                              )                             : `\x3Cstrong>${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_strong} ${deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `\x3Cspan style="color: #d0021b; text-decoration: line-through; font-weight: normal; margin-right: 4px;">was ${currencySym}${escapedMsrp}${_span} ` : ''}\x3Cspan style="color: #1f69ff; font-weight: normal;">now ${formattedPrice} at ${this.escapeHTML(deal.merchant)}${_span}`                          )                        : this.escapeHTML(deal.title)                      }                    ${_a}                  ${_h3}                  ${deal.description ? `\x3Cdiv class="tg-df-card-desc-container" style="margin-bottom: 12px; position: relative;">                    \x3Cp class="tg-df-card-desc-content" style="font-size: 13px; color: var(--tg-df-text-muted); margin-bottom: 0; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;">${this.escapeHTML(deal.description)}${_p}                    \x3Cbutton type="button" class="tg-df-card-desc-btn" style="display: none; appearance: none; border: none; color: #000000; font-size: 11px; font-weight: 700; text-transform: uppercase; cursor: pointer; font-family: inherit; position: absolute; bottom: 2px; right: 0; background: linear-gradient(to right, transparent, #fff 20%, #fff); padding: 0 0 0 16px;" onclick="                      var c = this.parentNode;                      if (this.dataset.expanded === 'true') {                        var pd = (c.tagName === 'P') ? c : this.previousElementSibling;                        if (c.tagName === 'P') { c.parentNode.appendChild(this); pd = c; }                        pd.style.display = '-webkit-box';                        pd.style.webkitLineClamp = '3';                        this.textContent = 'READ MORE';                        this.style.position = 'absolute';                        this.style.background = 'linear-gradient(to right, transparent, #fff 20%, #fff)';                        this.style.paddingLeft = '16px';                        this.dataset.expanded = 'false';                      } else {                        var pd = this.previousElementSibling;                        pd.style.display = 'inline';                        pd.style.webkitLineClamp = 'unset';                        this.textContent = 'READ LESS';                        this.style.position = 'static';                        this.style.background = 'transparent';                        this.style.paddingLeft = '4px';                        this.dataset.expanded = 'true';                        pd.appendChild(this);                      }                    ">READ MORE${_button}                  \x3C/div>` : ''}                  \x3Cdiv class="tg-df-card-footer">                    ${deal.authorName ? `                    \x3Cdiv class="tg-df-author-line-desktop" style="padding: 0 0 ${isSavingsSquadMode ? 0 : 12}px 0;">                       \x3Cdiv style="display: flex; align-items: center; gap: 10px;">                          ${deal.authorImage ? `\x3Cimg src="${this.escapeHTML(deal.authorImage)}" alt="${this.escapeHTML(deal.authorName)}" class="tg-df-author-img" width="36" height="36" style="border-radius: 50%; object-fit: cover; flex-shrink: 0; aspect-ratio: 1 / 1; min-width: 36px; min-height: 36px;">` : ''}                          \x3Cdiv style="display: flex; flex-direction: column;">                             \x3Cdiv style="font-size: 10px; color: var(--tg-df-text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 2px; font-weight: 600;">Recommended by:${_div}                             \x3Cdiv style="font-size: 11px; color: var(--tg-df-text); line-height: 1.2;">                                \x3Cstrong>\x3Ca href="https://www.tomsguide.com/${this.escapeHTML(deal.documentUrl || '').replace(/^\/+/, '')}" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit; border-bottom: 1px dotted var(--tg-df-text-muted);">${this.escapeHTML(deal.authorName)}${_a}${_strong}                                ${deal.authorRole && !['null', 'nul', 'undefined'].includes(String(deal.authorRole).toLowerCase()) ? ` • ${this.escapeHTML(deal.authorRole)}` : ''}                                ${deal.modifiedDate ? `\x3Cspan style="color: var(--tg-df-text-muted);"> • ${getTimeAgo(deal.modifiedDate)}${_span}` : ''}                             ${_div}                          ${_div}                       ${_div}                    ${_div}                    ` : ''}                    ${priceGroupHtml}                  ${_div}                ${_div}                \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" class="tg-df-card-cta" style="text-decoration: none; border-radius: 0;">${ctaText}${_a}              ${_div}            `;                        return htmlOutput;            } catch (e) {               console.log("Error rendering deal in map for index", index, typeof deal === 'object' ? JSON.stringify(deal) : deal, "MSG:", e.message);               return '';            }          }).join('');                    if (displayDeals.length > this.displayLimit) {            dealsHtml += `              \x3Cdiv style="width: 100%; display: flex; justify-content: center; margin-top: 16px; grid-column: 1 / -1;">                \x3Cbutton type="button" class="tg-df-tag-outline tg-df-load-more" style="padding: 8px 24px; border-radius: 100px; font-weight: 600; font-size: 14px; cursor: pointer;">Load More${_button}              ${_div}            `;          }                    this.grid.innerHTML = dealsHtml;          // Inject JSON-LD          try {            let targetNode = this.hostContainer || document.head;            let jsonLdScript = targetNode.querySelector('#tg-df-json-ld-' + this.widgetId);            if (!jsonLdScript) {                jsonLdScript = document.createElement('script');                jsonLdScript.type = 'application/ld+json';                jsonLdScript.id = 'tg-df-json-ld-' + this.widgetId;                targetNode.appendChild(jsonLdScript);            }            const jsonLdData = {              "@context": "https://schema.org",              "@type": "ItemList",              "itemListElement": displayDeals.slice(0, this.displayLimit).map((deal, index) => {                 let isoCurrency = "USD";                 if (deal.currency === '£') isoCurrency = "GBP";                 else if (deal.currency === '€') isoCurrency = "EUR";                 else if (deal.currency === 'A$') isoCurrency = "AUD";                 else if (deal.currency === 'CA$') isoCurrency = "CAD";                 const areaCode = typeof this.getAreaCode === 'function' ? this.getAreaCode() : 'US';                 const revenueId = typeof generateRevenueId === 'function' ? generateRevenueId(deal.url, deal.title, deal.merchant, null) : '';                 const rewrittenLink = typeof rewriteAffiliateLink === 'function' ? rewriteAffiliateLink(deal.url, areaCode, revenueId) : deal.url;                 return {                   "@type": "ListItem",                   "position": index + 1,                   "item": {                     "@type": "Product",                     "name": deal.title,                     "image": deal.image || "",                     "description": deal.description || "",                     "brand": {                       "@type": "Brand",                       "name": deal.brand || ""                     },                     "offers": {                       "@type": "Offer",                       "priceCurrency": isoCurrency,                       "price": deal.rawPrice || 0,                       "url": rewrittenLink,                       "seller": {                         "@type": "Organization",                         "name": deal.merchant || ""                       }                     }                   }                 };              }).filter(item => item.item.name)            };            jsonLdScript.textContent = JSON.stringify(jsonLdData);          } catch(e) { console.warn("JSON-LD generation failed", e); }          setTimeout(() => {            const contents = this.root.querySelectorAll('.tg-df-card-desc-content');            contents.forEach(p => {              if (p.scrollHeight > p.clientHeight || p.scrollHeight > 60) {                if (p.nextElementSibling) {                  p.nextElementSibling.style.display = 'block';                }              }            });                        // Allow hawklinks.js to discover and rewrite our widget links             // by appending the .article-body class and manually triggering processArticle.            let container = this.root.classList.contains('tg-df-container') ? this.root : this.root.querySelector('.tg-df-container');            if (container && !container.classList.contains('article-body')) {               container.classList.add('article-body');            }            if (this.grid && !this.grid.classList.contains('article-body')) this.grid.classList.add('article-body');            document.dispatchEvent(new CustomEvent('processArticle', { detail: { element: this.root } }));          }, 50);          const loadMoreBtn = this.grid.querySelector('.tg-df-load-more');          if (loadMoreBtn) {            loadMoreBtn.addEventListener('click', () => {              if (typeof trackElementInteraction === 'function') {                trackElementInteraction({ id: 'load-more', name: 'Load more', label: 'Load More Results' });              }              this.displayLimit += this.getRowsLimit();              this.render();            });          }                      this.bindCouponButtons();            this.checkAndUpdateCoupons();          } catch(e) {            console.warn("Widget render error", e);          }        }                async checkAndUpdateCoupons() {          const wrappers = Array.from(this.root.querySelectorAll('.tg-df-coupon-wrapper'));          if (wrappers.length === 0) return;                    const merchants = [...new Set(wrappers.map(w => w.getAttribute('data-merchant')).filter(Boolean))];          if (merchants.length === 0) return;          const couponResultsMap = await this.checkMerchantsCouponsBulk(merchants);                    for (const merchant of merchants) {            const hasCoupons = !!couponResultsMap[merchant];            const merchantWrappers = wrappers.filter(w => w.getAttribute('data-merchant') === merchant);            merchantWrappers.forEach(wrapper => {              const spinner = wrapper.querySelector('.tg-df-coupon-spinner');              const btn = wrapper.querySelector('.tg-df-tag-coupons');                            if (spinner) spinner.style.display = 'none';                            if (hasCoupons && btn) {                btn.style.display = 'inline-flex';              } else if (!hasCoupons) {                wrapper.style.display = 'none';              }            });          }        }        updateFloatingCopyBar() {          if (!this.editorBar || !this.editorSelectedCount) return;          if (this.editorMode && this.selectedDeals.size > 0) {            this.editorBar.style.display = 'flex';            this.editorSelectedCount.innerText = this.selectedDeals.size;          } else {            this.editorBar.style.display = 'none';          }        }        async copySelectedDealsToCMS() {           function htmlToSlate(htmlString) {              if (!htmlString) return [{ type: 'paragraph', children: [{ text: '' }] }];              let doc;              if (typeof window !== 'undefined' && window.DOMParser) {                 doc = new DOMParser().parseFromString(htmlString, 'text/html');              } else {                 doc = document.implementation.createHTMLDocument('');                 doc.body.innerHTML = htmlString;              }                            function parseNode(node, marks = {}) {                  if (node.nodeType === 3) {                      const text = node.textContent;                      if (!text) return null;                      return { text: text, ...marks };                  }                  if (node.nodeType === 1) {                      const tagName = node.tagName.toLowerCase();                      if (tagName === 'br') {                          return { type: 'line-break', children: [{ text: '' }] };                      }                      if (tagName === 'p') {                          let children = Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                          if (children.length === 0) children.push({ text: "" });                          return { type: 'paragraph', children };                      }                      if (tagName === 'strong' || tagName === 'b') {                          const newMarks = { ...marks, bold: true };                          return Array.from(node.childNodes).map(child => parseNode(child, newMarks)).flat().filter(Boolean);                      }                      if (tagName === 'em' || tagName === 'i') {                          const newMarks = { ...marks, italic: true };                          return Array.from(node.childNodes).map(child => parseNode(child, newMarks)).flat().filter(Boolean);                      }                      if (tagName === 'a') {                          const href = node.getAttribute('href') || '';                          let children = Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                          if (children.length === 0) children.push({ text: "" });                          return {                              type: 'link',                              url: href,                              isNoFollow: (node.getAttribute('rel') || '').includes('nofollow'),                              isSponsored: (node.getAttribute('rel') || '').includes('sponsored'),                              isOpenNewTab: node.getAttribute('target') === '_blank',                              isPreventDataRewrite: false,                              children: children                          };                      }                      return Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                  }                  return null;              }                            let blocksArray = [];              let currentParagraphChildren = [];              function flushParagraph() {                  if (currentParagraphChildren.length > 0) {                      blocksArray.push({ type: 'paragraph', children: currentParagraphChildren });                      currentParagraphChildren = [];                  }              }              Array.from(doc.body.childNodes).forEach(node => {                  const parsed = parseNode(node, {});                  const parsedItems = Array.isArray(parsed) ? parsed : (parsed ? [parsed] : []);                  parsedItems.forEach(item => {                      if (item.type === 'paragraph') {                          flushParagraph();                          blocksArray.push(item);                      } else {                          currentParagraphChildren.push(item);                      }                  });              });              flushParagraph();              if (blocksArray.length === 0) {                  blocksArray = [{ type: 'paragraph', children: [{ text: '' }] }];              }              return blocksArray;           }           const blocks = [];                      this.editorCopyBtn.innerHTML = '\x3Cspan class="tg-df-coupon-spinner" style="display:inline-block; margin-right:8px; border-top-color:#fff;">' + '<' + '/span> Copying...';           for (const deal of Array.from(this.selectedDeals.values())) {              const url = deal.url;              const merchant = deal.merchant;              const title = deal.title;              const image = deal.image;              const currentPrice = deal.currency + deal.rawPrice;              const wasPrice = deal.hasWasPrice && deal.rawMsrp > deal.rawPrice ? deal.currency + deal.rawMsrp : '';                            let couponsChildren = [];              try {                  const area = this.getAreaCode();                  const apiUrl = new URL('https://search-api.fie.future.net.uk/widget.php');                  apiUrl.searchParams.append('model_name', 'Everything');                  apiUrl.searchParams.append('language', 'en-GB');                  apiUrl.searchParams.append('area', area);                  apiUrl.searchParams.append('combine_product_types', '1');                  apiUrl.searchParams.append('filter_merchant_name', merchant);                  apiUrl.searchParams.append('all_filters', 'false');                  apiUrl.searchParams.append('exclude_unlabelled', 'false');                  apiUrl.searchParams.append('include_specs', 'false');                  apiUrl.searchParams.append('sort', 'voucher');                  apiUrl.searchParams.append('distinct_merchants', 'natural');                  apiUrl.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');                  apiUrl.searchParams.append('rows', '3');                  apiUrl.searchParams.append('origin', 'widgets-clientside');                                    let res; try { res = await fetch(apiUrl.toString()); } catch (e) { return; }                  if (res.ok) {                      const data = await res.json();                      let offers = [];                      if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {                        offers = data.widget.data.offers;                      } else if (data && data.data && Array.isArray(data.data.offers)) {                        offers = data.data.offers;                      }                                            if (offers.length > 0) {                          couponsChildren.push({ text: "Also check out these coupons: ", bold: true });                          offers.slice(0, 3).forEach((offer, idx) => {                              const actualOffer = offer.offer || offer;                              const offerName = actualOffer.name || actualOffer.title || offer.model_name || offer.title || offer.name || 'Coupon';                              const linkUrl = actualOffer.link || actualOffer.url || actualOffer.offer_link || '#';                              couponsChildren.push({ type: "line-break", children: [{ text: "" }] });                              couponsChildren.push({ text: "🎟️ " });                              couponsChildren.push({                                  type: "link",                                  url: linkUrl,                                  isNoFollow: true,                                  isSponsored: false,                                  isOpenNewTab: true,                                  isPreventDataRewrite: false,                                  children: [{ text: offerName, bold: true }]                              });                          });                      }                  }              } catch (err) {                  console.warn('Failed to fetch coupons for', merchant, err);              }              let descriptionValue = [];              if (deal.text) {                 descriptionValue = htmlToSlate(deal.text);              } else {                 const dealDescriptions = [                   `Don't miss out on this fantastic deal for the ${title}. It is currently available at ${merchant} for a highly competitive price.`,                   `We've spotted an excellent price drop on the ${title}. Grab it now at ${merchant} before it's gone.`,                   `The ${title} is currently seeing a generous discount over at ${merchant}. This is a perfect time to buy if you've been holding out.`,                   `If you're in the market for the ${title}, ${merchant} has just the deal for you.`,                   `Score the ${title} for less at ${merchant} right now. This is a rare chance to save big.`,                   `Upgrade your setup with the ${title}, now available at a stellar price via ${merchant}.`                 ];                 const randomDescription = dealDescriptions[Math.floor(Math.random() * dealDescriptions.length)];                 descriptionValue = [                    { type: "paragraph", children: [{ text: randomDescription }] }                 ];              }                            if (couponsChildren.length > 0) {                 let lastBlock = descriptionValue[descriptionValue.length - 1];                 if (lastBlock && lastBlock.type === 'paragraph') {                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children.push({ text: "Also check out these coupons: ", bold: true });                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children = lastBlock.children.concat(couponsChildren);                 } else {                     descriptionValue.push({                         type: "paragraph",                         children: [                             { type: "line-break", children: [{ text: "" }] },                             { type: "line-break", children: [{ text: "" }] },                             { text: "Also check out these coupons: ", bold: true },                             { type: "line-break", children: [{ text: "" }] },                             ...couponsChildren                         ]                     });                 }              }              function normalizeCurrencyToISO(symbol) {                const map = { '£': 'GBP', '$': 'USD', 'A$': 'AUD', 'CA$': 'CAD', '€': 'EUR' };                return map[symbol] || symbol;              }              const isoCurrency = normalizeCurrencyToISO(deal.currency);              blocks.push({                 id: (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : 'cms-' + Date.now() + Math.random(),                 blockTypeName: "deal",                 excludeFrom: [],                 collapsible: false,                 props: {                    description: {                       value: descriptionValue,                       touched: false,                       validationMessage: ""                    },                    image: {                       value: {                          credit: [{ type: "paragraph", children: [{ text: merchant }] }],                          dateCreated: Date.now(),                          dateModified: Date.now(),                          distribution: [],                          fileSize: 0,                          height: 1000,                          id: deal.id,                          imageRights: "",                          src: image,                          name: title + ".jpg",                          tags: [],                          width: 1000                       },                       touched: false,                       validationMessage: ""                    },                    showDealButton: { value: true, touched: false, validationMessage: "" },                    isPreferredPartner: { value: false, touched: false, validationMessage: "" },                    linkHref: { value: url, touched: false, validationMessage: "" },                    linkLabel: { value: "", touched: false, validationMessage: "" },                    linkIsNoFollow: { value: true, touched: false, validationMessage: "" },                    linkIsSponsored: { value: false, touched: false, validationMessage: "" },                    linkIsOpenNewWindow: { value: true, touched: false, validationMessage: "" },                    customPromoFlags: { value: [], touched: false, validationMessage: "" },                    showStarDeal: { value: false, touched: false, validationMessage: "" },                    savingType: { value: "none", touched: false, validationMessage: "" },                    starDealPromoFlag: { value: "", touched: false, validationMessage: "" },                    showEditorsChoice: { value: false, touched: false, validationMessage: "" },                    editorsChoiceTitle: { value: "", touched: false, validationMessage: "" },                    hawkPriceCurrency: { value: { value: isoCurrency, label: isoCurrency }, touched: false, validationMessage: "" },                    hawkPrice: { value: deal.hasWasPrice ? String(deal.rawMsrp) : String(deal.rawPrice), touched: false, validationMessage: "" },                    hawkSalePrice: { value: String(deal.rawPrice), touched: false, validationMessage: "" },                    lastCheckedPriceDate: { value: "", touched: false, validationMessage: "" },                    hawkModel: { touched: false, validationMessage: "" },                    productId: { value: "", touched: false, validationMessage: "" },                    voucherId: { value: "", touched: false, validationMessage: "" },                    brand: { value: deal.brand || merchant, touched: false, validationMessage: "" },                    productName: { value: title, touched: false, validationMessage: "" },                    label: { value: "", touched: false, validationMessage: "" },                    retailer: { value: merchant, touched: false, validationMessage: "" },                    priceCheckError: false                 },                 failedFetchError: ""              });           }           const payload = {              type: "articleBuilderPages",              data: blocks           };           const jsonStr = JSON.stringify(payload);                      if (navigator.clipboard && navigator.clipboard.writeText) {              navigator.clipboard.writeText(jsonStr).then(() => {                 this.editorCopyBtn.innerHTML = 'Copied!';                 setTimeout(() => {                    this.editorCopyBtn.innerHTML = '\x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2"><' + '/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"><' + '/path><' + '/svg> Copy to CMS';                 }, 2000);              }).catch(err => {                 console.warn('Failed to copy text: ', err);                 alert('Failed to copy deals to clipboard. See console.');              });           } else {              // Fallback              const textArea = document.createElement("textarea");              textArea.value = jsonStr;              document.body.appendChild(textArea);              textArea.focus();              textArea.select();              try {                 document.execCommand('copy');                 this.editorCopyBtn.innerHTML = 'Copied!';                 setTimeout(() => {                    this.editorCopyBtn.innerHTML = '\x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2"><' + '/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"><' + '/path><' + '/svg> Copy to CMS';                 }, 2000);              } catch (err) {                 console.warn('Fallback: Oops, unable to copy', err);                 alert('Fallback: Failed to copy deals to clipboard.');              }              document.body.removeChild(textArea);           }        }      }      // Initialize the Widget      if (document.readyState === 'loading') {        document.addEventListener('DOMContentLoaded', () => new DealsFinderWidget({ rootId: 'signal-deals-finder-root', rootNode: shadowRoot, hostContainer: hostContainer }));      } else {        new DealsFinderWidget({ rootId: 'signal-deals-finder-root', rootNode: shadowRoot, hostContainer: hostContainer });      }    })();  </script></div> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/best-iphone-18-pro-and-pro-max-deals</link>
                                                                            <description>
                            <![CDATA[ I track deals for a living and I'm rounding up all of the best iPhone 18 Pro and iPhone 18 Pro Max deals. Here's how you can get Apple's new iPhone for free. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">UnxNJNSCxXpzwjVLHQPnHR</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/RHH4L3qmH7q9YSrDYxjovS-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 18 Sep 2026 12:00:00 +0000</pubDate>                                                                                                                                <updated>Mon, 21 Sep 2026 16:51:03 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ louis.ramirez@futurenet.com (Louis Ramirez) ]]></author>                    <dc:creator><![CDATA[ Louis Ramirez ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oYF2xVwCb4pTGhAJi8Yqr5-320-70.jpeg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;As deals editor-in-chief at Tom’s Guide, Louis refuses to pay full price for anything. He has over 10 years of experience finding the best deals and coupons to bring readers. Louis price checks against multiple retailers and searches high and low for sales on 4K TVs, Apple devices, streaming services, mattresses, kitchen appliances, and more. He&#039;s also always looking for the the best coupon codes to turn good deals into stellar buys.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;He has covered major retail events like Amazon Prime Day, Black Friday, and Cyber Monday for more than a decade and knows how to spot an epic deal from a fake discount. He&#039;s also great at helping people negotiate better prices on everything from gym memberships to their home internet service. Louis&#039; work has also helped readers find PS5 restock, baby formula, Clorox wipes, and everything in between. For his next major purchase, Louis is hoping to find a killer deal on an M3-based Mac. &lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;A born-and-bred New Yorker, Louis is always in search of the perfect cup of coffee. On his free time, he enjoys swimming, running, and any workout that pushes his Apple Watch to the max. He&#039;s also a big fan of international films, horror movies, and K-dramas. His work has appeared on Gizmodo, CNET, Digital Trends, Dealnews, and Time Out New York.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/RHH4L3qmH7q9YSrDYxjovS-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 18 Pro Max and iPhone 18 Pro held side by side]]></media:description>                                                            <media:text><![CDATA[iPhone 18 Pro Max and iPhone 18 Pro held side by side]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 18 Pro Max and iPhone 18 Pro held side by side]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/RHH4L3qmH7q9YSrDYxjovS-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The 6.3-inch <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro</a> and 6.9-inch <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max</a> cost $1,199 and $1,299, respectively. That's $100 pricier than their predecessors. Fortunately, there are plenty of iPhone 18 Pro deals you can take advantage of right now. </p><p>I've been buying iPhones since the 6s, so when it comes to deals I know where to look. For example, right now <a href="https://tmobilepostpaid.pxf.io/c/1943169/4032247/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow">T-Mobile is offering the iPhone 18 Pro for free</a> when you bring your number and open an Experience Beyond plan. Or you can get it for free with trade-in and an Experience Beyond plan. That's one of the best iPhone 18 Pro deals around. </p><p>Prefer the bigger screen of the iPhone 18 Pro Max? <a href="https://www.verizon.com/smartphones/apple-iphone-18-pro-max/?isMyPlanFlow=true" target="_blank" rel="nofollow">Verizon is taking up to $1,200 off the iPhone 18 Pro Max</a> when you open a new line and trade-in an old phone. You'll even get NFL Sunday Ticket by YouTube for free with your account. </p><p>Below I've found all of the best iPhone 18 Pro deals at carriers and retailers alike. I'm also tracking all the <a href="https://www.tomsguide.com/phones/iphones/warning-here-are-all-the-iphone-18-pro-shipping-delays-at-t-mobile-verizon-at-and-t-and-more">iPhone 18 Pro delays</a>, so you know when you can expect your phone to arrive. If you're looking for deals on accessories, <a href="https://www.amazon.com/stores/page/7FF33670-28E4-48AA-9D38-3B9010BB6947" target="_blank" rel="nofollow">Amazon has iPhone accessories from $14</a> including cases, cables, chargers, AirPods, and more.</p><h3 class="article-body__section" id="section-quick-links"><span>Quick Links</span></h3><ul><li><strong>T-Mobile: </strong><a href="https://tmobilepostpaid.pxf.io/c/1943169/3726747/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow"><strong>free w/ new line + unlimited </strong></a><strong></strong></li><li><strong>Verizon: </strong><a href="https://www.verizon.com/smartphones/apple-iphone-18-pro/?isMyPlanFlow=true" target="_blank" rel="nofollow"><strong>free w/ new line + trade-in on eligible myPlan</strong></a><strong></strong></li><li><strong>AT&T: </strong><a href="https://www.att.com/buy/phones/apple-iphone-18-pro.html" target="_blank" rel="nofollow"><strong>up to $1,200 off w/ new line or trade</strong></a></li><li><strong>Xfinity Mobile: </strong><a href="https://www.xfinity.com/learn/mobile" target="_blank" rel="nofollow"><strong>up to $1,300 off any new iPhone w/ trade + unlimited</strong></a><strong></strong></li><li><strong>Mint Mobile: </strong><a href="https://www.mintmobile.com/phone-plans/3-month-plans/" target="_blank" rel="nofollow"><strong>up to 50% off 3-month data plans</strong></a><strong></strong></li><li><strong>Visible: </strong><a href="https://www.visible.com/shop/smartphones/iphone-18-pro?sku=MJQ54LL/A" target="_blank" rel="nofollow"><strong>$480 off any new iPhone purchase w/ unlimited</strong></a><strong></strong></li><li><strong>Walmart: </strong><a href="https://www.walmart.com/ip/AT-T-iPhone-18-Pro-256GB-Glacier/20973750630" target="_blank" rel="nofollow"><strong>from $31/month on select carriers</strong></a><strong></strong></li><li><strong>Red Pocket: </strong><a href="https://www.redpocket.com/shop/iphone/apple-iphone-18-pro-unlocked" target="_blank" rel="nofollow"><strong>$100 off iPhone 18 Pro or Pro Max</strong></a></li><li><strong>Apple Store: </strong><a href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow"><strong>up to $885 off w/ trade-in @ Apple</strong></a></li><li><strong>iPhone accessories: </strong><a href="https://www.amazon.com/stores/page/7FF33670-28E4-48AA-9D38-3B9010BB6947" target="_blank" rel="nofollow"><strong>from $7 @ Amazon</strong></a><strong></strong></li></ul><h3 class="article-body__section" id="section-iphone-18-pro"><span>iPhone 18 Pro</span></h3><div class="product"><a data-dimension112="82ce626a-b2dc-11f1-b0c3-a98753575a8a" data-action="Deal Block" data-label="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" href="https://tmobilepostpaid.pxf.io/c/1943169/4032247/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:50.00%;"><img id="Y26QJd7Ff7aeQmTHuW8nCP" name="NEW T-Mobile Logo" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Y26QJd7Ff7aeQmTHuW8nCP-1920-80.png" mos="" align="middle" fullscreen="" width="600" height="300" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro: </strong><a href="https://tmobilepostpaid.pxf.io/c/1943169/4032247/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow" data-dimension112="82ce626a-b2dc-11f1-b0c3-a98753575a8a" data-action="Deal Block" data-label="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension25=""><strong>free w/ trade-in + unlimited @ T-Mobile</strong></a><br>T-Mobile is offering the iPhone 18 Pro for free when you switch and bring your number or when you trade-in an eligible phone and sign up for T-Mobile's Experience Beyond plan. In our <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro review</a>, we said its the best phone money can buy. The iPhone 18 Pro features a 6.3-inch OLED 120Hz display (2622 x 1206), A20 Pro chipset, and 256GB of storage. You also get a 48MP main, 48MP ultrawide, and 48MP telephoto lens w/ 4x zoom. The front camera is 18MP. <a class="view-deal button" href="https://tmobilepostpaid.pxf.io/c/1943169/4032247/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow" data-dimension112="82ce626a-b2dc-11f1-b0c3-a98753575a8a" data-action="Deal Block" data-label="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro: free w/ trade-in + unlimited @ T-Mobile" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce6332-b2dc-11f1-9875-45193ceb5368" data-action="Deal Block" data-label="iPhone 18 Pro: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension48="iPhone 18 Pro: up to $1,200 off w/ new line or trade @ AT&amp;T" href="https://www.att.com/buy/phones/apple-iphone-18-pro.html" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:225px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="o9PdShQsgAk95AN7C5UMNR" name="AT&T Logo.jpeg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/o9PdShQsgAk95AN7C5UMNR-1920-80.jpeg" mos="" align="middle" fullscreen="" width="225" height="225" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro: </strong><a href="https://www.att.com/buy/phones/apple-iphone-18-pro.html" target="_blank" rel="nofollow" data-dimension112="82ce6332-b2dc-11f1-9875-45193ceb5368" data-action="Deal Block" data-label="iPhone 18 Pro: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension48="iPhone 18 Pro: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension25=""><strong>up to $1,200 off w/ new line or trade @ AT&T</strong></a><br>New and existing AT&T customers can get up to $1,200 off the iPhone 18 Pro when you trade-in any iPhone in any condition. New customers can also get up to $800 to pay off any devices that are still in contract. <a class="view-deal button" href="https://www.att.com/buy/phones/apple-iphone-18-pro.html" target="_blank" rel="nofollow" data-dimension112="82ce6332-b2dc-11f1-9875-45193ceb5368" data-action="Deal Block" data-label="iPhone 18 Pro: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension48="iPhone 18 Pro: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce62ce-b2dc-11f1-ae85-25776ca81f9c" data-action="Deal Block" data-label="iPhone 18 Pro: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension48="iPhone 18 Pro: up to $1,200 off w/ new line + trade-in @ Verizon" href="https://www.verizon.com/smartphones/apple-iphone-18-pro/?isMyPlanFlow=true" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:400px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="bhuNLVbkmhJxHuYhoz9cuY" name="verizon-redesign-thumb.jpeg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/bhuNLVbkmhJxHuYhoz9cuY-1920-80.jpg" mos="" align="middle" fullscreen="" width="400" height="400" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro: </strong><a href="https://www.verizon.com/smartphones/apple-iphone-18-pro/?isMyPlanFlow=true" target="_blank" rel="nofollow" data-dimension112="82ce62ce-b2dc-11f1-ae85-25776ca81f9c" data-action="Deal Block" data-label="iPhone 18 Pro: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension48="iPhone 18 Pro: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension25=""><strong>up to $1,200 off w/ new line + trade-in @ Verizon</strong></a><br>Verizon will take up to $1,200 off your iPhone 18 Pro when you open a new line, trade-in an old phone, and open an eligible unlimited data plan. <a class="view-deal button" href="https://www.verizon.com/smartphones/apple-iphone-18-pro/?isMyPlanFlow=true" target="_blank" rel="nofollow" data-dimension112="82ce62ce-b2dc-11f1-ae85-25776ca81f9c" data-action="Deal Block" data-label="iPhone 18 Pro: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension48="iPhone 18 Pro: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce6404-b2dc-11f1-81bc-33559aee3d8f" data-action="Deal Block" data-label="iPhone 18 Pro: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension48="iPhone 18 Pro: free w/ trade-in + unlimited @ Xfinity Mobile" href="https://www.xfinity.com/learn/mobile" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1413px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="MEg942YDCTSzn9H3vsaqPj" name="xfinity-mobile.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/MEg942YDCTSzn9H3vsaqPj-1920-80.jpg" mos="" align="middle" fullscreen="" width="1413" height="1413" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro: </strong><a href="https://www.xfinity.com/learn/mobile" target="_blank" rel="nofollow" data-dimension112="82ce6404-b2dc-11f1-81bc-33559aee3d8f" data-action="Deal Block" data-label="iPhone 18 Pro: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension48="iPhone 18 Pro: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension25=""><strong>free w/ trade-in + unlimited @ Xfinity Mobile</strong></a><br>New and existing Xfinity Mobile Plus customers can get the iPhone 18 Pro for free when trade-in a device and open a new line with eligible data plan. New customers must activate a new Xfinity Mobile line within 30 days of purchase, whereas existing customers can upgrade one of their existing lines to receive the deal. <a class="view-deal button" href="https://www.xfinity.com/learn/mobile" target="_blank" rel="nofollow" data-dimension112="82ce6404-b2dc-11f1-81bc-33559aee3d8f" data-action="Deal Block" data-label="iPhone 18 Pro: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension48="iPhone 18 Pro: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce6396-b2dc-11f1-91f3-374d995ab367" data-action="Deal Block" data-label="Mint Mobile: $15 off any 3-month plan @ Mint Mobile" data-dimension48="Mint Mobile: $15 off any 3-month plan @ Mint Mobile" data-dimension25="$" href="https://www.mintmobile.com/phone-plans/3-month-plans/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:606px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="w2sEQkELQqB3oTd6G5arL5" name="mint-mobile-logo-recobox.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/w2sEQkELQqB3oTd6G5arL5-1920-80.jpg" mos="" align="middle" fullscreen="" width="606" height="606" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>Mint Mobile: </strong><a href="https://www.mintmobile.com/phone-plans/3-month-plans/" target="_blank" rel="nofollow" data-dimension112="82ce6396-b2dc-11f1-91f3-374d995ab367" data-action="Deal Block" data-label="Mint Mobile: $15 off any 3-month plan @ Mint Mobile" data-dimension48="Mint Mobile: $15 off any 3-month plan @ Mint Mobile" data-dimension25="$"><strong>$15 off any 3-month plan @ Mint Mobile</strong></a><br>It's not a preorder deal per se, but if you want to save on data — you'll want to check out this Mint Mobile offer. For a limited time, Mint Mobile is taking $15 off any 3-month plan. After discount, the 3-month Unlimited plan costs $15/month ($45 upfront). That's one of the best Mint Mobile deals I've seen. <a class="view-deal button" href="https://www.mintmobile.com/phone-plans/3-month-plans/" target="_blank" rel="nofollow" data-dimension112="82ce6396-b2dc-11f1-91f3-374d995ab367" data-action="Deal Block" data-label="Mint Mobile: $15 off any 3-month plan @ Mint Mobile" data-dimension48="Mint Mobile: $15 off any 3-month plan @ Mint Mobile" data-dimension25="$">View Deal</a></p></div><div class="product"><a data-dimension112="82ce64cc-b2dc-11f1-960c-09fe28238b7a" data-action="Deal Block" data-label="Visible: $480 off w/ new iPhone @ Visible" data-dimension48="Visible: $480 off w/ new iPhone @ Visible" href="https://www.visible.com/shop/smartphones/iphone-18-pro?sku=MJQ54LL/A" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1000px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="nXRVmdXfPxa8NUZ7ukyY7P" name="visible_logo_new.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/nXRVmdXfPxa8NUZ7ukyY7P-1920-80.jpg" mos="" align="middle" fullscreen="" width="1000" height="1000" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>Visible: </strong><a href="https://www.visible.com/shop/smartphones/iphone-18-pro?sku=MJQ54LL/A" target="_blank" rel="nofollow" data-dimension112="82ce64cc-b2dc-11f1-960c-09fe28238b7a" data-action="Deal Block" data-label="Visible: $480 off w/ new iPhone @ Visible" data-dimension48="Visible: $480 off w/ new iPhone @ Visible" data-dimension25=""><strong>$480 off w/ new iPhone @ Visible</strong></a><br>Visible's iPhone 18 Pro deal is pretty straightforward. Buy any new iPhone with the Visible+ Pro plan and you'll get $480 back via monthly credits over the span of 24 months. Visible+ Pro costs $45/month and includes unlimited premium data on Verizon's 5G Ultra Wideband network, smartwatch data plan service, and up to 4K UHD video streaming. <a class="view-deal button" href="https://www.visible.com/shop/smartphones/iphone-18-pro?sku=MJQ54LL/A" target="_blank" rel="nofollow" data-dimension112="82ce64cc-b2dc-11f1-960c-09fe28238b7a" data-action="Deal Block" data-label="Visible: $480 off w/ new iPhone @ Visible" data-dimension48="Visible: $480 off w/ new iPhone @ Visible" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="1b9144b6-b389-11f1-b4db-e5ff482b4ca5" data-action="Deal Block" data-label="iPhone 18 Pro" data-dimension48="iPhone 18 Pro" data-dimension25="$1099" href="https://www.redpocket.com/shop/iphone/apple-iphone-18-pro-unlocked" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:374px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="2Rb63M2Ym3t5t2s8BWCeLK" name="Red Pocket Mobile logo" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/2Rb63M2Ym3t5t2s8BWCeLK-1920-80.png" mos="" align="middle" fullscreen="" width="374" height="374" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>RedPocket Mobile is an MVNO that lets you choose between using AT&T's, T-Mobile's, or Verizon's network. Right now, you can get the iPhone 18 Pro for $1,099 ($100 off) with no port or trade-in required. Unlimited data plans start from $10/month or $100/year. <a class="view-deal button" href="https://www.redpocket.com/shop/iphone/apple-iphone-18-pro-unlocked" target="_blank" rel="nofollow" data-dimension112="1b9144b6-b389-11f1-b4db-e5ff482b4ca5" data-action="Deal Block" data-label="iPhone 18 Pro" data-dimension48="iPhone 18 Pro" data-dimension25="$1099">View Deal</a></p></div><div class="product"><a data-dimension112="1b91454c-b389-11f1-9076-917394898d0a" data-action="Deal Block" data-label="iPhone 18 Pro" data-dimension48="iPhone 18 Pro" data-dimension25="$999" href="https://www.boostmobile.com/shop/iphone-18-pro.html" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:713px;"><p class="vanilla-image-block" style="padding-top:38.85%;"><img id="UGYgmHB5HuHtAFmJHSMZnU" name="Boost Mobile logo 2024.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/UGYgmHB5HuHtAFmJHSMZnU-1920-80.jpg" mos="" align="middle" fullscreen="" width="713" height="277" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>Boost Mobile is offering the iPhone 18 Pro for $999 when you bring your line and sign up for Boost's Unlimited Premium plan ($60/month). The plan includes unlimited talk, text, and 50GB of premium/high-speed data as well as global talk/text and mobile hotspot. Or you can get it for $1,099 when you open a new Unlimited Premium plan. <a class="view-deal button" href="https://www.boostmobile.com/shop/iphone-18-pro.html" target="_blank" rel="nofollow" data-dimension112="1b91454c-b389-11f1-9076-917394898d0a" data-action="Deal Block" data-label="iPhone 18 Pro" data-dimension48="iPhone 18 Pro" data-dimension25="$999">View Deal</a></p></div><div class="product"><a data-dimension112="82ce6468-b2dc-11f1-97f9-8fc058d17290" data-action="Deal Block" data-label="iPhone 18 Pro: up to $600 off w/ unlimited @ Total Wireless" data-dimension48="iPhone 18 Pro: up to $600 off w/ unlimited @ Total Wireless" href="https://www.totalwireless.com/m/home" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="Z3gikFPLPLmWFv4RSSgxVh" name="total-square.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Z3gikFPLPLmWFv4RSSgxVh-1920-80.jpg" mos="" align="middle" fullscreen="" width="600" height="600" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro: </strong><a href="https://www.totalwireless.com/m/home" target="_blank" rel="nofollow" data-dimension112="82ce6468-b2dc-11f1-97f9-8fc058d17290" data-action="Deal Block" data-label="iPhone 18 Pro: up to $600 off w/ unlimited @ Total Wireless" data-dimension48="iPhone 18 Pro: up to $600 off w/ unlimited @ Total Wireless" data-dimension25=""><strong>up to $600 off w/ unlimited @ Total Wireless</strong></a><br>Total Wireless is taking up to $600 off the iPhone 18 Pro. You'll get a $25/monthly bill credit (over 24 months) when you stay on Total Wireless' All Access plan. <a class="view-deal button" href="https://www.totalwireless.com/m/home" target="_blank" rel="nofollow" data-dimension112="82ce6468-b2dc-11f1-97f9-8fc058d17290" data-action="Deal Block" data-label="iPhone 18 Pro: up to $600 off w/ unlimited @ Total Wireless" data-dimension48="iPhone 18 Pro: up to $600 off w/ unlimited @ Total Wireless" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce6530-b2dc-11f1-9df9-3f1c1e641363" data-action="Deal Block" data-label="iPhone 18 Pro: from $31/month @ Walmart" data-dimension48="iPhone 18 Pro: from $31/month @ Walmart" href="https://www.walmart.com/ip/AT-T-iPhone-18-Pro-256GB-Glacier/20973750630" 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:93.65%;"><img id="Bi2iDjTxUHTUQK9FHZ4W8D" name="Walmart logo.jpeg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Bi2iDjTxUHTUQK9FHZ4W8D-1920-80.jpeg" mos="" align="middle" fullscreen="" width="960" height="899" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro: </strong><a href="https://www.walmart.com/ip/AT-T-iPhone-18-Pro-256GB-Glacier/20973750630" target="_blank" rel="nofollow" data-dimension112="82ce6530-b2dc-11f1-9df9-3f1c1e641363" data-action="Deal Block" data-label="iPhone 18 Pro: from $31/month @ Walmart" data-dimension48="iPhone 18 Pro: from $31/month @ Walmart" data-dimension25=""><strong>from $31/month @ Walmart</strong></a><br>Walmart is offering the iPhone 18 Pro for AT&T, Verizon, or T-Mobile from $31/month. The phone is available in all colors and storage capacities, although some models are starting to sell out. <a class="view-deal button" href="https://www.walmart.com/ip/AT-T-iPhone-18-Pro-256GB-Glacier/20973750630" target="_blank" rel="nofollow" data-dimension112="82ce6530-b2dc-11f1-9df9-3f1c1e641363" data-action="Deal Block" data-label="iPhone 18 Pro: from $31/month @ Walmart" data-dimension48="iPhone 18 Pro: from $31/month @ Walmart" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce6594-b2dc-11f1-9bb3-6ff3d9e48857" data-action="Deal Block" data-label="iPhone 18 Pro: up to $480 off @ StraightTalk" data-dimension48="iPhone 18 Pro: up to $480 off @ StraightTalk" href="https://www.straighttalk.com/all-phones/apple-iphone-18-pro-256gb-prepaid" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:264px;"><p class="vanilla-image-block" style="padding-top:72.35%;"><img id="jg63LBik54HBQtDrbyFRh8" name="StraightTalk logo.png" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/jg63LBik54HBQtDrbyFRh8-1920-80.png" mos="" align="middle" fullscreen="" width="264" height="191" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro: </strong><a href="https://www.straighttalk.com/all-phones/apple-iphone-18-pro-256gb-prepaid" target="_blank" rel="nofollow" data-dimension112="82ce6594-b2dc-11f1-9bb3-6ff3d9e48857" data-action="Deal Block" data-label="iPhone 18 Pro: up to $480 off @ StraightTalk" data-dimension48="iPhone 18 Pro: up to $480 off @ StraightTalk" data-dimension25=""><strong>up to $480 off @ StraightTalk</strong></a><br>StraightTalk is taking up to $480 off the iPhone 18 Pro. You'll get $20 off your monthly bill over the span of 24 months when you activate a Gold Unlimited plan or higher. <a class="view-deal button" href="https://www.straighttalk.com/all-phones/apple-iphone-18-pro-256gb-prepaid" target="_blank" rel="nofollow" data-dimension112="82ce6594-b2dc-11f1-9bb3-6ff3d9e48857" data-action="Deal Block" data-label="iPhone 18 Pro: up to $480 off @ StraightTalk" data-dimension48="iPhone 18 Pro: up to $480 off @ StraightTalk" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="a1cee7fe-b5dc-11f1-a9da-c5e2fec625c8" data-action="Deal Block" data-label="iPhone 18 Pro" data-dimension48="iPhone 18 Pro" data-dimension25="$899" href="https://www.metrobyt-mobile.com/cell-phone/apple-iphone-18-pro" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:300px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="UrMF7jvSAWeMTgQPNEmbqD" name="metrobytmobilelogo.jpeg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/UrMF7jvSAWeMTgQPNEmbqD-1920-80.jpeg" mos="" align="middle" fullscreen="" width="300" height="300" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>Metro by T-Mobile is offering a handful of iPhone 18 Pro deals starting from $899. To get this price, you'll need to port your number to Metro by T-Mobile and set up AutoPay. You can also get it for $999 when you bring your number and opt for the $40 Period web plan. <a class="view-deal button" href="https://www.metrobyt-mobile.com/cell-phone/apple-iphone-18-pro" target="_blank" rel="nofollow" data-dimension112="a1cee7fe-b5dc-11f1-a9da-c5e2fec625c8" data-action="Deal Block" data-label="iPhone 18 Pro" data-dimension48="iPhone 18 Pro" data-dimension25="$899">View Deal</a></p></div><div class="product"><a data-dimension112="82ce65f8-b2dc-11f1-a8c6-7594da732413" data-action="Deal Block" data-label="iPhone 18 Pro: up to $885 w/ trade-in @ Apple Store" data-dimension48="iPhone 18 Pro: up to $885 w/ trade-in @ Apple Store" href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:66.67%;"><img id="4Y3oAjs2dPF6xp4nhVsVcc" name="Applelogo.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/4Y3oAjs2dPF6xp4nhVsVcc-1920-80.jpg" mos="" align="middle" fullscreen="" width="600" height="400" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro: </strong><a href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow" data-dimension112="82ce65f8-b2dc-11f1-a8c6-7594da732413" data-action="Deal Block" data-label="iPhone 18 Pro: up to $885 w/ trade-in @ Apple Store" data-dimension48="iPhone 18 Pro: up to $885 w/ trade-in @ Apple Store" data-dimension25=""><strong>up to $885 w/ trade-in @ Apple Store</strong></a><br>The Apple Store is offering up to a $885 credit when you trade-in your old smartphone for one of the new iPhone 18 Pro models. For example, an iPhone 15 will get you up to a $305 credit, whereas an iPhone 13 Pro will get you up to a $255 credit. The iPhone 18 Pro features a 6.3-inch OLED 120Hz display (2622 x 1206), A20 Pro chipset, and 256GB of storage. You also get a 48MP main, 48MP ultrawide, and 48MP telephoto lens w/ 4x zoom. The front camera is 18MP. <a class="view-deal button" href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow" data-dimension112="82ce65f8-b2dc-11f1-a8c6-7594da732413" data-action="Deal Block" data-label="iPhone 18 Pro: up to $885 w/ trade-in @ Apple Store" data-dimension48="iPhone 18 Pro: up to $885 w/ trade-in @ Apple Store" data-dimension25="">View Deal</a></p></div><h3 class="article-body__section" id="section-iphone-18-pro-max"><span>iPhone 18 Pro Max</span></h3><div class="product"><a data-dimension112="82ce6742-b2dc-11f1-a953-1dbfb96f129b" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" href="https://tmobilepostpaid.pxf.io/c/1943169/4032248/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:50.00%;"><img id="Y26QJd7Ff7aeQmTHuW8nCP" name="NEW T-Mobile Logo" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Y26QJd7Ff7aeQmTHuW8nCP-1920-80.png" mos="" align="middle" fullscreen="" width="600" height="300" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro Max: </strong><a href="https://tmobilepostpaid.pxf.io/c/1943169/4032248/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow" data-dimension112="82ce6742-b2dc-11f1-a953-1dbfb96f129b" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension25=""><strong>up to $1,200 off w/ trade-in + unlimited @ T-Mobile</strong></a><br>T-Mobile is taking up to $1,200 off the iPhone 18 Pro Max when you trade-in an old device and sign up for an eligible unlimited data plan. <a class="view-deal button" href="https://tmobilepostpaid.pxf.io/c/1943169/4032248/38171?subId1=hawk-custom-tracking" target="_blank" rel="nofollow" data-dimension112="82ce6742-b2dc-11f1-a953-1dbfb96f129b" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ trade-in + unlimited @ T-Mobile" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce66de-b2dc-11f1-8e7a-f98b3d9ab0c5" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ new line + trade-in @ Verizon" href="https://www.verizon.com/smartphones/apple-iphone-18-pro-max/?isMyPlanFlow=true" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3321px;"><p class="vanilla-image-block" style="padding-top:40.98%;"><img id="R4vXmWQKAkSdQs7bVstjs8" name="Verizon logo 2024.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/R4vXmWQKAkSdQs7bVstjs8-1920-80.jpg" mos="" align="middle" fullscreen="" width="3321" height="1361" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro Max: </strong><a href="https://www.verizon.com/smartphones/apple-iphone-18-pro-max/?isMyPlanFlow=true" target="_blank" rel="nofollow" data-dimension112="82ce66de-b2dc-11f1-8e7a-f98b3d9ab0c5" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension25=""><strong>up to $1,200 off w/ new line + trade-in @ Verizon</strong></a><br>Verizon will take up to $1,200 off your iPhone 18 Pro Max when you open a new line, trade-in an old phone, and open an eligible unlimited data plan. In our <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max review</a>, we said the A20 chip raises the bar for performance in a smartphone. It features a 6.9-inch OLED 120Hz display (2868 x 1320), A20 Pro chipset, and 256GB of storage. You also get a 48MP main, 48MP ultrawide, and 48MP telephoto lens w/ 4x zoom. The front camera is 18MP. <a class="view-deal button" href="https://www.verizon.com/smartphones/apple-iphone-18-pro-max/?isMyPlanFlow=true" target="_blank" rel="nofollow" data-dimension112="82ce66de-b2dc-11f1-8e7a-f98b3d9ab0c5" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ new line + trade-in @ Verizon" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce67a6-b2dc-11f1-b48a-177831517a30" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ new line or trade @ AT&amp;T" href="https://www.att.com/buy/phones/apple-iphone-18-pro-max.html" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:225px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="o9PdShQsgAk95AN7C5UMNR" name="AT&T Logo.jpeg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/o9PdShQsgAk95AN7C5UMNR-1920-80.jpeg" mos="" align="middle" fullscreen="" width="225" height="225" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro Max: </strong><a href="https://www.att.com/buy/phones/apple-iphone-18-pro.html" target="_blank" rel="nofollow" data-dimension112="82ce67a6-b2dc-11f1-b48a-177831517a30" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension25=""><strong>up to $1,200 off w/ new line or trade @ AT&T</strong></a><br>New and existing AT&T customers can get up to $1,200 off the iPhone 18 Pro Max when you trade-in any iPhone in any condition. New customers can also get up to $800 to pay off any devices that are still in contract. <a class="view-deal button" href="https://www.att.com/buy/phones/apple-iphone-18-pro-max.html" target="_blank" rel="nofollow" data-dimension112="82ce67a6-b2dc-11f1-b48a-177831517a30" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension48="iPhone 18 Pro Max: up to $1,200 off w/ new line or trade @ AT&amp;T" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce680a-b2dc-11f1-aa5a-d9c45db6d226" data-action="Deal Block" data-label="iPhone 18 Pro Max: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension48="iPhone 18 Pro Max: free w/ trade-in + unlimited @ Xfinity Mobile" href="https://www.xfinity.com/learn/mobile" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1413px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="MEg942YDCTSzn9H3vsaqPj" name="xfinity-mobile.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/MEg942YDCTSzn9H3vsaqPj-1920-80.jpg" mos="" align="middle" fullscreen="" width="1413" height="1413" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro Max: </strong><a href="https://www.xfinity.com/learn/mobile" target="_blank" rel="nofollow" data-dimension112="82ce680a-b2dc-11f1-aa5a-d9c45db6d226" data-action="Deal Block" data-label="iPhone 18 Pro Max: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension48="iPhone 18 Pro Max: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension25=""><strong>free w/ trade-in + unlimited @ Xfinity Mobile</strong></a><br>New and existing Xfinity Mobile customers can get the iPhone 18 Pro Max for free with a Mobile Plus plan and trade-in. New customers must activate a new Xfinity Mobile line within 30 days of purchase, whereas existing customers can upgrade one of their existing lines to receive the deal. <a class="view-deal button" href="https://www.xfinity.com/learn/mobile" target="_blank" rel="nofollow" data-dimension112="82ce680a-b2dc-11f1-aa5a-d9c45db6d226" data-action="Deal Block" data-label="iPhone 18 Pro Max: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension48="iPhone 18 Pro Max: free w/ trade-in + unlimited @ Xfinity Mobile" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="1b91468c-b389-11f1-9e88-9394227d2ca7" data-action="Deal Block" data-label="iPhone 18 Pro Max" data-dimension48="iPhone 18 Pro Max" data-dimension25="$1199" href="https://www.redpocket.com/shop/iphone/apple-iphone-18-pro-max-unlocked" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:374px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="2Rb63M2Ym3t5t2s8BWCeLK" name="Red Pocket Mobile logo" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/2Rb63M2Ym3t5t2s8BWCeLK-1920-80.png" mos="" align="middle" fullscreen="" width="374" height="374" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>RedPocket Mobile is an MVNO that lets you choose between using AT&T's, T-Mobile's, or Verizon's network. Right now, you can get the iPhone 18 Pro Max for $1,199 ($100 off) with no port or trade-in required. Unlimited data plans start from $10/month or $100/year. <a class="view-deal button" href="https://www.redpocket.com/shop/iphone/apple-iphone-18-pro-max-unlocked" target="_blank" rel="nofollow" data-dimension112="1b91468c-b389-11f1-9e88-9394227d2ca7" data-action="Deal Block" data-label="iPhone 18 Pro Max" data-dimension48="iPhone 18 Pro Max" data-dimension25="$1199">View Deal</a></p></div><div class="product"><a data-dimension112="82ce686e-b2dc-11f1-8178-3d37da490693" data-action="Deal Block" data-label="Visible: $480 off w/ new iPhone @ Visible" data-dimension48="Visible: $480 off w/ new iPhone @ Visible" href="https://www.visible.com/shop/smartphones/iphone-18-pro-max?sku=MJW64LL/A" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1000px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="nXRVmdXfPxa8NUZ7ukyY7P" name="visible_logo_new.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/nXRVmdXfPxa8NUZ7ukyY7P-1920-80.jpg" mos="" align="middle" fullscreen="" width="1000" height="1000" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>Visible: </strong><a href="https://www.visible.com/shop/smartphones/iphone-18-pro-max?sku=MJW64LL/A" target="_blank" rel="nofollow" data-dimension112="82ce686e-b2dc-11f1-8178-3d37da490693" data-action="Deal Block" data-label="Visible: $480 off w/ new iPhone @ Visible" data-dimension48="Visible: $480 off w/ new iPhone @ Visible" data-dimension25=""><strong>$480 off w/ new iPhone @ Visible</strong></a><br>Buy any new iPhone with the Visible+ Pro plan and you'll get $480 back via monthly credits over the span of 24 months. Visible+ Pro costs $45/month and includes unlimited premium data on Verizon's 5G Ultra Wideband network, smartwatch data plan service, and up to 4K UHD video streaming. <a class="view-deal button" href="https://www.visible.com/shop/smartphones/iphone-18-pro-max?sku=MJW64LL/A" target="_blank" rel="nofollow" data-dimension112="82ce686e-b2dc-11f1-8178-3d37da490693" data-action="Deal Block" data-label="Visible: $480 off w/ new iPhone @ Visible" data-dimension48="Visible: $480 off w/ new iPhone @ Visible" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce68d2-b2dc-11f1-b6cc-9976746ccc61" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $600 off w/ unlimited @ Total Wireless" data-dimension48="iPhone 18 Pro Max: up to $600 off w/ unlimited @ Total Wireless" href="https://www.totalwireless.com/m/home" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="Z3gikFPLPLmWFv4RSSgxVh" name="total-square.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Z3gikFPLPLmWFv4RSSgxVh-1920-80.jpg" mos="" align="middle" fullscreen="" width="600" height="600" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro Max: </strong><a href="https://www.totalwireless.com/m/home" target="_blank" rel="nofollow" data-dimension112="82ce68d2-b2dc-11f1-b6cc-9976746ccc61" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $600 off w/ unlimited @ Total Wireless" data-dimension48="iPhone 18 Pro Max: up to $600 off w/ unlimited @ Total Wireless" data-dimension25=""><strong>up to $600 off w/ unlimited @ Total Wireless</strong></a><br>Total Wireless is taking up to $600 off the iPhone 18 Pro Max. You'll get a $25/monthly bill credit (over 24 months) when you stay on Total Wireless' All Access plan. <a class="view-deal button" href="https://www.totalwireless.com/m/home" target="_blank" rel="nofollow" data-dimension112="82ce68d2-b2dc-11f1-b6cc-9976746ccc61" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $600 off w/ unlimited @ Total Wireless" data-dimension48="iPhone 18 Pro Max: up to $600 off w/ unlimited @ Total Wireless" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce692c-b2dc-11f1-8b05-f3e8419612da" data-action="Deal Block" data-label="iPhone 18 Pro Max: from $34/month @ Walmart" data-dimension48="iPhone 18 Pro Max: from $34/month @ Walmart" href="https://www.walmart.com/ip/Verizon-iPhone-18-Pro-Max-256GB-Black/20995618639" 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:93.65%;"><img id="Bi2iDjTxUHTUQK9FHZ4W8D" name="Walmart logo.jpeg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Bi2iDjTxUHTUQK9FHZ4W8D-1920-80.jpeg" mos="" align="middle" fullscreen="" width="960" height="899" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro Max: </strong><a href="https://www.walmart.com/ip/Verizon-iPhone-18-Pro-Max-256GB-Black/20995618639" target="_blank" rel="nofollow" data-dimension112="82ce692c-b2dc-11f1-8b05-f3e8419612da" data-action="Deal Block" data-label="iPhone 18 Pro Max: from $34/month @ Walmart" data-dimension48="iPhone 18 Pro Max: from $34/month @ Walmart" data-dimension25=""><strong>from $34/month @ Walmart</strong></a><br>Walmart is offering the iPhone 18 Pro Max for AT&T, Verizon, or T-Mobile from $34/month. The phone is available in all colors and storage capacities, although some models are starting to sell out. <a class="view-deal button" href="https://www.walmart.com/ip/Verizon-iPhone-18-Pro-Max-256GB-Black/20995618639" target="_blank" rel="nofollow" data-dimension112="82ce692c-b2dc-11f1-8b05-f3e8419612da" data-action="Deal Block" data-label="iPhone 18 Pro Max: from $34/month @ Walmart" data-dimension48="iPhone 18 Pro Max: from $34/month @ Walmart" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="1b914768-b389-11f1-af80-2d0958ab4a44" data-action="Deal Block" data-label="iPhone 18 Pro Max" data-dimension48="iPhone 18 Pro Max" data-dimension25="$1099" href="https://www.boostmobile.com/shop/iphone-18-pro-max.html" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:713px;"><p class="vanilla-image-block" style="padding-top:38.85%;"><img id="UGYgmHB5HuHtAFmJHSMZnU" name="Boost Mobile logo 2024.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/UGYgmHB5HuHtAFmJHSMZnU-1920-80.jpg" mos="" align="middle" fullscreen="" width="713" height="277" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>Boost Mobile is offering the iPhone 18 Pro Max for $1,099 when you bring your line and sign up for Boost's Unlimited Premium plan ($60/month). The plan includes unlimited talk, text, and 50GB of premium/high-speed data as well as global talk/text and mobile hotspot. Or you can get it for $1,199 when you open a new Unlimited Premium plan. <a class="view-deal button" href="https://www.boostmobile.com/shop/iphone-18-pro-max.html" target="_blank" rel="nofollow" data-dimension112="1b914768-b389-11f1-af80-2d0958ab4a44" data-action="Deal Block" data-label="iPhone 18 Pro Max" data-dimension48="iPhone 18 Pro Max" data-dimension25="$1099">View Deal</a></p></div><div class="product"><a data-dimension112="82ce6990-b2dc-11f1-9036-e58cd9024ab9" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $480 off @ StraightTalk" data-dimension48="iPhone 18 Pro Max: up to $480 off @ StraightTalk" href="https://www.straighttalk.com/all-phones/apple-iphone-18-pro-max-512gb-prepaid" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:264px;"><p class="vanilla-image-block" style="padding-top:72.35%;"><img id="jg63LBik54HBQtDrbyFRh8" name="StraightTalk logo.png" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/jg63LBik54HBQtDrbyFRh8-1920-80.png" mos="" align="middle" fullscreen="" width="264" height="191" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro Max: </strong><a href="https://www.straighttalk.com/all-phones/apple-iphone-18-pro-max-512gb-prepaid" target="_blank" rel="nofollow" data-dimension112="82ce6990-b2dc-11f1-9036-e58cd9024ab9" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $480 off @ StraightTalk" data-dimension48="iPhone 18 Pro Max: up to $480 off @ StraightTalk" data-dimension25=""><strong>up to $480 off @ StraightTalk</strong></a><br>StraightTalk is taking up to $480 off the iPhone 18 Pro Max. You'll get $20 off your monthly bill over the span of 24 months when you activate a Gold Unlimited plan or higher. <a class="view-deal button" href="https://www.straighttalk.com/all-phones/apple-iphone-18-pro-max-512gb-prepaid" target="_blank" rel="nofollow" data-dimension112="82ce6990-b2dc-11f1-9036-e58cd9024ab9" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $480 off @ StraightTalk" data-dimension48="iPhone 18 Pro Max: up to $480 off @ StraightTalk" data-dimension25="">View Deal</a></p></div><div class="product"><a data-dimension112="82ce69f4-b2dc-11f1-97e1-9540a7192b09" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $885 w/ trade-in @ Apple Store" data-dimension48="iPhone 18 Pro Max: up to $885 w/ trade-in @ Apple Store" href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:600px;"><p class="vanilla-image-block" style="padding-top:66.67%;"><img id="4Y3oAjs2dPF6xp4nhVsVcc" name="Applelogo.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/4Y3oAjs2dPF6xp4nhVsVcc-1920-80.jpg" mos="" align="middle" fullscreen="" width="600" height="400" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong>iPhone 18 Pro Max: </strong><a href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow" data-dimension112="82ce69f4-b2dc-11f1-97e1-9540a7192b09" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $885 w/ trade-in @ Apple Store" data-dimension48="iPhone 18 Pro Max: up to $885 w/ trade-in @ Apple Store" data-dimension25=""><strong>up to $885 w/ trade-in @ Apple Store</strong></a><br>The Apple Store is offering up to a $885 credit when you trade-in your old smartphone for one of the new iPhone 18 Pro Max models. For example, an iPhone 15 will get you up to a $305 credit, whereas an iPhone 13 Pro will get you up to a $255 credit. The iPhone 18 Pro Max features a 6.9-inch OLED 120Hz display (2868 x 1320), A20 Pro chipset, and 256GB of storage. You also get a 48MP main, 48MP ultrawide, and 48MP telephoto lens w/ 4x zoom. The front camera is 18MP. <a class="view-deal button" href="https://www.apple.com/shop/trade-in" target="_blank" rel="nofollow" data-dimension112="82ce69f4-b2dc-11f1-97e1-9540a7192b09" data-action="Deal Block" data-label="iPhone 18 Pro Max: up to $885 w/ trade-in @ Apple Store" data-dimension48="iPhone 18 Pro Max: up to $885 w/ trade-in @ Apple Store" data-dimension25="">View Deal</a></p></div><h3 class="article-body__section" id="section-shop-more-deals"><span>Shop more deals</span></h3><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?brands=Apple&rows=6&view_mode=savings_squad&widget_title=Top+Deals+Handpicked+by+Our+Editors&widget_subtitle=Discover+the+best+discounts+currently+available%2C+curated+daily+by+the+Tom%27s+Guide+Savings+Squad.&bg_color=transparent" data-vizualizer-embed="true"></div>    <script>    /**     * Tom's Guide Deals Finder - Vanilla JS Encapsulated Engine     */    (function() {      // --- Freyr Analytics Adapter ---      function initAnalytics() {        window.dataLayer = window.dataLayer || [];        window.googletag = window.googletag || {};        window.googletag.cmd = window.googletag.cmd || [];        window.hawk = window.hawk || { analytics: { freyr: [] } };        window.hawk.analytics = window.hawk.analytics || { freyr: [] };        window.hawk.analytics.freyr = window.hawk.analytics.freyr || [];        window.freyr = window.freyr || { cmd: [] };        const scriptSrc = 'https://freyr.futurecdn.net/freyr.js';        const hostname = typeof window !== 'undefined' ? window.location.hostname : '';        const isTestEnv = typeof window.navigator !== 'undefined' && (window.navigator.webdriver || window.navigator.userAgent.includes('Headless'));        const shouldSendRealAnalytics = !isTestEnv && hostname && hostname !== 'localhost' && hostname !== '127.0.0.1' && !hostname.includes('run.app');        if (shouldSendRealAnalytics && !document.querySelector(`script[src="${scriptSrc}"]`)) {          const script = document.createElement('script');          script.src = scriptSrc;          script.async = true;          document.head.appendChild(script);        }      }      function storeEventForDebug(name, data) {        if (!window.hawk || !window.hawk.analytics || !window.hawk.analytics.freyr) return;        window.hawk.analytics.freyr.push({ name, data });        try {          if (typeof window !== 'undefined' && window.localStorage) {            window.localStorage.setItem("hawk", JSON.stringify(window.hawk));          }        } catch (e) {          // Ignore storage issues        }        try {          window.dispatchEvent(new CustomEvent("hawk-analytics-update"));        } catch (e) {}      }      function sendToFreyr(eventName, data) {        if (typeof window === 'undefined') return;        window.freyr = window.freyr || { cmd: [] };        window.freyr.cmd.push(() => {          if (window.freyr && window.freyr.pushAndUpdate) {            window.freyr.pushAndUpdate(eventName, data);          }        });      }      function sendEvent(event, skip = false) {        try {          storeEventForDebug(event.name, event.data);          if (!skip) {            sendToFreyr(event.name, event.data);          }        } catch (e) {          // Ensure tracking errors don't surface to the user        }      }      function getCookie(name) {        try {          const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));          return match ? match[2] : null;        } catch (e) {          return null;        }      }      function getTimeAgo(dateString) {        if (!dateString) return '';        const date = new Date(dateString);        const now = new Date();        const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);        if (diffInSeconds < 60) return 'Just now';        const diffInMinutes = Math.floor(diffInSeconds / 60);        if (diffInMinutes < 60) return `${diffInMinutes} min${diffInMinutes > 1 ? 's' : ''} ago`;        const diffInHours = Math.floor(diffInMinutes / 60);        if (diffInHours < 24) return `${diffInHours} hr${diffInHours > 1 ? 's' : ''} ago`;        const diffInDays = Math.floor(diffInHours / 24);        if (diffInDays < 30) return `${diffInDays} day${diffInDays > 1 ? 's' : ''} ago`;        const diffInMonths = Math.floor(diffInDays / 30);        if (diffInMonths < 12) return `${diffInMonths} mo${diffInMonths > 1 ? 's' : ''} ago`;        const diffInYears = Math.floor(diffInDays / 365);        return `${diffInYears} yr${diffInYears > 1 ? 's' : ''} ago`;      }      function normalizeCurrency(symbol) {        const map = {          '£': 'GBP',          '$': 'USD',          'A$': 'AUD',          'CA$': 'CAD',          '€': 'EUR'        };        return map[symbol] || symbol;      }      function trackElementInteraction(props) {        sendEvent({          name: 'elementInteraction',          data: {            element: {              action: props.action || "click",              id: props.id || undefined,              class: props.class || undefined,              name: props.name || undefined,              text: props.text || undefined,              label: props.label || undefined,              container: props.container || undefined,              url: props.url || undefined,              articleId: props.articleId || undefined            }          }        });      }      function generateRevenueId(url, productName, merchantName, modelId) {        const str = `${window.location.href}|${productName}|${merchantName}|${modelId || ''}|${new Date().toDateString()}|tomsguide`;        let hash = 0;        for (let i = 0; i < str.length; i++) {          const char = str.charCodeAt(i);          hash = ((hash << 5) - hash) + char;          hash = hash & hash;        }        let numericStr = Math.abs(hash).toString();        while (numericStr.length < 19) {          numericStr += Math.floor(Math.random() * 10).toString();        }        return numericStr.substring(0, 19);      }      function rewriteAffiliateLink(url, territory, revenueId) {        if (!url) return url;        const t = (territory || 'gb').toLowerCase();        return url.replace(/hawk-custom-tracking/g, `tomsguide-${t}-${revenueId}`);      }      function trackHawkEvent(params) {        const { clickType, widgetId, productCategoryName, product, productsArray, zeroBasedProductIndexOrNull, totalDealsOrProducts, areaClicked, merchant, revenueId, isoCurrencyCode, queryName, widgetTypeName } = params;        const data = {          event: "hawkEvent",          category: "Affiliates",          affiliate: {            action: {              type: clickType,              id: widgetId,              event: clickType === "appeared" ? "viewed" : "Click from",              timestamp: Date.now()            },            component: {              flag: "Editor",              product: productCategoryName || "deals",              category: `Signal Deal Finder ${widgetTypeName || "Carousel"} widget`,              type: clickType === "appeared" ? "review" : "signal product",              label: queryName || (product ? (product.name || "") : ""),              index: zeroBasedProductIndexOrNull === null || zeroBasedProductIndexOrNull === undefined ? -1 : zeroBasedProductIndexOrNull,              linkCount: totalDealsOrProducts || 0,              blockLayout: "",              areaClicked: areaClicked || ""            }          },          products: productsArray || (product && merchant ? [            {              product: {                primary: {                  id: product.id || product.matchId || null,                  name: product.name,                  type: "deal",                  price: product.price,                  previousPrice: product.previousPrice || null,                  currency: isoCurrencyCode || "USD",                  preorder: false,                  labels: [],                  link: product.link,                  originalLink: product.originalLink || null,                  revenueId: revenueId || null,                  startTime: null,                  endTime: null,                  voucherCode: null,                  voucherAudience: null,                  voucherPercentageSaving: null,                  voucherMoneySaving: null,                  voucherType: null,                  offerExclusive: false,                  offerScope: null,                  globalId: product.globalId || null,                  inStock: product.inStock !== false,                  contractProvider: null,                  contractMinutes: null,                  contractTexts: null,                  contractData: null,                  contractLength: null,                  contractMonthlyPrice: null,                  contractCurrency: isoCurrencyCode || "USD"                }              },              merchant: {                id: merchant.id || null,                name: merchant.name,                url: merchant.url || null,                network: merchant.network || null              },              model: {                id: product.modelId || null,                brand: product.brand || null,                name: product.name,                parent: product.parent || null              }            }          ] : []),          reviews: [],          _clear: true,          "gtm.uniqueEventId": Date.now() % 10000        };        sendEvent({ name: 'hawkEvent', data });      }      function trackDealClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Product Card" });      }      function trackViewSimilarClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Product Card View Similar" });      }      function trackPriceComparisonClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Price Comparison" });      }      function trackReviewClick(params) {        trackHawkEvent({ ...params, clickType: "review", areaClicked: "Signal Product Card Review Link" });      }      function trackShare(params) {        trackHawkEvent({ ...params, clickType: "share", areaClicked: "Signal Product Card Share" });      }      function trackDealsAppeared(widgetId, deals, revenueId, currency, queryName, widgetTypeName) {         if (!deals || deals.length === 0) return;                  const productsArray = deals.slice(0, 50).map((deal) => {            let voucherPct = null;            let rawPrice = parseFloat(deal.rawPrice) || parseFloat(deal.price) || null;            let rawMsrp = parseFloat(deal.rawMsrp) || parseFloat(deal.msrp) || null;            if (rawMsrp > rawPrice && rawPrice > 0) {              voucherPct = Math.round((1 - (rawPrice / rawMsrp)) * 100);            }            let numId = null;            if (deal.externalProductId && !isNaN(parseInt(deal.externalProductId))) {              numId = parseInt(deal.externalProductId);            } else if (deal.id && !isNaN(parseInt(deal.id))) {              numId = parseInt(deal.id);            } else {              numId = deal.matchId || null;            }            return {              product: {                primary: {                  id: numId,                  name: deal.productName || deal.title || "",                  type: "deal",                  price: rawPrice,                  previousPrice: rawMsrp,                  currency: currency || 'USD',                  preorder: false,                  labels: deal.modelBrand || deal.brand ? [                     { type: "brand", value: deal.modelBrand || deal.brand }                  ] : [],                  link: deal.url,                  originalLink: deal.url,                  revenueId: revenueId || null,                  startTime: null,                  endTime: null,                  voucherCode: null,                  voucherAudience: null,                  voucherPercentageSaving: voucherPct,                  voucherMoneySaving: null,                  voucherType: null,                  offerExclusive: false,                  offerScope: null,                  globalId: deal.productKey || null,                  inStock: deal.inStock !== false,                  contractProvider: null,                  contractMinutes: null,                  contractTexts: null,                  contractData: null,                  contractLength: null,                  contractMonthlyPrice: null,                  contractCurrency: currency || 'USD'                }              },              merchant: {                id: deal.merchantId ? parseInt(deal.merchantId) : null,                name: deal.merchant || "Retailer",                url: deal.merchantUrl || null,                network: deal.merchantNetwork || null              },              model: {                id: deal.modelId ? parseInt(deal.modelId) : null,                brand: deal.modelBrand || deal.brand || null,                name: deal.productName || deal.title || "",                parent: deal.modelParent || null              }            };         });                  trackHawkEvent({             clickType: "appeared",             widgetId: widgetId,             productCategoryName: "deals",             zeroBasedProductIndexOrNull: null,             totalDealsOrProducts: deals.length,             productsArray: productsArray,             queryName: queryName,             widgetTypeName: widgetTypeName         });      }      // 1. Setup Shadow DOM Sandbox      const currentScript = document.currentScript;      let hostContainer = null;      let template = null;            if (currentScript) {        let prev = currentScript.previousElementSibling;        while (prev) {          if (prev.tagName === 'TEMPLATE' && prev.classList.contains('tg-df-widget-template')) {            template = prev;          } else if (prev.tagName === 'DIV' && prev.classList.contains('tg-df-widget-host') && !prev.hasAttribute('data-initialized')) {            hostContainer = prev;            break;          }          prev = prev.previousElementSibling;        }      }            // Fallbacks in case script is deferred      if (!hostContainer) {        const hosts = document.querySelectorAll('.tg-df-widget-host:not([data-initialized])');        if (hosts.length > 0) hostContainer = hosts[0];      }            // Safely embedded template for CMS environments      const rawTemplate = `  \x3Cstyle>    /* --- Shadow DOM Base Reset --- */    *, *::before, *::after {      box-sizing: border-box;    }    img, picture, svg, video {      max-width: 100%;      height: auto;      display: block;    }    /*       1. Scoped CSS for Tom's Guide Deals Widget       All classes are prefixed with \`tg-df-\` to prevent CMS style leakage.    */    .tg-df-container {      container-type: inline-size;      container-name: tg-df;      --tg-df-blue: #1F69FF;      --tg-df-blue-hover: #004d8c;      --tg-df-text: #222222;      --tg-df-text-muted: #555555;      --tg-df-bg: #ffffff;      --tg-df-bg-secondary: #f4f4f4;      --tg-df-border: #e2e8f0;      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;      color: var(--tg-df-text);      background-color: transparent;       width: 100%;      max-width: 1200px;      margin: 0 auto;      padding-bottom: 24px;    }    .tg-df-container *, .tg-df-container *::before, .tg-df-container *::after {      margin: 0;      padding: 0;      box-sizing: border-box;    }    .tg-df-container img {      border: none;      margin: 0;      padding: 0;    }    .tg-df-container a {      text-decoration: none;      color: inherit;    }    /*       2. Search & Filter Bar    */    .tg-df-controls {      display: flex;      flex-direction: column;      align-items: center;      gap: 20px;      margin-bottom: 32px;      width: 100%;      position: relative;      z-index: 20;    }    .tg-df-top-bar {      display: flex;      width: 100%;      max-width: 760px;      gap: 12px;      margin: 0 auto;      align-items: center;    }    .tg-df-search-wrapper {      position: relative;      flex: 1;      width: 100%;      box-shadow: 0 8px 24px rgba(0,0,0,0.06);      border-radius: 40px;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      z-index: 100;    }    .tg-df-autocomplete-dropdown {      position: absolute;      top: calc(100% + 4px);      left: 0;      right: 0;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 12px;      box-shadow: 0 8px 32px rgba(0,0,0,0.12);      max-height: 300px;      overflow-y: auto;      z-index: 200;      display: none;    }    .tg-df-autocomplete-dropdown.active {      display: block;    }    .tg-df-autocomplete-item {      padding: 12px 24px;      cursor: pointer;      font-size: 14px;      color: var(--tg-df-text);      transition: background 0.1s ease;    }    .tg-df-autocomplete-item:hover {      background: var(--tg-df-bg-secondary);    }    .tg-df-search-input {      width: 100%;      padding: 16px 64px 16px 24px;      font-size: 16px;      border: 2px solid transparent;      border-radius: 40px;      outline: none;      transition: border-color 0.2s ease, box-shadow 0.2s ease;      color: var(--tg-df-text);      background: transparent;    }    .tg-df-search-input:focus {      border-color: transparent;      box-shadow: 0 0 0 3px rgba(0, 108, 196, 0.15);    }    .tg-df-search-input::placeholder {      color: #999999;    }        .tg-df-search-btn {      position: absolute;      right: 8px;      top: 50%;      transform: translateY(-50%);      width: 40px;      height: 40px;      border-radius: 50%;      background: #222;      border: none;      display: flex;      align-items: center;      justify-content: center;      cursor: pointer;      transition: background 0.2s ease;    }        .tg-df-search-btn:hover {      background: #000;    }    .tg-df-search-icon {      width: 16px;      height: 16px;      fill: #fff;    }    .tg-df-settings-wrapper {      position: relative;    }        .tg-df-settings-btn {      width: 48px;      height: 48px;      border-radius: 50%;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      box-shadow: 0 4px 12px rgba(0,0,0,0.04);      display: flex;      align-items: center;      justify-content: center;      cursor: pointer;      transition: all 0.2s ease;      color: var(--tg-df-text-muted);      flex-shrink: 0;    }    .tg-df-settings-btn:hover {      background: var(--tg-df-bg-secondary);      border-color: #0000ff;      color: var(--tg-df-text);    }    .tg-df-settings-btn svg {      width: 24px;      height: 24px;      fill: currentColor;    }    .tg-df-settings-dropdown {      position: absolute;      top: calc(100% + 8px);      right: 0;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 12px;      box-shadow: 0 8px 32px rgba(0,0,0,0.12);      width: 280px;      padding: 20px;      display: none;      z-index: 100;      flex-direction: column;      gap: 20px;    }    .tg-df-settings-dropdown.active {      display: flex;    }        .tg-df-settings-dropdown-backdrop {      display: none;      position: fixed;      inset: 0;      z-index: 99;    }        .tg-df-settings-dropdown-backdrop.active {      display: block;    }    .tg-df-setting-item {      display: flex;      flex-direction: column;      gap: 10px;    }    .tg-df-setting-label {      font-size: 11px;      font-weight: 700;      color: var(--tg-df-text-muted);      text-transform: uppercase;      letter-spacing: 0.5px;    }        .tg-df-region-select {        padding: 10px 12px;        border-radius: 8px;        border: 1px solid var(--tg-df-border);        font-size: 15px;        outline: none;        background: var(--tg-df-bg-secondary);        color: var(--tg-df-text);        cursor: pointer;        width: 100%;    }    .tg-df-toggle {        position: relative;        display: inline-block;        width: 44px;        height: 24px;        flex-shrink: 0;    }    .tg-df-toggle input {        opacity: 0;        width: 0;        height: 0;    }    .tg-df-slider {        position: absolute;        cursor: pointer;        top: 0; left: 0; right: 0; bottom: 0;        background-color: #ccc;        transition: .2s;        border-radius: 24px;    }    .tg-df-slider:before {        position: absolute;        content: "";        height: 18px;        width: 18px;        left: 3px;        bottom: 3px;        background-color: white;        transition: .2s;        border-radius: 50%;    }    .tg-df-toggle input:checked + .tg-df-slider {        background-color: #1F69FF;    }    .tg-df-toggle input:checked + .tg-df-slider:before {        transform: translateX(20px);    }    .tg-df-dl-row {        flex-direction: row;        align-items: center;        justify-content: space-between;    }    .tg-df-dl-row-text {        font-size: 14px;        font-weight: 600;        color: var(--tg-df-text);    }    .tg-df-dl-row-subtext {        font-size: 12px;        font-weight: 400;        line-height: 1.3;        color: var(--tg-df-text-muted);        margin-top: 4px;        display: block;    }    .tg-df-filters-container {      position: relative;      width: 100%;      max-width: 800px;    }    .tg-df-scroll-btn {      display: none;      position: absolute;      top: 50%;      transform: translateY(-50%);      width: 32px;      height: 32px;      background: white;      border: 1px solid var(--tg-df-border);      border-radius: 50%;      align-items: center;      justify-content: center;      cursor: pointer;      z-index: 10;      box-shadow: 0 2px 8px rgba(0,0,0,0.1);      color: var(--tg-df-text-primary);      padding: 0;    }    .tg-df-scroll-btn svg {      width: 16px;      height: 16px;    }    .tg-df-scroll-btn:hover {      background: #f4f4f4;    }    .tg-df-scroll-btn.left {      left: 0px;    }    .tg-df-scroll-btn.right {      right: 0px;    }    @container tg-df (max-width: 768px) {      .tg-df-scroll-btn {        display: flex;        top: 22px; /* vertically center within the 44px high filter buttons */      }    }    .tg-df-filters {      display: grid;      width: 100%;      grid-template-columns: repeat(4, 1fr);      gap: 12px;      margin: 0 auto;      max-width: 800px;    }                 .tg-df-sort-wrapper {      position: relative;      display: flex;      align-items: center;      width: 100%;    }        .tg-df-sort-icon {      position: absolute;      left: 14px;      width: 14px;      height: 14px;      fill: var(--tg-df-text-muted);      pointer-events: none;    }    .tg-df-sort-select, .tg-df-filter-select {      width: 100%;      padding: 10px 36px 10px 38px;      font-size: 14px;      border: 1px solid var(--tg-df-border);      border-radius: 100px;      outline: none;      appearance: none;      background-color: var(--tg-df-bg-secondary);      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12'%3E%3Cpath fill='%23555555' d='M6 8L1 3h10z'/%3E%3C/svg%3E");      background-repeat: no-repeat;      background-position: right 14px center;      color: var(--tg-df-text);      cursor: pointer;      font-weight: 500;      transition: all 0.2s ease;    }        .tg-df-price-input::-webkit-outer-spin-button,    .tg-df-price-input::-webkit-inner-spin-button {      -webkit-appearance: none;      margin: 0;    }    .tg-df-price-input {      -moz-appearance: textfield;    }    .tg-df-sort-select:hover, .tg-df-filter-select:hover {      background-color: #e2e8f0;    }    .tg-df-multiselect-container {      position: relative;    }    @container tg-df (max-width: 768px) {      .tg-df-filters-container {      position: relative;      width: 100%;      max-width: 800px;    }    .tg-df-scroll-btn {      display: none;      position: absolute;      top: 50%;      transform: translateY(-50%);      width: 32px;      height: 32px;      background: white;      border: 1px solid var(--tg-df-border);      border-radius: 50%;      align-items: center;      justify-content: center;      cursor: pointer;      z-index: 10;      box-shadow: 0 2px 8px rgba(0,0,0,0.1);      color: var(--tg-df-text-primary);      padding: 0;    }    .tg-df-scroll-btn svg {      width: 16px;      height: 16px;    }    .tg-df-scroll-btn:hover {      background: #f4f4f4;    }    .tg-df-scroll-btn.left {      left: 0px;    }    .tg-df-scroll-btn.right {      right: 0px;    }    @container tg-df (max-width: 768px) {      .tg-df-scroll-btn {        display: flex;        top: 22px; /* vertically center within the 44px high filter buttons */      }    }    .tg-df-filters {        width: 100%;        margin: 0;        margin-bottom: -320px;        padding: 0 16px 320px 16px;        display: flex;        flex-wrap: nowrap;        gap: 8px;        overflow-x: auto;        overflow-y: hidden;        pointer-events: none;        scrollbar-width: none;        -webkit-overflow-scrolling: touch;      }      .tg-df-filters::-webkit-scrollbar {        display: none;      }      .tg-df-sort-wrapper {        pointer-events: auto;        flex: 0 0 auto;        width: 175px;        min-width: 175px;      }    }        .tg-df-multiselect-trigger {      display: block;      background: #fff;      user-select: none;      width: 100%;      overflow: hidden;      white-space: nowrap;      text-overflow: ellipsis;    }        .tg-df-multiselect-dropdown {      display: none;      position: absolute;      top: calc(100% + 4px);      left: 0;      width: 100%;      min-width: 220px;      max-height: 300px;      overflow-y: auto;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 8px;      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);      z-index: 100;      padding: 8px 0;    }    .tg-df-multiselect-dropdown.active {      display: block;    }    .tg-df-ms-option {      padding: 8px 16px;      display: flex;      align-items: center;      gap: 8px;      cursor: pointer;      font-size: 14px;    }    .tg-df-ms-option:hover {      background-color: var(--tg-df-bg-secondary);    }        .tg-df-ms-option input {      cursor: pointer;      accent-color: #1f69ff;    }    .tg-df-sort-select:focus, .tg-df-filter-select:focus {      border-color: #0000ff;      box-shadow: 0 0 0 3px rgba(0, 0, 255, 0.2);      background-color: var(--tg-df-bg);    }    /*       3. Deal Grid Layout    */    .tg-df-grid.tg-df-grid-auto {      padding-top: 24px;    }    .tg-df-grid, .tg-df-grid.layout-grid {      display: grid;      grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));      gap: 10px;    }    .tg-df-grid.layout-row {      grid-template-columns: 1fr;      gap: 16px;    }        .tg-df-grid.layout-row .tg-df-card {      flex-direction: row;      align-items: stretch;      height: auto;      box-shadow: none;      border-bottom: 1px solid var(--tg-df-border);    }    .tg-df-grid.layout-row .tg-df-card:hover {      box-shadow: none;    }    .tg-df-grid.layout-row .tg-df-card-image-box {      width: 140px;      min-width: 140px;      aspect-ratio: 3/4;      border-right: none;      padding: 16px 16px 16px 32px;    }    .tg-df-grid.layout-row .tg-df-card-body {      padding: 16px;      justify-content: space-between;    }    .tg-df-grid.layout-row .tg-df-card-title {      font-size: 15px;      margin-bottom: 16px;    }    .tg-df-grid.layout-row .tg-df-card-stars { margin-bottom: 8px; }    .tg-df-grid.layout-row .tg-df-card-footer {      flex-direction: column;      align-items: flex-start;      gap: 0;    }    .tg-df-grid.layout-row .tg-df-card-merchant-pill {      margin-bottom: 4px;    }    .tg-df-grid.layout-row .tg-df-card-price-group {      margin-bottom: 8px;    }    .tg-df-grid.layout-row .tg-df-price-group {      width: auto;    }    .tg-df-grid.layout-row .tg-df-card-cta {      width: 100%;      max-width: 200px;      padding: 10px 24px;      font-size: 13px;      flex-shrink: 0;      text-align: center;      justify-content: center;    }    /*       4. Deal Card Design    */    .tg-df-card {      position: relative;      display: flex;      flex-direction: column;      background-color: #ffffff;      border-radius: 0;      overflow: hidden;      transition: transform 0.2s ease, box-shadow 0.2s ease;      text-decoration: none;      color: inherit;      height: 100%;      box-shadow: 0 0 16px rgba(0, 0, 0, 0.08);      border: 1px solid var(--tg-df-border);    }    .tg-df-card:hover {      box-shadow: 0 0 24px rgba(0, 0, 0, 0.12);    }    .tg-df-card-image-box {      width: 100%;      aspect-ratio: 3/4;      background-color: #f8f8f8;      display: flex;      align-items: center;      justify-content: center;      position: relative;      overflow: hidden;      padding: 32px;      flex: 0 0 auto;    }    .tg-df-card-image {      max-width: 100%;      max-height: 100%;      width: auto;      height: auto;      object-fit: contain;      mix-blend-mode: multiply; /* Helps white background images blend into secondary bg */      transition: transform 0.3s ease;    }    .tg-df-card:hover .tg-df-card-image {      transform: scale(1.05); /* Zoom in on hover */    }    .tg-df-card-discount-badge {      position: absolute;      top: 12px;      left: 12px;      background: #dc2626; /* Red */      color: #ffffff;      padding: 6px 8px;      font-size: 11px;      font-weight: 500;      text-transform: uppercase;      letter-spacing: 0.5px;      border-radius: 0;      z-index: 10;    }        .tg-df-card-merchant-pill {      display: block;      padding: 0;      font-size: 11px;      font-weight: 600;      text-transform: uppercase;      letter-spacing: 0.5px;      border-radius: 0;      color: var(--tg-df-text-muted);      margin-bottom: 8px;      white-space: nowrap;      overflow: hidden;      text-overflow: ellipsis;    }    .tg-df-card-body {      padding: 16px;      display: flex;      flex-direction: column;      flex-grow: 1;      min-width: 0;    }    .tg-df-card-badges {      display: flex;      flex-wrap: wrap;      gap: 6px;      margin-bottom: 8px;    }    .tg-df-tag {      display: inline-flex;      align-items: center;      padding: 4px 6px;      font-size: 11px;      font-weight: 700;      text-transform: uppercase;      border-radius: 4px;      gap: 4px;    }    .tg-df-tag-prime {      background-color: #00A8E1;      color: #fff;    }    .tg-df-tag-coupons {      background-color: #f1f5f9;      color: #334155;      border: 1px solid #cbd5e1;      cursor: pointer;      transition: background-color 0.2s;    }    .tg-df-tag-coupons:hover {      background-color: #e2e8f0;    }        .tg-df-tag-outline {      background-color: #f1f5f9;      color: #334155;      border: 1px solid #cbd5e1;      cursor: pointer;      transition: background-color 0.2s;    }    .tg-df-tag-outline:hover {      background-color: #e2e8f0;    }        @keyframes tg-df-spin {      0% { transform: rotate(0deg); }      100% { transform: rotate(360deg); }    }    .tg-df-coupon-spinner {      border: 2px solid #e2e8f0;      border-top: 2px solid #3b82f6;      border-radius: 50%;      width: 14px;      height: 14px;      animation: tg-df-spin 1s linear infinite;      margin: 4px 8px;      display: inline-block;    }        /* Vouchers Modal */    .tg-df-modal-backdrop {      position: fixed;      top: 0; left: 0; right: 0; bottom: 0;      background: rgba(0,0,0,0.5);      z-index: 10000;      display: flex;      align-items: center;      justify-content: center;      opacity: 0;      pointer-events: none;      transition: opacity 0.3s;    }    .tg-df-modal-backdrop.active {      opacity: 1;      pointer-events: auto;    }    .tg-df-modal {      background: #fff;      border-radius: 12px;      width: 90%;      max-width: 400px;      max-height: 80vh;      display: flex;      flex-direction: column;      box-shadow: 0 10px 40px rgba(0,0,0,0.2);      transform: translateY(20px);      transition: transform 0.3s;    }    .tg-df-modal-backdrop.active .tg-df-modal {      transform: translateY(0);    }    .tg-df-modal-header {      padding: 16px;      border-bottom: 1px solid #e2e8f0;      display: flex;      align-items: center;      justify-content: space-between;    }    .tg-df-modal-title {      font-size: 16px;      font-weight: 600;      margin: 0;    }    .tg-df-modal-close {      background: none;      border: none;      cursor: pointer;      padding: 4px;      color: #64748b;    }    .tg-df-modal-body {      padding: 16px;      overflow-y: auto;    }    .tg-df-voucher-item {      padding: 12px;      border: 1px dashed #cbd5e1;      border-radius: 8px;      margin-bottom: 10px;      background: #f8fafc;      display: flex;      align-items: center;      gap: 12px;      text-decoration: none;      color: inherit;      transition: background-color 0.2s, border-color 0.2s;    }    .tg-df-voucher-item:hover {      background: #f1f5f9;      border-color: #94a3b8;    }    .tg-df-voucher-item:last-child {      margin-bottom: 0;    }    .tg-df-voucher-logo {      width: 48px;      height: 48px;      object-fit: contain;      border-radius: 4px;      background: #fff;      border: 1px solid #e2e8f0;      flex-shrink: 0;    }    .tg-df-voucher-content {      flex: 1;      min-width: 0;    }    .tg-df-voucher-title {      font-size: 14px;      font-weight: 600;      margin: 0 0 4px 0;      line-height: 1.3;      color: #0f172a;    }    .tg-df-voucher-expiry {      font-size: 12px;      color: #64748b;      display: flex;      align-items: center;      gap: 4px;      margin-top: 6px;    }    .tg-df-voucher-code {      display: inline-flex;      align-items: center;      background: #f1f5f9;      border: 1px dashed #cbd5e1;      padding: 6px 10px;      font-family: monospace;      font-weight: 700;      font-size: 14px;      color: #0f172a;      border-radius: 4px;      margin-top: 8px;      cursor: pointer;      transition: all 0.2s ease;    }    .tg-df-voucher-code:hover {      background: #e2e8f0;      border-color: #94a3b8;    }    .tg-df-voucher-code.copied {      background: #ecfdf5;      border-color: #10b981;      color: #10b981;    }    .tg-df-voucher-cta {      display: inline-block;      margin-top: 8px;      font-size: 13px;      font-weight: 600;      color: #2563eb;      text-decoration: none;    }    .tg-df-card-title {      font-size: 15px;      font-weight: 400;      line-height: 1.4;      margin: 0 0 12px 0;      color: var(--tg-df-text);    }    .tg-df-card-footer {      margin-top: auto;      display: flex;      flex-direction: column;      width: 100%;    }    .tg-df-card-price-group {      display: flex;      flex-direction: row;      align-items: center;      gap: 8px;      margin-bottom: 12px;    }    .tg-df-card-price {      font-size: 16px;      font-weight: 700;      color: #dc2626; /* Red price */      line-height: 1;    }        .tg-df-card-msrp {      font-size: 13px;      color: var(--tg-df-text-muted);      text-decoration: line-through;    }    .tg-df-container .tg-df-card-cta {      display: flex;      align-items: center;      justify-content: center;      width: 100%;      box-sizing: border-box;      background-color: #1f69ff;      color: #ffffff;      font-size: 12px;      font-weight: 700;      text-transform: uppercase;      letter-spacing: 0.5px;      padding: 12px 16px;      border-radius: 0;      border: none;      cursor: pointer;      transition: background-color 0.2s ease;    }    .tg-df-card:hover .tg-df-card-cta,    .tg-df-card-cta:hover {      background-color: #1555cc;    }    /*       5. State & Skeleton Styles    */    .tg-df-message {      grid-column: 1 / -1;      text-align: center;      padding: 48px 24px;      color: var(--tg-df-text-muted);      font-size: 16px;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 8px;    }    @keyframes tg-df-shimmer {      0% { background-position: -200% 0; }      100% { background-position: 200% 0; }    }    .tg-df-skeleton {      background: linear-gradient(90deg, var(--tg-df-bg-secondary) 25%, #e2e8f0 50%, var(--tg-df-bg-secondary) 75%);      background-size: 200% 100%;      animation: tg-df-shimmer 1.5s infinite;      border-radius: 4px;    }    .tg-df-skeleton-img {      width: 100%;      height: 100%;      position: absolute;      top: 0; left: 0;    }        .tg-df-skeleton-text {      height: 16px;      margin-bottom: 8px;      width: 100%;    }    .tg-df-skeleton-text.short { width: 40%; }    .tg-df-skeleton-text.title { height: 20px; margin-bottom: 16px; }    /* Editor Floating Bar & Elements */    .tg-df-editor-bar {      position: sticky;      top: 120px;      z-index: 1000;      background: #111827;      color: #fff;      padding: 12px 16px;      border-radius: 8px;      margin-bottom: 16px;      display: flex;      align-items: center;      justify-content: space-between;      box-shadow: 0 4px 12px rgba(0,0,0,0.15);    }    .tg-df-editor-bar-text {      font-weight: 600;      font-size: 14px;    }    .tg-df-editor-copy-btn {      background: #10b981;      color: #fff;      padding: 6px 16px;      border: none;      border-radius: 4px;      font-weight: 600;      cursor: pointer;      display: flex;      align-items: center;      font-size: 13px;    }    .tg-df-editor-copy-btn:hover { background: #059669; }        .tg-df-deal-checkbox {      position: absolute;      top: 12px;      right: 12px;      z-index: 10;      width: 20px;      height: 20px;      cursor: pointer;      pointer-events: auto;    }    /*       6. Mobile List View (Stacks into a cleaner horizontal row/list)    */    @container tg-df (max-width: 599px) {      .tg-df-controls {        padding: 16px 16px 8px;      }            .tg-df-top-bar {        width: 100%;      }            .tg-df-settings-dropdown {        position: fixed;        top: auto;        bottom: 0;        left: 0;        right: 0;        width: 100%;        border-radius: 20px 20px 0 0;        padding: 24px;        box-shadow: 0 -8px 32px rgba(0,0,0,0.15);        z-index: 1000;        border: none;        border-top: 1px solid var(--tg-df-border);      }            .tg-df-settings-dropdown-backdrop.active {        background: rgba(0,0,0,0.4);      }            .tg-df-search-wrapper {        box-shadow: 0 0 16px rgba(0,0,0,0.08);      }                  .tg-df-sort-wrapper.tg-df-price-range-wrapper {        flex: 0 0 auto;        min-width: max-content;        width: auto;      }            .tg-df-sort-select, .tg-df-filter-select {        width: 100%;        text-align: left;        padding: 10px 24px 10px 32px;        background-position: right 8px center;        text-overflow: ellipsis;        white-space: nowrap;        overflow: hidden;      }      .tg-df-sort-icon {        left: 10px;      }      .tg-df-grid:not(.layout-grid):not(.layout-row),      .tg-df-grid.layout-row {        grid-template-columns: 1fr;        gap: 16px;      }            .tg-df-grid.tg-df-grid-auto {        padding-top: 24px;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card,      .tg-df-grid.layout-row .tg-df-card {        flex-direction: row;        align-items: stretch;        height: auto;        box-shadow: none; /* simple line on mobile if preferred, or keep */        border-bottom: 1px solid var(--tg-df-border);      }      .tg-df-grid.tg-df-grid-auto .tg-df-card:hover,      .tg-df-grid.layout-row .tg-df-card:hover {        box-shadow: none;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-image-box,      .tg-df-grid.layout-row .tg-df-card-image-box {        width: 120px;        min-width: 120px;        aspect-ratio: 3/4;        border-right: none;        padding: 12px;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-body,      .tg-df-grid.layout-row .tg-df-card-body {        padding: 12px;        justify-content: space-between;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-title,      .tg-df-grid.layout-row .tg-df-card-title {        font-size: 14px;        margin-bottom: 12px;      }      /* Single column mobile grid override */      .tg-df-grid.layout-grid {        grid-template-columns: 1fr;        gap: 16px;      }      .tg-df-grid.layout-grid .tg-df-card-image-box {        padding: 12px;      }      .tg-df-grid.layout-grid .tg-df-card-body {        padding: 10px;      }      .tg-df-grid.layout-grid .tg-df-card-title {        font-size: 13px;        margin-bottom: 8px;      }      .tg-df-grid.layout-grid .tg-df-card-price {        font-size: 14px;      }            .tg-df-card-footer {        flex-direction: column;        align-items: stretch;        gap: 0;        width: 100%;        min-width: 0;      }      .tg-df-card-merchant-pill {        margin-bottom: 4px;      }      .tg-df-card-price-group {        flex: 1 1 auto;        margin-bottom: 8px;      }      .tg-df-card-price {        font-size: 16px;      }      .tg-df-card-msrp {        display: block;       }      .tg-df-grid.layout-row .tg-df-card-cta,      .tg-df-container .tg-df-card-cta {        width: 100%;        max-width: none;        min-width: 0;        box-sizing: border-box;        padding: 8px 16px;        font-size: 12px;        flex: 0 0 auto;        text-align: center;        white-space: normal;        line-height: 1.2;      }    }    .tg-df-container.is-carousel {      min-height: 760px;      background-color: #E7F0FF;      padding: 0 0 24px 0;      border-radius: 24px;      width: 100vw;      max-width: 1200px;      position: relative;      left: 50%;      transform: translateX(-50%);    }    .tg-df-container.is-carousel.hide-header-details {      min-height: 480px;    }    /*       7. Carousel View Mode    */    .tg-df-container .tg-df-carousel-host {      /* Layout is now handled by container wrapper */    }    .tg-df-container .tg-df-carousel-eyebrow {      color: #1F69FF;      font-weight: 700;      font-size: 14px;      text-transform: uppercase;      letter-spacing: 1px;      padding: 24px 16px 0 16px;      display: none;    }    .tg-df-container .tg-df-carousel-query-title {      color: #011535;      font-size: 28px;      font-weight: 600;      padding: 0 16px 24px 16px;      line-height: 1.2;      display: none;    }    .tg-df-container .tg-df-carousel-blue-box {      background-color: transparent;      border-radius: 0;      padding: 24px 24px 0 24px;      margin: 0;      color: #1F69FF;          position: relative;      overflow: hidden;    }    .tg-df-container .tg-df-carousel-bg-circle-1 {      display: none;    }    .tg-df-container .tg-df-carousel-bg-circle-2 {      display: none;    }    .tg-df-container .tg-df-carousel-bg-circle-3 {      display: none;    }    .tg-df-container .tg-df-carousel-box-content {      position: relative;      z-index: 10;    }    .tg-df-container .tg-df-carousel-box-eyebrow {      background-color: transparent;      color: #1F69FF;      font-weight: 700;      font-size: 14px;      text-transform: uppercase;      letter-spacing: 1px;      display: inline-block;      padding: 0;      border-radius: 0;    }    .tg-df-container .tg-df-carousel-box-title {      font-size: 28px;      font-weight: 600;      line-height: 1.2;      margin-top: 8px;      color: #1e293b;    }    .tg-df-container .tg-df-countdown-wrapper {      position: absolute;      top: 0;      right: 0;      display: flex;      flex-direction: column;      align-items: flex-end;      gap: 12px;      transform: scale(0.67);      transform-origin: top right;    }    .tg-df-container .tg-df-countdown-title {      font-size: 14px;      font-weight: 600;      color: #011535;      margin: 0;    }    .tg-df-container .tg-df-countdown-blocks {      display: flex;      gap: 16px;    }    .tg-df-container .tg-df-countdown-item {      display: flex;      flex-direction: column;      align-items: center;      gap: 4px;    }    .tg-df-container .tg-df-countdown-box {      width: 59px;      height: 59px;      background: #03FE9E;      border-radius: 15px;      display: flex;      align-items: center;      justify-content: center;    }    .tg-df-container .tg-df-countdown-num {      font-family: 'Inter', sans-serif;      font-weight: 700;      font-size: 20px;      line-height: normal;      color: #011535;    }    .tg-df-container .tg-df-countdown-label {      font-family: 'Inter', sans-serif;      font-weight: 500;      font-size: 16px;      line-height: normal;      color: #1e293b;      text-transform: uppercase;    }    .tg-df-container .tg-df-carousel-box-subtitle {      font-size: 16px;      margin-top: 8px;      font-weight: 300;      color: #1e293b;      line-height: 24px;    }    .tg-df-container .tg-df-carousel-roundels-wrapper {      position: relative;      margin-top: 24px;      margin-left: -24px;      margin-right: -24px;    }    .tg-df-container .tg-df-carousel-roundels {      display: flex;      gap: 16px;      overflow-x: auto;            scrollbar-width: none;      padding-top: 12px;      padding-bottom: 24px;      padding-left: 24px;      padding-right: 24px;      margin-left: 0;      margin-right: 0;    }        .tg-df-container .tg-df-carousel-scroll-left,    .tg-df-container .tg-df-carousel-scroll-right {      position: absolute;      top: 50%;      transform: translateY(-50%);      height: 36px;      width: 36px;      display: flex;      align-items: center;      justify-content: center;      border-radius: 50%;      background-color: #ffffff;      border: 1px solid #e2e8f0;      box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);      color: #1F69FF;      cursor: pointer;      transition: all 0.2s;      margin-top: -4px;      z-index: 20;    }    .tg-df-container .tg-df-carousel-scroll-left { left: 8px; }    .tg-df-container .tg-df-carousel-scroll-right { right: 8px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-left { left: 0px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-right { right: 0px; }    .tg-df-carousel-filters-outer { margin-left: -24px; margin-right: -24px; padding-left: 24px; padding-right: 24px; }    .tg-df-grid-wrapper { position: relative; }    @container tg-df (max-width: 599px) { .tg-df-carousel-filters-outer { margin-left: -16px; margin-right: -16px; padding-left: 16px; padding-right: 16px; } }        .tg-df-container .tg-df-carousel-scroll-left:hover,    .tg-df-container .tg-df-carousel-scroll-right:hover {      background-color: rgba(255, 255, 255, 0.6);    }    .tg-df-container .tg-df-carousel-roundels::-webkit-scrollbar {      display: none;    }    .tg-df-container .tg-df-roundel {      display: flex;      flex-direction: column;      align-items: center;      gap: 8px;      cursor: pointer;      min-width: 120px;      flex-shrink: 0;    }    .tg-df-container .tg-df-roundel-img-box {      width: 120px;      height: 120px;      border-radius: 50%;      background: white;      display: flex;      align-items: center;      justify-content: center;      overflow: hidden;      box-shadow: 0px 3px 14px 0px rgba(30, 41, 59, 0.08);      transition: box-shadow 0.2s;    }    .tg-df-container .tg-df-roundel:hover .tg-df-roundel-img-box {      box-shadow: 0 0 0 2px #E7F0FF, 0 0 0 4px #1F69FF;    }    .tg-df-container .tg-df-roundel.active .tg-df-roundel-img-box {      box-shadow: 0 0 0 2px #E7F0FF, 0 0 0 4px #1F69FF;    }    .tg-df-container .tg-df-roundel:hover .tg-df-roundel-img-box img {      transform: scale(1.08);    }    .tg-df-container .tg-df-roundel-img-box img {      width: 100%;      height: 100%;      object-fit: contain;      padding: 10px;      box-sizing: border-box;      transition: transform 0.3s ease;    }    .tg-df-container .tg-df-roundel-label {      font-size: 13px;      font-weight: 400;      color: #1e293b;      text-align: center;    }    .tg-df-container .tg-df-carousel-filters-label {      font-size: 16px;      font-weight: 400;      color: #1e293b;      white-space: nowrap;      margin-right: 4px;    }    .tg-df-container .tg-df-carousel-filters-wrap {      display: flex;      align-items: center;      flex-wrap: nowrap;      gap: 8px;      margin-top: 8px;      overflow-x: auto;      scrollbar-width: none;      -webkit-overflow-scrolling: touch;      padding-bottom: 8px;      margin-left: -24px;      margin-right: -24px;      padding-left: 24px;      padding-right: 24px;    }    .tg-df-container .tg-df-carousel-filters-wrap::-webkit-scrollbar {      display: none;    }        .tg-df-container .tg-df-carousel-filter-btn img,    .tg-df-container .tg-df-carousel-filter-btn picture {      height: 20px;      width: 20px;      object-fit: contain;      object-position: center;      display: inline-flex;      align-items: center;      justify-content: center;      margin-right: 6px;    }    .tg-df-container .tg-df-carousel-filter-btn picture img {      margin-right: 0;      height: 100%;      width: 100%;    }    .tg-df-container .tg-df-carousel-filter-btn img.active-img,    .tg-df-container .tg-df-carousel-filter-btn picture:has(.active-img) {      display: none;    }    .tg-df-container .tg-df-carousel-filter-btn:hover img.inactive-img,    .tg-df-container .tg-df-carousel-filter-btn.active img.inactive-img,    .tg-df-container .tg-df-carousel-filter-btn:hover picture:has(.inactive-img),    .tg-df-container .tg-df-carousel-filter-btn.active picture:has(.inactive-img) {      display: none;    }    .tg-df-container .tg-df-carousel-filter-btn:hover img.active-img,    .tg-df-container .tg-df-carousel-filter-btn.active img.active-img,    .tg-df-container .tg-df-carousel-filter-btn:hover picture:has(.active-img),    .tg-df-container .tg-df-carousel-filter-btn.active picture:has(.active-img) {      display: inline-flex;    }    .tg-df-container .tg-df-carousel-filter-btn {      background: #ffffff;      border: 2px solid #1e293b;      color: #1e293b;      border-radius: 24px;      padding: 6px 16px;      font-size: 14px;      font-weight: 600;      cursor: pointer;      transition: all 0.2s;      flex-shrink: 0;      white-space: nowrap;    }    .tg-df-container .tg-df-carousel-filter-btn svg {      margin-right: 6px;    }    .tg-df-container .tg-df-carousel-filter-btn {      display: inline-flex;      align-items: center;    }    .tg-df-container .tg-df-carousel-filter-btn:hover {      background: #1e293b;      color: white;      border-color: #1e293b;    }    .tg-df-container .tg-df-carousel-filter-btn.active {      background: #1e293b;      color: white;      border-color: #1e293b;    }        .tg-df-grid.carousel-compact {      display: flex;      flex-wrap: nowrap;      overflow-x: auto;      gap: 16px;      padding: 16px 24px;      align-items: stretch;      scrollbar-width: none;    }    .tg-df-grid.carousel-compact::-webkit-scrollbar {      display: none;    }    .tg-df-grid.carousel-compact .tg-df-card {      flex: 0 0 auto;      width: 200px;      min-height: auto;      height: auto;      display: flex;      flex-direction: column;      border-radius: 15px;      border: none;      box-shadow: 0 0 16px rgba(0,0,0,0.08);      overflow: visible;    }    .tg-df-grid.carousel-compact .tg-df-card-image-box {      padding: 12px;      background-color: transparent;      border-radius: 15px 15px 0 0;      height: 130px;    }    .tg-df-grid.carousel-compact .tg-df-card-image {      mix-blend-mode: normal;    }    .tg-df-grid.carousel-compact .tg-df-card-discount-badge {      border-radius: 0;      top: 0px;      left: 0px;      padding: 4px 8px;      font-size: 11px;    }    .tg-df-grid.carousel-compact .tg-df-card-body {      padding: 8px 12px 12px 12px;    }    .tg-df-grid.carousel-compact .tg-df-card-title {      font-size: 14px;      font-weight: 400;      margin-bottom: 8px;      color: #011535;    }    .tg-df-grid.carousel-compact .tg-df-card-body:not(:has(.tg-df-card-stars)):not(:has(.tg-df-tag-prime)):not(:has(.tg-df-coupon-wrapper:not([style*="none"]))) > .tg-df-card-title,    .tg-df-grid.carousel-compact .tg-df-card-body:not(:has(.tg-df-card-stars)):has(> .tg-df-card-title:first-child) > .tg-df-card-title {    }    .tg-df-grid.carousel-compact .tg-df-card-cta {      border-radius: 5px;      padding: 8px 10px;      margin-top: 4px;      background-color: #1F69FF;    }    .tg-df-grid.carousel-compact .tg-df-card-price-group {      margin-bottom: 2px;    }    .tg-df-grid.carousel-compact .tg-df-card-merchant-pill {      margin-bottom: 2px;    }    @container tg-df (max-width: 599px) {      .tg-df-container .tg-df-carousel-blue-box-title {        font-size: 24px;      }      .tg-df-container .tg-df-countdown-title {        display: none;      }      .tg-df-container .tg-df-countdown-wrapper {        position: absolute;        top: 0;        right: 0;        align-items: flex-end;        transform: scale(0.40);        transform-origin: top right;      }      .tg-df-container .tg-df-roundel {        min-width: 88px;      }      .tg-df-container .tg-df-roundel-img-box {        width: 88px;        height: 88px;      }    }    /* REPLICA BLOCK STYLES */    .tg-df-grid.layout-replica-2 { grid-template-columns: repeat(2, 1fr) !important; gap: 20px; }    .tg-df-grid.layout-replica-1 { grid-template-columns: 1fr !important; gap: 20px; }        .tg-df-container .hawk-deal-widget-container { border-bottom: 1px solid #e5e7eb; display: flex; flex-direction: column; margin: 0; padding: 20px 0; box-sizing: border-box; font-family: inherit; }    .tg-df-container .hawk-deal-widget-wrap { display: flex; flex-direction: row; align-items: flex-start; width: 100%; gap: 24px; }    .tg-df-container .hawk-deal-widget-image-container { display: flex; flex-shrink: 0; justify-content: center; width: 160px; height: 160px; align-items: center; background: white; margin-bottom: 0px; }    .tg-df-container .hawk-deal-widget-title-product-title { color: #111827; font-size: 18px; font-weight: 700; line-height: 1.4; display: inline; }    .tg-df-container .hawk-deal-widget-title-price { font-size: 18px; font-weight: 700; line-height: 1.4; white-space: nowrap; color: #2563eb; }    .tg-df-container .hawk-deal-widget-title-price-now { font-weight: 700; }    .tg-df-container .hawk-deal-widget-title-retailer-price:hover { text-decoration: underline; }    .tg-df-container .hawk-deal-widget-title-retailer { font-size: 18px; font-weight: 700; line-height: 1.4; color: #2563eb; }    .tg-df-container .hawk-deal-widget-title-was-price { color: #dc2626; font-size: 16px; font-weight: 500; line-height: 1.4; text-decoration: line-through; white-space: nowrap; margin-left: 8px; margin-right: 8px; }    .tg-df-container .hawk-deal-widget-text-body-container { position: relative; width: 100%; box-sizing: border-box; }    .tg-df-container .hawk-deal-widget-text-body-main { font-size: 16px; width: 100%; margin-bottom: 12px; }    .tg-df-container .hawk-deal-widget-text-body-description { display: block; font-size: 15px; margin-top: 12px; color: #4b5563; line-height: 1.6; }    .tg-df-container .hawk-deal-widget-text-body-description p { margin: 0; line-height: 1.6; }    .tg-df-container .hawk-deal-widget-text-cta-container { display: flex; flex-direction: column; gap: 12px; width: 100%; flex: 1; min-width: 0; box-sizing: border-box; }    .tg-df-container .hawk-deal-widget-footer { display: flex; justify-content: flex-end; width: 100%; margin-top: auto; }    .tg-df-container .hawk-deal-widget-button-wrapper { display: flex; flex-direction: column; align-items: flex-end; justify-content: flex-end; width: 100%; }    .tg-df-container .hawk-deal-widget-preferred-partner-wrapper { display: flex; flex-direction: row; }        @container tg-df (min-width: 600px) {      .tg-df-mobile-only { display: none !important; }    }    @container tg-df (max-width: 599px) {      .tg-df-desktop-only { display: none !important; }      .tg-df-grid.layout-replica-2 { grid-template-columns: 1fr !important; }      .tg-df-grid.savings-squad-cards { grid-template-columns: 1fr !important; display: flex; flex-direction: column; }    }    .tg-df-grid.savings-squad-cards .tg-df-card-title {      -webkit-line-clamp: unset !important;      display: block !important;      overflow: visible !important;    }    @container tg-df (max-width: 500px) {      .tg-df-container .hawk-deal-widget-wrap { display: block; }      .tg-df-container .hawk-deal-widget-image-container { display: block; float: left; margin: 0 16px 8px 0; width: 120px; max-width: 120px; height: auto; align-items: normal; justify-content: normal; }      .tg-df-container .hawk-deal-widget-text-cta-container { display: block; text-align: left; }      .tg-df-container .hawk-deal-widget-footer { display: block; margin-top: 16px; clear: both; width: 100%; }      .tg-df-container .hawk-deal-widget-button-wrapper { display: block; width: 100%; }      .tg-df-container .hawk-deal-widget-button-wrapper .hawk-deal-widget-preferred-partner-wrapper { display: block; width: 100%; }      .tg-df-container .hawk-affiliate-link-deal-button { box-sizing: border-box !important; display: flex !important; max-width: none !important; width: 100% !important; margin: 0 !important; }    }        .tg-df-container .hawk-affiliate-link-deal-button {       align-items: center; background-color: #1f69ff; box-sizing: border-box; color: #ffffff !important; display: flex; font-size: 14px; font-weight: 700; justify-content: center; letter-spacing: 0.5px; line-height: 1; min-width: 160px; padding: 14px 24px; text-align: center; text-decoration: none; text-transform: uppercase; width: 100%; word-break: normal; border-radius: 4px; border: 0; transition: background-color 0.2s;     }    .tg-df-container .hawk-affiliate-link-deal-button:hover { background-color: #0056e0; text-decoration: none; }    .tg-df-container .hawk-lazy-image-deal-widget { display: block; height: auto; margin: auto; max-height: 160px; max-width: 100%; mix-blend-mode: multiply; object-fit: contain; }    .tg-df-container .hawk-deal-widget-text-cta-container a { color: #2563eb; text-decoration: none; display: inline; }    .tg-df-container .hawk-deal-widget-text-cta-container a:hover { text-decoration: underline; }    .tg-df-container .hawk-deal-widget-text-cta-container a:has(.hawk-deal-widget-title-product-title) { color: #111827; }    .tg-df-container .hawk-deal-widget-text-cta-container a:hover .hawk-deal-widget-title-product-title,    .tg-df-container .hawk-deal-widget-text-cta-container a:hover .hawk-deal-widget-title-retailer-price { text-decoration: underline; }    .tg-df-savings-squad-header { margin-bottom: 24px; text-align: center; display: none; }    .tg-df-banner-img-desktop { display: block; width: 100%; height: auto; margin-bottom: 32px; }    .tg-df-banner-img-mobile { display: none; width: 100%; height: auto; margin-bottom: 32px; }    @container tg-df (max-width: 600px) {      .tg-df-banner-img-desktop { display: none; }      .tg-df-banner-img-mobile { display: block; }    }    .tg-df-header-title { font-size: 28px; font-weight: 700; color: var(--tg-df-text); margin: 32px 0 12px 0; line-height: 1.3; }    .tg-df-header-subtitle { font-size: 16px; color: var(--tg-df-text-muted); margin: 0 0 32px 0; line-height: 1.5; }  \x3C/style>  \x3C!-- Widget Container --\x3E  \x3Cdiv class="tg-df-container" id="signal-deals-finder-root">    \x3Cdiv class="tg-df-savings-squad-header" id="tg-df-savings-squad-header">      \x3Cpicture>        \x3Cimg src="https://cdn.mos.cms.futurecdn.net/flexiimages/xkh2og7m3d1778189998.png" alt="Deals Banner" class="tg-df-banner-img-desktop" />        \x3Cimg src="https://cdn.mos.cms.futurecdn.net/flexiimages/gmak6rtdf41778245089.png" alt="Deals Banner Mobile" class="tg-df-banner-img-mobile" />      \x3C/picture>      \x3Cdiv class="tg-df-header-text">        \x3Ch2 class="tg-df-header-title" id="tg-df-header-title">Editor's Choice Deals\x3C/h2>        \x3Cp class="tg-df-header-subtitle" id="tg-df-header-subtitle">Discover the best discounts currently available, curated daily by the Tom's Guide Savings Squad.\x3C/p>      \x3C/div>    \x3C/div>    \x3C!-- Editor Floating Bar --\x3E    \x3Cdiv class="tg-df-editor-bar" id="tg-df-editor-bar" style="display:none;">      \x3Cdiv class="tg-df-editor-bar-text" style="display: flex; align-items: center;">        \x3Cspan id="tg-df-selected-count">0\x3C/span>\x26nbsp;Deals Selected        \x3Cbutton class="tg-df-editor-clear-btn" id="tg-df-editor-clear" type="button" style="margin-left: 12px; font-size: 13px; color: #9ca3af; background: none; border: none; cursor: pointer; text-decoration: underline;">Clear All\x3C/button>      \x3C/div>      \x3Cbutton class="tg-df-editor-copy-btn" id="tg-df-editor-copy" type="button">        \x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2">\x3C/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">\x3C/path>\x3C/svg>        Copy to CMS      \x3C/button>    \x3C/div>    \x3Cdiv class="tg-df-carousel-host" id="tg-df-carousel-host" style="display: none;">      \x3Cdiv class="tg-df-carousel-eyebrow">DEAL FINDER\x3C/div>      \x3Cdiv class="tg-df-carousel-query-title" id="tg-df-carousel-title-label">Best Deals\x3C/div>            \x3Cdiv class="tg-df-carousel-blue-box">        \x3Cdiv class="tg-df-carousel-bg-circle-1" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-bg-circle-2" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-bg-circle-3" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-box-content">          \x3Cdiv class="tg-df-countdown-wrapper" id="tg-df-countdown-wrapper" style="display:none;">            \x3Cdiv class="tg-df-countdown-title" id="tg-df-countdown-title">Prime Day starts in\x3C/div>            \x3Cdiv class="tg-df-countdown-blocks">              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-days">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">DAYS\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-hrs">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">HRS\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-min">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">MIN\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-sec">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">SEC\x3C/div>\x3C/div>            \x3C/div>          \x3C/div>          \x3Cdiv class="tg-df-carousel-box-eyebrow">DEAL FINDER\x3C/div>          \x3Cdiv class="tg-df-carousel-box-title">Find Deals Fast\x3C/div>          \x3Cdiv class="tg-df-carousel-box-subtitle">The latest deals from the biggest retailers, all in one place\x3C/div>                    \x3Cdiv class="tg-df-carousel-roundels-wrapper">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-roundels').scrollBy({left: -200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \x3Cdiv class="tg-df-carousel-roundels">                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Televisions" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/wcMxTsHgqu3roMbAx7RLnT-132-100.png" alt="TVs" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">TVs\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Phones" data-pr="over50">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/G3KGaRGzj24F6PUsw4bWpT-132-100.png" alt="Phones" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Phones\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Computing" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/znNvsLzx8NEgNkD9HSFSnT-132-100.png" alt="Computing" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Computing\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Gaming" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/Pgew8yaRQeZFHqHjTzvBnT-132-100.png" alt="Gaming" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Gaming\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Mattresses" data-pr="over500">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/cW7xsaLyesxkHFVSiC4kmT-132-100.png" alt="Mattresses" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Mattresses\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Audio" data-pr="over30">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/pCvBVHuhaQVjKt3VgCjbqT-132-100.png" alt="Audio" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Audio\x3C/span>            \x3C/div>                  \x3C/div>        \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" onclick="this.parentElement.querySelector('.tg-df-carousel-roundels').scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>        \x3C/div>        \x3C/div>        \x3Cdiv class="tg-df-carousel-filters-outer" style="position: relative;">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').scrollBy({left: -200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \x3Cdiv class="tg-df-carousel-filters-wrap">                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="0">All\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-ot="amazon_lightning">              \x3Cimg src="https://cdn.mos.cms.futurecdn.net/HqAui7w97ft2NPqBtQ5r38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/yWPQ5yyQRhUwVKzGwYbh38-600-100.png" class="active-img" alt="" /> Lightning deals\x3C/button>            \x3Cbutton class="tg-df-carousel-filter-btn" data-ot="amazon_prime">              \x3Cimg src="https://cdn.mos.cms.futurecdn.net/fwoVXvL79turN3Ph535m38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/u75QjVpt3w2EsMimJiRo38-600-100.png" class="active-img" alt="" /> Prime deals\x3C/button>            \x3Cbutton class="tg-df-carousel-filter-btn" data-d="10">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 10% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="15">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 15% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="25">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 25% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-pr="under50">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-badge-dollar-sign">\x3Cpath d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z">\x3C/path>\x3Cpath d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8">\x3C/path>\x3Cpath d="M12 18V6">\x3C/path>\x3C/svg>            Under $50\x3C/button>        \x3C/div>        \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>      \x3C/div>    \x3C/div>    \x3C/div>      \x3C!-- Search & Filter Controls --\x3E      \x3Cdiv class="tg-df-top-bar" id="tg-df-top-bar" style="position: relative; z-index: 100; margin: 0 auto 20px;">        \x3Cdiv class="tg-df-search-wrapper">          \x3Cinput type="text" class="tg-df-search-input" placeholder="Search for deals, products, or brands...">          \x3Cbutton type="button" class="tg-df-search-btn" aria-label="Search">              \x3Csvg class="tg-df-search-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">                \x3Cpath d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>              \x3C/svg>          \x3C/button>          \x3Cdiv class="tg-df-autocomplete-dropdown" id="tg-df-autocomplete">\x3C/div>        \x3C/div>      \x3C/div>    \x3Cdiv class="tg-df-controls" id="tg-df-controls" style="display:flex;">              \x3Cdiv class="tg-df-filters-container" style="position: relative; width: 100%; max-width: 800px; margin: 0 auto;">          \x3Cbutton class="tg-df-scroll-btn left" style="display: none;" onclick="this.parentElement.querySelector('.tg-df-filters').scrollBy({left: -200, behavior: 'smooth'})">            \x3Csvg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\x3Cpath d="M15 18l-6-6 6-6"/>\x3C/svg>          \x3C/button>          \x3Cbutton class="tg-df-scroll-btn right" style="display: none;" onclick="this.parentElement.querySelector('.tg-df-filters').scrollBy({left: 200, behavior: 'smooth'})">            \x3Csvg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\x3Cpath d="M9 18l6-6-6-6"/>\x3C/svg>          \x3C/button>          \x3Cdiv class="tg-df-filters">          \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-category-filter-wrapper" style="display: none;">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-category-filter" aria-label="Category">            \x3Coption value="all">All Categories\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper tg-df-multiselect-container" id="tg-df-brand-filter-wrapper" style="display:none;">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M4.25 5.61C6.27 8.2 10 13 10 13v6c0 .55.45 1 1 1h2c.55 0 1-.45 1-1v-6s3.72-4.8 5.74-7.39A.998.998 0 0 0 18.95 4H5.04c-.83 0-1.3.95-.79 1.61z"/>          \x3C/svg>          \x3Cdiv class="tg-df-filter-select tg-df-multiselect-trigger" id="tg-df-brand-trigger" tabindex="0">            Any Brand          \x3C/div>          \x3Cdiv class="tg-df-multiselect-dropdown" id="tg-df-brand-dropdown">            \x3C!-- Populated via script --\x3E          \x3C/div>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper tg-df-price-range-wrapper" id="tg-df-custom-price-wrapper" style="display: flex; align-items:center; justify-content:center; padding: 10px 20px; gap: 8px; border: 1px solid var(--tg-df-border); border-radius: 100px; background-color: var(--tg-df-bg);">          \x3Cspan style="font-size:14px; font-weight:500; color:var(--tg-df-text-primary);">Price\x3C/span>          \x3Cinput type="number" class="tg-df-price-input" id="tg-df-custom-price-min" placeholder="Min" style="width: 48px; background: transparent; border: none; color: var(--tg-df-text-primary); outline: none; font-size: 14px; text-align: center; padding: 0;">          \x3Cspan style="color:var(--tg-df-text-muted)">-\x3C/span>          \x3Cinput type="number" class="tg-df-price-input" id="tg-df-custom-price-max" placeholder="Max" style="width: 48px; background: transparent; border: none; color: var(--tg-df-text-primary); outline: none; font-size: 14px; text-align: center; padding: 0;">        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-legacy-price-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-price-filter" aria-label="Filter Prices">            \x3Coption value="all">All Prices\x3C/option>            \x3Coption value="under50">Under $50\x3C/option>            \x3Coption value="50_100">$50 - $100\x3C/option>            \x3Coption value="100_200">$100 - $200\x3C/option>            \x3Coption value="200_500">$200 - $500\x3C/option>            \x3Coption value="over500">Over $500\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-discount-filter-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">            \x3Cpath d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-discount-filter" aria-label="Discount Amount">            \x3Coption value="all">Any discount\x3C/option>            \x3Coption value="5">Min 5%\x3C/option>            \x3Coption value="10">Min 10%\x3C/option>            \x3Coption value="15">Min 15%\x3C/option>            \x3Coption value="20">Min 20%\x3C/option>            \x3Coption value="25">Min 25%\x3C/option>            \x3Coption value="30">Min 30%\x3C/option>            \x3Coption value="40">Min 40%\x3C/option>            \x3Coption value="50">Min 50%\x3C/option>            \x3Coption value="60">Min 60%\x3C/option>            \x3Coption value="70">Min 70%\x3C/option>          \x3C/select>          \x3C/div>        \x3C/div>        \x3C/div>      \x3C/div>    \x3C!-- Deals Grid Wrapper --\x3E    \x3Cdiv class="tg-df-grid-wrapper tg-df-carousel-cards-wrapper" id="tg-df-grid-wrapper">      \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').scrollBy({left: -200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>      \x3Cdiv class="tg-df-grid" id="tg-df-grid">        \x3C!-- Content populated by JavaScript --\x3E      \x3C/div>      \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>    \x3C/div>        \x3C!-- Vouchers Modal --\x3E    \x3Cdiv class="tg-df-modal-backdrop" id="tg-df-vouchers-modal">      \x3Cdiv class="tg-df-modal">        \x3Cdiv class="tg-df-modal-header">          \x3Ch3 class="tg-df-modal-title" id="tg-df-vouchers-title">Available Coupons & Deals\x3C/h3>          \x3Cbutton class="tg-df-modal-close" id="tg-df-vouchers-close">            \x3Csvg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">              \x3Cline x1="18" y1="6" x2="6" y2="18">\x3C/line>              \x3Cline x1="6" y1="6" x2="18" y2="18">\x3C/line>            \x3C/svg>          \x3C/button>        \x3C/div>        \x3Cdiv class="tg-df-modal-body" id="tg-df-vouchers-content">          \x3C!-- Vouchers injected here --\x3E        \x3C/div>      \x3C/div>    \x3C/div>  \x3C/div>`;      if (!template) {        template = document.createElement('template');        template.innerHTML = rawTemplate;      }      let shadowRoot = null;      if (hostContainer && template) {        hostContainer.setAttribute('data-initialized', 'true');        shadowRoot = hostContainer.attachShadow({ mode: 'open' });        shadowRoot.appendChild(template.content.cloneNode(true));      }      class DealsFinderWidget {        constructor(config) {          this.rootNode = config.rootNode || document;          this.hostContainer = config.hostContainer || null;          this.rootId = config.rootId || 'signal-deals-finder-root';          this.root = this.rootNode.querySelector('#' + this.rootId);          if (!this.root) return;          this.widgetId = (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : 'widget-' + Date.now() + '-' + Math.random().toString(36).slice(2);          this.grid = this.root.querySelector('#tg-df-grid');          this.tagsContainer = this.root.querySelector('#tg-df-tags-container');          this.categoryFilter = this.root.querySelector('#tg-df-category-filter');          this.categoryFilterWrapper = this.root.querySelector('#tg-df-category-filter-wrapper');          this.searchInput = this.root.querySelector('.tg-df-search-input');          this.autocompleteDropdown = this.root.querySelector('#tg-df-autocomplete');          this.sortSelect = this.root.querySelector('.tg-df-sort-select');          this.searchBtn = this.root.querySelector('.tg-df-search-btn');                    this.settingsToggle = this.root.querySelector('#tg-df-settings-toggle');          this.settingsPanel = this.root.querySelector('#tg-df-settings-panel');          this.settingsBackdrop = this.root.querySelector('#tg-df-settings-backdrop');          this.regionSelect = this.root.querySelector('#tg-df-region-select');          this.retailerSelect = this.root.querySelector('#tg-df-retailer-select');          this.offerTypeSelect = this.root.querySelector('#tg-df-offer-type-select');          this.viewModeSelect = this.root.querySelector('#tg-df-view-mode-select');          this.rowsSelect = this.root.querySelector('#tg-df-rows-select');          this.dealModeToggle = this.root.querySelector('#tg-df-deal-mode');          this.editorModeToggle = this.root.querySelector('#tg-df-editor-mode');          this.priceFilter = this.root.querySelector('#tg-df-price-filter');          this.discountFilter = this.root.querySelector('#tg-df-discount-filter');                    this.editorBar = this.root.querySelector('#tg-df-editor-bar');          this.editorSelectedCount = this.root.querySelector('#tg-df-selected-count');          this.editorCopyBtn = this.root.querySelector('#tg-df-editor-copy');          this.editorClearBtn = this.root.querySelector('#tg-df-editor-clear');                    this.apiUrl = 'https://search-api.fie.future.net.uk/widget.php';          this.deals = [];          this.displayLimit = 12;          this.airedaleArticles = null;          this.airedaleTags = [];          this.airedaleTagCounts = {};          this.activeDealTag = null;          this.selectedBrands = [];          this.currentQuery = '';          this.editorMode = this.hostContainer ? this.hostContainer.hasAttribute('data-editor-mode') : false;          this.viewModeOverride = this.hostContainer ? this.hostContainer.getAttribute('data-view-mode') : null;          this.selectedDeals = new Map();                    this.brandFilterWrapper = this.root.querySelector('#tg-df-brand-filter-wrapper');          this.brandTrigger = this.root.querySelector('#tg-df-brand-trigger');          this.brandDropdown = this.root.querySelector('#tg-df-brand-dropdown');                    this.customPriceWrapper = this.root.querySelector('#tg-df-custom-price-wrapper');          this.customPriceMin = this.root.querySelector('#tg-df-custom-price-min');          this.customPriceMax = this.root.querySelector('#tg-df-custom-price-max');          this.legacyPriceWrapper = this.root.querySelector('#tg-df-legacy-price-wrapper');          this.discountFilterWrapper = this.root.querySelector('#tg-df-discount-filter-wrapper');          this.initResizeObserver();          this.init();        }        getViewMode() {          console.log("DEBUG getViewMode -> override:", this.viewModeOverride, "editorMode:", this.editorMode);          if (this.viewModeOverride && (!this.editorMode || !this.viewModeSelect)) {            return this.viewModeOverride;          }          return (this.viewModeSelect && this.viewModeSelect.value) ? this.viewModeSelect.value : (this.viewModeOverride || 'auto');        }        applyLayoutMode() {          if (!this.grid) return;          const mode = this.getViewMode();          console.log("[DEBUG] applyLayoutMode CALLED! mode=", mode);          this.grid.classList.remove('layout-row', 'layout-grid', 'tg-df-grid-auto', 'carousel-compact', 'layout-replica-1', 'layout-replica-2');                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          const showHeaderDetails = params.get('show_header_details') !== 'false';          const carouselHost = this.root.querySelector('#tg-df-carousel-host');          const controlsDiv = this.root.querySelector('#tg-df-controls');          const topBarDiv = this.root.querySelector('#tg-df-top-bar');          const headerElement = this.root.querySelector('#tg-df-savings-squad-header');          if (headerElement) {             headerElement.style.display = (mode === 'savings_squad' && showHeaderDetails) ? 'block' : 'none';          }          if (mode === 'carousel') {             this.grid.classList.add('carousel-compact');             if (carouselHost) carouselHost.style.display = 'block';             if (controlsDiv) controlsDiv.style.display = 'none';             if (topBarDiv) topBarDiv.style.display = 'none';             if (this.root.classList.contains('tg-df-container')) {               this.root.classList.add('is-carousel');             }          } else {             if (carouselHost) carouselHost.style.display = 'none';             if (controlsDiv) controlsDiv.style.display = 'flex';             if (topBarDiv) topBarDiv.style.display = 'block';             if (this.root.classList.contains('tg-df-container')) {               this.root.classList.remove('is-carousel');             }          }          if (mode === 'grid') {            this.grid.classList.add('layout-grid');          } else if (mode === 'row') {            this.grid.classList.add('layout-row');          } else if (mode === 'savings_squad') {            this.grid.classList.add('tg-df-grid-auto', 'savings-squad-cards');          } else if (mode !== 'carousel') {            this.grid.classList.add('tg-df-grid-auto');          }                    const settingsWrapper = this.root.querySelector('.tg-df-settings-wrapper');          if (settingsWrapper) {            settingsWrapper.style.display = mode === 'auto' ? 'none' : 'block';          }          if (this.customPriceWrapper) {             this.customPriceWrapper.style.display = mode === 'auto' ? 'flex' : 'none';          }          if (this.legacyPriceWrapper) {             this.legacyPriceWrapper.style.display = mode === 'auto' ? 'none' : 'flex';          }          if (this.discountFilterWrapper) {             this.discountFilterWrapper.style.display = mode === 'auto' ? 'none' : 'flex';          }        }        initResizeObserver() {          try {            if (window.parent === window) return;          } catch (e) {            // cross origin frame check threw          }          const emitHeight = () => {            try {              const height = document.documentElement.scrollHeight || document.body.scrollHeight;              const msg = { type: 'embed-size', height: height };              if (window.parent && window.parent !== window) {                window.parent.postMessage(msg, '*');                window.parent.postMessage(JSON.stringify({ ...msg, sentinel: 'amp' }), '*');              }            } catch (e) {}          };                    if (window.ResizeObserver) {            try {              const ro = new ResizeObserver(() => emitHeight());              ro.observe(document.body);              if (this.root) ro.observe(this.root);            } catch(e){ console.warn(e); }          }          window.addEventListener('resize', emitHeight);          setTimeout(emitHeight, 300);        }        initCountdown() {          this.cdWrapper = this.root.querySelector('#tg-df-countdown-wrapper');                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          this.showCountdown = params.get('show_countdown') === 'true';          const showHeaderDetails = params.get('show_header_details') !== 'false';          const eyebrow = this.root.querySelector('.tg-df-carousel-box-eyebrow');          const title = this.root.querySelector('.tg-df-carousel-box-title');          const subtitle = this.root.querySelector('.tg-df-carousel-box-subtitle');          if (!showHeaderDetails) {            let containerElement = this.root.classList.contains('tg-df-container') ? this.root : this.root.querySelector('.tg-df-container');            if (containerElement) containerElement.classList.add('hide-header-details');            if (eyebrow) eyebrow.style.display = 'none';            if (title) title.style.display = 'none';            if (subtitle) subtitle.style.display = 'none';          }          if (!this.cdWrapper) return;          this.cdTitle = this.root.querySelector('#tg-df-countdown-title');          this.cdDays = this.root.querySelector('#tg-df-cd-days');          this.cdHrs = this.root.querySelector('#tg-df-cd-hrs');          this.cdMin = this.root.querySelector('#tg-df-cd-min');          this.cdSec = this.root.querySelector('#tg-df-cd-sec');          this.updateCountdown();          this.cdInterval = setInterval(() => this.updateCountdown(), 1000);        }        updateCountdown() {          if (!this.cdWrapper) return;          if (!this.showCountdown) {            this.cdWrapper.style.display = 'none';            return;          }          const area = this.getAreaCode();          let offset = '-04:00';          if (['DE', 'FR', 'IT', 'ES', 'NL'].includes(area)) {             offset = '+02:00';          } else if (['GB', 'IE', 'UK'].includes(area)) {             offset = '+01:00';          }          const startTime = new Date('2026-06-23T00:00:00' + offset).getTime();          const endTime = new Date('2026-06-26T00:00:00' + offset).getTime();          const now = Date.now();          let targetTime = 0;          if (now < startTime) {             targetTime = startTime;             if (this.cdTitle) this.cdTitle.textContent = 'Prime Day starts in';             this.cdWrapper.style.display = 'flex';          } else if (now < endTime) {             targetTime = endTime;             if (this.cdTitle) this.cdTitle.textContent = 'Prime Day ends in';             this.cdWrapper.style.display = 'flex';          } else {             this.cdWrapper.style.display = 'none';             if (this.cdInterval) clearInterval(this.cdInterval);             return;          }          const diff = Math.max(0, targetTime - now);          const d = Math.floor(diff / (1000 * 60 * 60 * 24));          const h = Math.floor((diff / (1000 * 60 * 60)) % 24);          const m = Math.floor((diff / 1000 / 60) % 60);          const s = Math.floor((diff / 1000) % 60);          if (this.cdDays) this.cdDays.textContent = d;          if (this.cdHrs) this.cdHrs.textContent = h;          if (this.cdMin) this.cdMin.textContent = m;          if (this.cdSec) this.cdSec.textContent = s;        }        init() {          this.initCountdown();          try {            initAnalytics();          } catch (e) {            console.warn('Deals Widget Analytics Error:', e);          }                    this.bindEvents();                    let initialQuery = '';                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          let initialViewMode = params.get('view_mode');          if (!this.viewModeOverride && initialViewMode) {            this.viewModeOverride = initialViewMode;          }          if (!params.has('search') && !params.has('q') && !params.has('query') && initialViewMode !== 'savings_squad') {             initialQuery = 'Gaming laptops';          }          const website = params.get('website') || 'tomsguide';          this.website = website;          if (website === 'techradar') {            const squadHeader = this.root.querySelector('.tg-df-savings-squad-header');            if (squadHeader) {               const pic = squadHeader.querySelector('picture');               if (pic) pic.style.display = 'none';            }            const style = document.createElement('style');            style.innerHTML = `              .tg-df-container .hawk-affiliate-link-deal-button, .tg-df-container .tg-df-card-cta { background-color: #5DAF08 !important; }              .tg-df-container .hawk-affiliate-link-deal-button:hover, .tg-df-container .tg-df-card-cta:hover { background-color: #4a8c06 !important; }            `;            this.root.appendChild(style);          }                    if (this.regionSelect) {            this.regionSelect.value = params.get('region') || 'auto';            this.updatePriceDropdownCurrency();          }                    if (this.retailerSelect && params.has('retailer')) {            this.retailerSelect.value = params.get('retailer');          }                    if (params.has('brands')) {            const b = params.get('brands');            if (b) {              this.selectedBrands = b.split(',');            }          }                    if (this.offerTypeSelect && params.has('offer_type')) {            this.offerTypeSelect.value = params.get('offer_type');          }          if (this.viewModeSelect && params.has('view_mode')) {            this.viewModeSelect.value = params.get('view_mode');          }          if (this.rowsSelect && params.has('rows')) {            this.rowsSelect.value = params.get('rows');          }          if (params.has('price')) {            const priceVal = params.get('price');            if (this.priceFilter) {               // Try assigning it directly to select. If it's not present implicitly ignores               this.priceFilter.value = priceVal;            }            if (priceVal.includes('_')) {               const parts = priceVal.split('_');               if (this.customPriceMin && parts[0]) this.customPriceMin.value = parts[0];               if (this.customPriceMax && parts[1]) this.customPriceMax.value = parts[1];            }          }          if (this.discountFilter && params.has('min_discount_ratio')) {            // Need to convert back from ratio (e.g. 0.8) to select value (e.g. "20")            const ratioStr = params.get('min_discount_ratio');            const ratioFloat = parseFloat(ratioStr);            if (!isNaN(ratioFloat)) {               const percentage = Math.round((1 - ratioFloat) * 100);               this.discountFilter.value = percentage.toString();            }          }          if (this.sortSelect) {            this.sortSelect.value = params.get('sort') || 'date_desc';          }          if (this.dealModeToggle && params.has('deal_mode')) {            this.dealModeToggle.checked = params.get('deal_mode') === 'true' || params.get('deal_mode') === '1';          }          const headerTitleEl = this.root.querySelector('#tg-df-header-title');          const headerSubtitleEl = this.root.querySelector('#tg-df-header-subtitle');          if (params.has('widget_title') && headerTitleEl) {             headerTitleEl.textContent = params.get('widget_title');          }          if (params.has('widget_subtitle') && headerSubtitleEl) {             headerSubtitleEl.textContent = params.get('widget_subtitle');          }                    // Re-apply layout after params have updated control values          this.applyLayoutMode();                    if (params.get('search')) {            initialQuery = params.get('search');          } else if (params.get('q')) {            initialQuery = params.get('q');          } else if (params.get('query')) {            initialQuery = params.get('query');          }                    this.currentQuery = initialQuery;          if (this.searchInput) {            if (this.getViewMode() === 'savings_squad') {              this.searchInput.value = '';            } else {              this.searchInput.value = this.currentQuery;            }          }                    if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {            this.fetchDeals(this.currentQuery);          } else {            this.render();          }        }        updatePriceDropdownCurrency() {          if (!this.priceFilter || !this.regionSelect) return;          const currencySymbols = {            'US': '$',            'GB': '£',            'CA': '$CA',            'AU': '$AU',            'DE': '€',            'FR': '€',            'IT': '€',          };          const area = this.getAreaCode();          const cur = currencySymbols[area || 'US'] || '$';                    const options = this.priceFilter.options;          for (let i = 0; i < options.length; i++) {            const opt = options[i];            if (opt.value === 'all') {              opt.innerText = 'All Prices';            } else if (opt.value === 'under50') {              opt.innerText = `Under ${cur}50`;            } else if (opt.value === '50_100') {              opt.innerText = `${cur}50 - ${cur}100`;            } else if (opt.value === '100_200') {              opt.innerText = `${cur}100 - ${cur}200`;            } else if (opt.value === '200_500') {              opt.innerText = `${cur}200 - ${cur}500`;            } else if (opt.value === 'over500') {              opt.innerText = `Over ${cur}500`;            }          }        }        populateBrandDropdown(values) {          if (!this.brandDropdown || !this.brandFilterWrapper) return;          this.brandFilterWrapper.style.display = 'flex'; // show the wrapper                    let html = '';          const allChecked = this.selectedBrands.length === 0 ? 'checked' : '';          const _div = '<' + '/div>';          const _span = '<' + '/span>';          html += `\x3Cdiv class="tg-df-ms-option">\x3Cinput type="checkbox" value="" ${allChecked} class="tg-df-brand-chk"> Any Brand${_div}`;                    values.forEach(v => {             if (!v.formatted_value || v.formatted_value === 'Any Brand') return;             const isChecked = this.selectedBrands.includes(v.formatted_value) ? 'checked' : '';             html += `\x3Cdiv class="tg-df-ms-option">\x3Cinput type="checkbox" value="${this.escapeHTML(v.formatted_value)}" ${isChecked} class="tg-df-brand-chk"> ${this.escapeHTML(v.formatted_value)} \x3Cspan style="color:var(--tg-df-text-muted);font-size:12px">(${v.count || 0})${_span}${_div}`;          });                    this.brandDropdown.innerHTML = html;                    // Re-bind listeners          const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');          chks.forEach(chk => {            chk.addEventListener('change', (e) => {              const val = e.target.value;              if (val === '') {                this.selectedBrands = [];              } else {                if (e.target.checked) {                   if (!this.selectedBrands.includes(val)) this.selectedBrands.push(val);                } else {                   this.selectedBrands = this.selectedBrands.filter(b => b !== val);                }              }                            if (this.selectedBrands.length === 0) {                 this.brandTrigger.innerText = 'Any Brand';              } else if (this.selectedBrands.length === 1) {                 this.brandTrigger.innerText = this.selectedBrands[0];              } else {                 this.brandTrigger.innerText = `${this.selectedBrands.length} Brands selected`;              }                            // Only call API if changed from UI interactions              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                 this.updateURLParams();                 this.fetchDeals(this.currentQuery);              }            });          });                    // Update button text on load          if (this.selectedBrands.length === 0) {             this.brandTrigger.innerText = 'Any Brand';          } else if (this.selectedBrands.length === 1) {             this.brandTrigger.innerText = this.selectedBrands[0];          } else {             this.brandTrigger.innerText = `${this.selectedBrands.length} Brands selected`;          }        }        updateURLParams() {          const url = new URL(window.location);          if (this.currentQuery && this.currentQuery !== 'Gaming laptops') {            url.searchParams.set('q', this.currentQuery);          } else {            url.searchParams.delete('q');            url.searchParams.delete('search');            url.searchParams.delete('query');          }                    if (this.regionSelect && this.regionSelect.value !== 'auto') {            url.searchParams.set('region', this.regionSelect.value);          } else {            url.searchParams.delete('region');          }                    if (this.retailerSelect && this.retailerSelect.value) {            url.searchParams.set('retailer', this.retailerSelect.value);          } else {            url.searchParams.delete('retailer');          }                    if (this.selectedBrands && this.selectedBrands.length > 0) {            url.searchParams.set('brands', this.selectedBrands.join(','));          } else {            url.searchParams.delete('brands');          }                    if (this.offerTypeSelect && this.offerTypeSelect.value) {            url.searchParams.set('offer_type', this.offerTypeSelect.value);          } else {            url.searchParams.delete('offer_type');          }                    if (this.viewModeSelect && this.viewModeSelect.value !== 'auto') {            url.searchParams.set('view_mode', this.viewModeSelect.value);          } else {            url.searchParams.delete('view_mode');          }                    if (this.rowsSelect && this.rowsSelect.value !== '12') {            url.searchParams.set('rows', this.rowsSelect.value);          } else {            url.searchParams.delete('rows');          }                    const min = this.customPriceMin ? this.customPriceMin.value : '';          const max = this.customPriceMax ? this.customPriceMax.value : '';          if (min || max) {             url.searchParams.set('price', `${min}_${max}`);          } else if (this.priceFilter && this.priceFilter.value !== 'all') {            url.searchParams.set('price', this.priceFilter.value);          } else {            url.searchParams.delete('price');          }                    if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {            const v = parseInt(this.discountFilter.value);            if (!isNaN(v) && v > 0) {               const ratio = (100 - v) / 100;               url.searchParams.set('min_discount_ratio', ratio.toString());            }          } else {            url.searchParams.delete('min_discount_ratio');          }                    if (this.sortSelect && this.sortSelect.value !== 'date_desc') {            url.searchParams.set('sort', this.sortSelect.value);          } else {            url.searchParams.delete('sort');          }                    if (this.dealModeToggle && this.dealModeToggle.checked) {            url.searchParams.set('deal_mode', 'true');          } else {            url.searchParams.delete('deal_mode');          }                    window.history.replaceState({}, '', url);        }        bindEvents() {          const handleFiltersScroll = () => {            const filters = this.root.querySelector('.tg-df-filters');            const leftBtn = this.root.querySelector('.tg-df-scroll-btn.left');            const rightBtn = this.root.querySelector('.tg-df-scroll-btn.right');            if (filters && leftBtn && rightBtn) {              const { scrollLeft, scrollWidth, clientWidth } = filters;              leftBtn.style.display = scrollLeft > 0 ? 'flex' : 'none';              rightBtn.style.display = Math.ceil(scrollLeft + clientWidth) < scrollWidth - 5 ? 'flex' : 'none';            }          };          const filters = this.root.querySelector('.tg-df-filters');          if (filters) {            filters.addEventListener('scroll', handleFiltersScroll);            window.addEventListener('resize', handleFiltersScroll);            setTimeout(handleFiltersScroll, 100);                        // Also call after rendering dropdowns            const origRenderCategories = this.renderCategories;            if (origRenderCategories) {               this.renderCategories = (...args) => {                 origRenderCategories.apply(this, args);                 setTimeout(handleFiltersScroll, 50);               };            }          }                const roundels = this.root.querySelectorAll('.tg-df-carousel-cat');          roundels.forEach(r => {             r.addEventListener('click', () => {                const q = r.getAttribute('data-query');                const pr = r.getAttribute('data-pr');                if (typeof trackHawkEvent !== 'undefined') {                     trackHawkEvent({                         clickType: "CC",                         widgetId: this.widgetId,                         productCategoryName: "deals",                         zeroBasedProductIndexOrNull: null,                         totalDealsOrProducts: null,                         areaClicked: "Category Roundel",                         revenueId: this.revenueId,                         isoCurrencyCode: typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD',                         queryName: q,                         widgetTypeName: this.widgetTypeName                     });                 }                this.currentQuery = q;                const label = this.root.querySelector('#tg-df-carousel-title-label');                if (label) label.textContent = 'Best ' + q;                if (this.priceFilter) this.priceFilter.value = pr || 'all';                if (this.discountFilter) this.discountFilter.value = '5';                if (this.searchInput) this.searchInput.value = q;                                roundels.forEach(ro => ro.classList.remove('active'));                r.classList.add('active');                this.fetchDeals(this.currentQuery);             });          });          const discBtns = this.root.querySelectorAll('.tg-df-carousel-filter-btn');          discBtns.forEach(b => {             b.addEventListener('click', () => {                const d = b.getAttribute('data-d');                const pr = b.getAttribute('data-pr');                const ot = b.getAttribute('data-ot');                let label = b.innerText ? b.innerText.trim() : '';                let filterType = 'unknown';                let filterVal = 'unknown';                if (d !== null) { filterType = 'discount'; filterVal = d; }                else if (pr !== null) { filterType = 'price'; filterVal = pr; }                else if (ot !== null) { filterType = 'offertype'; filterVal = ot; }                if (typeof trackElementInteraction === 'function') trackElementInteraction({ id: `filter-${filterType}-${filterVal}`, name: 'Filter Button', label: label });                                if (d !== null) {                   if (this.discountFilter) this.discountFilter.value = this.discountFilter.value === d ? '0' : d;                } else if (pr !== null) {                   if (this.priceFilter) this.priceFilter.value = this.priceFilter.value === pr ? 'all' : pr;                } else if (ot !== null) {                   if (this.offerTypeSelect) this.offerTypeSelect.value = this.offerTypeSelect.value === ot ? 'all' : ot;                } else {                   if (this.discountFilter) this.discountFilter.value = '0';                   if (this.priceFilter) this.priceFilter.value = 'all';                   if (this.offerTypeSelect) this.offerTypeSelect.value = 'all';                }                if (d === null && pr === null && ot === null && b.getAttribute("data-type") !== "custom") {                   discBtns.forEach(ro => ro.classList.remove('active'));                   b.classList.add('active');                } else if (b.getAttribute("data-type") !== "custom") {                   // Only operate on hardcoded buttons (those without data-type)                   discBtns.forEach(ro => {                      if (!ro.getAttribute('data-d') && !ro.getAttribute('data-pr') && !ro.getAttribute('data-ot') && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active');                   });                                      let makeActive = true;                   if (d !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-d') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   } else if (pr !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-pr') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   } else if (ot !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-ot') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   }                                      if (makeActive) b.classList.add('active');                                      // Check if anything is active, if not activate "All"                   let anyActive = false;                   discBtns.forEach(ro => { if (ro.classList.contains('active') && ro.getAttribute('data-type') !== 'custom') anyActive = true; });                   if (!anyActive) {                       discBtns.forEach(ro => { if (!ro.getAttribute('data-d') && !ro.getAttribute('data-pr') && !ro.getAttribute('data-ot') && ro.getAttribute('data-type') !== 'custom') ro.classList.add('active'); });                   }                }                                this.fetchDeals(this.currentQuery);             });          });          if (this.brandTrigger && this.brandDropdown) {            this.brandTrigger.addEventListener('click', () => {              this.brandDropdown.classList.toggle('active');            });            document.addEventListener('click', (e) => {              if (this.brandFilterWrapper && !e.composedPath().includes(this.brandFilterWrapper)) {                this.brandDropdown.classList.remove('active');              }            });          }          const showAutocomplete = () => {             if (this.getViewMode() !== 'savings_squad' || !this.autocompleteDropdown || !this.airedaleTags) return;                          let terms = this.airedaleTags;             if (this.airedaleBrands) {                terms = terms.concat(this.airedaleBrands.map(b => b.formatted_value));             }             terms = [...new Set(terms)];                          const query = this.searchInput.value.trim();             let matches = [];             if (query.length > 0) {                 matches = terms.filter(t => t.toLowerCase().includes(query.toLowerCase()) && t.toLowerCase() !== query.toLowerCase());             } else {                 matches = terms;             }                          if (matches.length > 0) {                 this.autocompleteDropdown.innerHTML = matches.map(m => `\x3Cdiv class="tg-df-autocomplete-item" data-tag="${this.escapeHTML(m)}">${this.escapeHTML(m)}<` + `/div>`).join('');                 this.autocompleteDropdown.classList.add('active');             } else {                 this.autocompleteDropdown.classList.remove('active');             }          };          let debounceTimer;          if(this.searchInput) {            this.searchInput.addEventListener('focus', showAutocomplete);            this.searchInput.addEventListener('input', (e) => {              clearTimeout(debounceTimer);              const query = e.target.value.trim();              this.currentQuery = query;              showAutocomplete();              debounceTimer = setTimeout(() => {                this.updateURLParams();                if (query.length > 2) {                  this.fetchDeals(query);                } else if (query.length === 0) {                  if (this.getViewMode() === 'savings_squad') {                    this.activeDealTag = null;                    this.currentQuery = '';                    if (this.categoryFilter) this.categoryFilter.value = 'all';                    this.fetchDeals('');                  } else {                    this.deals = [];                    this.render();                  }                }              }, 400);            });            this.searchInput.addEventListener('keypress', (e) => {              if (e.key === 'Enter') {                if (this.autocompleteDropdown) this.autocompleteDropdown.classList.remove('active');                clearTimeout(debounceTimer);                const query = e.target.value.trim();                this.currentQuery = query;                                let isTag = false;                if (this.airedaleTags && this.airedaleTags.includes(query)) isTag = true;                if (this.airedaleBrands && this.airedaleBrands.some(b => b.formatted_value === query)) isTag = true;                this.activeDealTag = isTag ? query : null;                                trackElementInteraction({ id: 'search-submit', name: 'Ask', label: 'Ask (main search)', text: query });                this.updateURLParams();                if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                   if (query.length === 0 && this.getViewMode() === 'savings_squad') {                       if (this.categoryFilter) this.categoryFilter.value = 'all';                   }                   this.fetchDeals(query);                }              }            });          }          if (this.autocompleteDropdown) {             this.autocompleteDropdown.addEventListener('click', (e) => {                const item = e.target.closest('.tg-df-autocomplete-item');                if (item) {                   const tag = item.getAttribute('data-tag');                   this.currentQuery = tag;                   if (this.searchInput) this.searchInput.value = tag;                   this.activeDealTag = tag;                   if (this.categoryFilter && this.airedaleTags.includes(tag)) {                       this.categoryFilter.value = tag;                   }                   this.autocompleteDropdown.classList.remove('active');                   this.updateURLParams();                   this.fetchDeals(tag);                }             });             document.addEventListener('click', (e) => {               if (this.autocompleteDropdown && this.searchInput && !e.composedPath().includes(this.searchInput) && !e.composedPath().includes(this.autocompleteDropdown)) {                 this.autocompleteDropdown.classList.remove('active');               }             });          }          if (this.searchBtn) {            this.searchBtn.addEventListener('click', () => {              if (this.autocompleteDropdown) this.autocompleteDropdown.classList.remove('active');              clearTimeout(debounceTimer);              const query = this.searchInput.value.trim();              trackElementInteraction({ id: 'search-submit', name: 'Ask', label: 'Ask (main search)', text: query });                            let isTag = false;              if (this.airedaleTags && this.airedaleTags.includes(query)) isTag = true;              if (this.airedaleBrands && this.airedaleBrands.some(b => b.formatted_value === query)) isTag = true;              this.activeDealTag = isTag ? query : null;                            this.currentQuery = query;              this.updateURLParams();              if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                 if (query.length === 0 && this.getViewMode() === 'savings_squad') {                     if (this.categoryFilter) this.categoryFilter.value = 'all';                 }                 this.fetchDeals(query);              }            });          }          if(this.sortSelect && this.sortSelect.querySelector('option[value="date_desc"]') === null) {              const option = document.createElement('option');              option.value = "date_desc";              option.text = "Newest First";              this.sortSelect.insertBefore(option, this.sortSelect.firstChild);          }          if(this.sortSelect) this.sortSelect.addEventListener('change', () => {            trackElementInteraction({ id: `sort-option-${this.sortSelect.value}`, name: 'Sort', label: `Sort: ${this.sortSelect.options[this.sortSelect.selectedIndex].text}` });            this.updateURLParams();            if (this.deals.length > 0) {              this.sortData();              this.render();            }          });                    const priceFilter = this.root.querySelector('#tg-df-price-filter');          if (priceFilter) {            this.priceFilter = priceFilter;            this.priceFilter.addEventListener('change', () => {              trackElementInteraction({ id: `filter-price-${this.priceFilter.value}`, name: 'Price', label: this.priceFilter.options[this.priceFilter.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }            });          }          const updateCustomPrice = () => {             this.updateURLParams();             if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);             } else {                this.render();             }          };          if (this.customPriceMin) {             this.customPriceMin.addEventListener('change', updateCustomPrice);             this.customPriceMin.addEventListener('keypress', (e) => {                if (e.key === 'Enter') updateCustomPrice();             });          }          if (this.customPriceMax) {             this.customPriceMax.addEventListener('change', updateCustomPrice);             this.customPriceMax.addEventListener('keypress', (e) => {                if (e.key === 'Enter') updateCustomPrice();             });          }          const discountFilter = this.root.querySelector('#tg-df-discount-filter');          if (discountFilter) {            this.discountFilter = discountFilter;            this.discountFilter.addEventListener('change', () => {              trackElementInteraction({ id: `filter-discount-${this.discountFilter.value}`, name: 'Discount', label: this.discountFilter.options[this.discountFilter.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }            });          }          if (this.categoryFilter) {            this.categoryFilter.addEventListener('change', (e) => {               const val = e.target.value === 'all' ? null : e.target.value;               this.activeDealTag = val;               if (val) {                 this.currentQuery = val;               } else {                 if (this.searchInput && this.currentQuery === document.querySelector('#tg-df-brand-trigger')?.getAttribute('data-active-brand')) {                     // don't clear current query if a brand is selected                 } else if (this.searchInput) {                     this.currentQuery = '';                     this.searchInput.value = '';                 }               }               this.fetchSavingsSquad();            });          }                    if (this.settingsToggle) {            this.settingsToggle.addEventListener('click', () => {              const o = this.settingsPanel.classList.toggle('active');              this.settingsBackdrop.classList.toggle('active');              if (o) trackElementInteraction({ id: 'filter-open', name: 'Filters', label: 'Open filters' });            });          }                    if (this.settingsBackdrop) {            this.settingsBackdrop.addEventListener('click', () => {              this.settingsPanel.classList.remove('active');              this.settingsBackdrop.classList.remove('active');            });          }                    if (this.regionSelect) {            this.regionSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-region-${this.regionSelect.value}`, name: 'Region', label: this.regionSelect.options[this.regionSelect.selectedIndex].text });              this.updateURLParams();              this.updatePriceDropdownCurrency();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.retailerSelect) {            this.retailerSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-merchant-${this.retailerSelect.value}`, name: 'Retailer', label: this.retailerSelect.options[this.retailerSelect.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.offerTypeSelect) {            this.offerTypeSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-offertype-${this.offerTypeSelect.value}`, name: 'Offer Type', label: this.offerTypeSelect.options[this.offerTypeSelect.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.viewModeSelect) {            this._prevViewMode = this.viewModeSelect.value;            this.viewModeSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-viewmode-${this.viewModeSelect.value}`, name: 'View Mode', label: this.viewModeSelect.options[this.viewModeSelect.selectedIndex].text });                            // Reset all active toggles and filters to prevent config carry-over              this.selectedBrands = [];              if (this.brandTrigger) this.brandTrigger.innerText = 'Select Brands';              if (this.brandDropdown) {                const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                chks.forEach(chk => { chk.checked = false; });              }              if (this.priceFilter) this.priceFilter.value = 'all';              if (this.customPriceMin) this.customPriceMin.value = '';              if (this.customPriceMax) this.customPriceMax.value = '';              if (this.sortSelect) this.sortSelect.value = 'date_desc';              if (this.discountFilter) this.discountFilter.value = '0';              if (this.retailerSelect) this.retailerSelect.value = '';              if (this.offerTypeSelect) this.offerTypeSelect.value = '';              if (this.rowsSelect) this.rowsSelect.value = '12';              if (this.categoryFilter) this.categoryFilter.value = 'all';              this.activeDealTag = null;              this.updateURLParams();              this.applyLayoutMode();                            if (this.getViewMode() === 'savings_squad' || this._prevViewMode === 'savings_squad') {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }              this._prevViewMode = this.viewModeSelect.value;            });          }                    if (this.rowsSelect) {            this.rowsSelect.addEventListener('change', () => {              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.dealModeToggle) {            this.dealModeToggle.addEventListener('change', () => {              this.updateURLParams();              this.render();            });          }          if (this.editorModeToggle) {             this.editorModeToggle.addEventListener('change', (e) => {                this.editorMode = e.target.checked;                this.render();                this.updateFloatingCopyBar();             });          }          if (this.editorCopyBtn) {             this.editorCopyBtn.addEventListener('click', () => {                this.copySelectedDealsToCMS();             });          }          if (this.editorClearBtn) {             this.editorClearBtn.addEventListener('click', () => {                this.selectedDeals.clear();                this.render();                this.updateFloatingCopyBar();             });          }          if (this.grid) {            this.grid.addEventListener('change', (e) => {               if (e.target.classList.contains('tg-df-deal-checkbox')) {                  const dealId = e.target.getAttribute('data-id');                  if (e.target.checked) {                     const dealObj = this.deals.find(d => d.id === dealId);                     if (dealObj) this.selectedDeals.set(dealId, dealObj);                  } else {                     this.selectedDeals.delete(dealId);                  }                  this.updateFloatingCopyBar();               }            });            this.grid.addEventListener('click', (e) => {              const dealCard = e.target.closest('[data-action="deal-click"]');              const similarCard = e.target.closest('[data-action="view-similar-click"]');              const cardLink = dealCard || similarCard;              if (cardLink) {                const productName = cardLink.getAttribute('data-product-name');                const merchantName = cardLink.getAttribute('data-merchant-name');                const productId = cardLink.getAttribute('data-analytics-id');                const price = parseFloat(cardLink.getAttribute('data-price')) || null;                const prevPriceStr = cardLink.getAttribute('data-previous-price');                const previousPrice = prevPriceStr ? parseFloat(prevPriceStr) : null;                const originalLink = cardLink.getAttribute('data-original-link');                const rewrittenLink = cardLink.getAttribute('href');                const revenueId = cardLink.getAttribute('data-revenue-id');                const index = parseInt(cardLink.getAttribute('data-index'), 10) || 0;                const inStock = cardLink.getAttribute('data-in-stock') === 'true';                const totalText = cardLink.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: cardLink.getAttribute('data-model-id') || null,                    matchId: cardLink.getAttribute('data-match-id') || null,                    brand: cardLink.getAttribute('data-model-brand') || null,                    parent: cardLink.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: cardLink.getAttribute('data-merchant-id') || null,                    network: cardLink.getAttribute('data-merchant-network') || null,                    url: cardLink.getAttribute('data-merchant-url') || null,                    name: merchantName                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: normalizeCurrency(this.escapeHTML(cardLink.getAttribute('data-currency') || '$'))                };                if (dealCard) {                  trackDealClick(trackingParams);                } else {                  trackViewSimilarClick(trackingParams);                }              }              const couponsBtn = e.target.closest('[data-action="coupons-click"]');              if (couponsBtn) {                trackElementInteraction({                  id: 'product-card-show-coupons',                  name: 'Coupons',                  label: `Product card coupons: ${couponsBtn.getAttribute('data-merchant')}`                });              }            });          }          this.setupScrollListeners();        }        setupScrollListeners() {          const containers = [             this.root.querySelector('.tg-df-carousel-roundels'),             this.root.querySelector('.tg-df-carousel-filters-wrap'),             this.root.querySelector('#tg-df-grid')          ];                    containers.forEach(container => {             if (!container) return;                          const checkScroll = () => {                if (!container.parentElement) return;                const leftBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-left');                const rightBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-right');                                if (leftBtn) {                   if (container.scrollLeft <= 5) leftBtn.style.display = 'none';                   else leftBtn.style.display = 'flex';                }                                if (rightBtn) {                   if (container.scrollWidth <= container.clientWidth) {                       rightBtn.style.display = 'none';                   } else if (container.scrollLeft >= container.scrollWidth - container.clientWidth - 5) {                       rightBtn.style.display = 'none';                   } else {                       rightBtn.style.display = 'flex';                   }                }             };                          container.addEventListener('scroll', checkScroll);             checkScroll();                          window.addEventListener('resize', checkScroll);                          const observer = new MutationObserver(checkScroll);             observer.observe(container, { childList: true, subtree: true, characterData: false });          });        }        get widgetTypeName() {          const mode = this.viewModeSelect ? this.viewModeSelect.value : (this.viewModeOverride || 'auto');          switch(mode) {              case 'carousel': return 'Carousel';              case 'savings_squad': return 'Savings Squad';              case 'grid': return 'Grid';              case 'row': return 'Row';              default: return 'Auto Collection';          }        }        getRowsLimit() {          if (this.rowsSelect && this.rowsSelect.value) return parseInt(this.rowsSelect.value, 10);          let configSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {             configSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {             configSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(configSource);          if (params.has('rows')) return parseInt(params.get('rows'), 10) || 12;          return 12;        }        getAreaCode() {          if (this.regionSelect && this.regionSelect.value) {            if (this.regionSelect.value === 'auto') return null;            return this.regionSelect.value;          }          let area = null;          try {            const locale = window.navigator.language || window.navigator.userLanguage;            if (locale && locale.includes('-')) {              area = locale.split('-')[1].toUpperCase();            } else if (locale && locale.length === 2) {              if (locale.toUpperCase() === 'EN') { area = 'US'; }              else { area = locale.toUpperCase(); }            }          } catch (e) { /* Ignore */ }                    // Map to known valid options or fallback to US          const valid = ['US', 'GB', 'CA', 'AU', 'DE', 'FR', 'IT'];          if (area === 'UK') area = 'GB';          if (valid.includes(area)) {             return area;          }          return 'US';        }        async fetchDeals(query) {          this.showLoading();          this.deals = [];          this.displayLimit = this.getRowsLimit();                    try {            console.log("getViewMode returns:", this.getViewMode());            if (this.getViewMode() === 'savings_squad') {               await this.fetchSavingsSquad();            } else {               if (this.isBroadQuery(query)) {                 await this.fetchAdviserDeals(query);               } else {                 await this.fetchHawkDeals(query);                 if (this.deals.length === 0) {                   await this.fetchAdviserDeals(query);                 }               }            }          } catch (error) {            console.warn("[Tom's Guide Widget] Fetch error:", error);            this.showError();          }        }        async fetchSavingsSquad() {          let topArticles = this.airedaleArticles;          if (!topArticles) {            const siteParam = this.website || 'tomsguide';            const airedaleUrl = `https://airedale.futurecdn.net/feeds/feed_1781000519267.json?site=${siteParam}&articleType=deals&limit=50`;            let res;            try {               res = await fetch(airedaleUrl);            } catch(e) {               try { res = await fetch(`https://airedale.futurecdn.net/feeds/feed_1776420579726.json?site=${siteParam}&articleType=deals&limit=50`); } catch (err) { console.warn("Fallback fetch failed", err); return; }            }            if (!res.ok) throw new Error('Airedale API Error');            const articles = await res.json();            topArticles = Array.isArray(articles) ? articles.slice(0, 50) : ((articles.data && Array.isArray(articles.data)) ? articles.data.slice(0, 50) : []);            this.airedaleArticles = topArticles;                        let tagCounts = {};            topArticles.forEach((a) => {              let articleTags = new Set();              if (a.articlecategory && Array.isArray(a.articlecategory)) {                 a.articlecategory.forEach((t) => articleTags.add(t));              }              articleTags.forEach(t => {                 tagCounts[t] = (tagCounts[t] || 0) + 1;              });            });                        this.airedaleTags = Object.keys(tagCounts).sort((a, b) => tagCounts[b] - tagCounts[a]);            this.airedaleTagCounts = tagCounts;          }                    let targetArticles = topArticles;          if (!this.activeDealTag && this.currentQuery) {             const tagMatch = this.airedaleTags.find(t => t.toLowerCase() === this.currentQuery.toLowerCase());             if (tagMatch) {                this.activeDealTag = tagMatch;             }          }          if (this.activeDealTag) {             const cleanTag = this.activeDealTag.toLowerCase().replace(/&/g, '').replace(/[^a-z0-9]+/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');             const encodedTag = encodeURIComponent(cleanTag);             const siteParam = this.website || 'tomsguide';             const url = `https://airedale.futurecdn.net/feeds/feed_1781000519267.json?site=${siteParam}&articleType=deals&limit=50&articleCategoryHandle=${encodedTag}`;             try {                const res = await fetch(url);                if (res.ok) {                   const articles = await res.json();                   targetArticles = Array.isArray(articles) ? articles.slice(0, 50) : ((articles.data && Array.isArray(articles.data)) ? articles.data.slice(0, 50) : []);                }             } catch(e) {                console.warn("Failed to fetch by activeDealTag", e);             }          }          let extractedDeals = [];          let seenUrls = new Set();                    let overallBrandsCounts = {};                    // First pass: extract ALL brands from topArticles so the dropdown has all options          topArticles.forEach((article) => {             if (!article.articlepage) return;             let pageData = [];             try { pageData = JSON.parse(article.articlepage[0]); } catch(e){ console.warn(e); }             const savingsSquad = pageData.filter((p) => p.type === 'deal' || p.type === 'featured-product');             savingsSquad.forEach((block) => {                const data = block.data || {};                if (data.brand) {                   const cleanBrand = data.brand.replace(/^\d+\.\s*/, '').trim();                   overallBrandsCounts[cleanBrand] = (overallBrandsCounts[cleanBrand] || 0) + 1;                }             });          });          targetArticles.forEach((article) => {             if (!article.articlepage) return;                          let pageData = [];             try {                pageData = JSON.parse(article.articlepage[0]);             } catch(e){ console.warn(e); }                          const savingsSquad = pageData.filter((p) => p.type === 'deal' || p.type === 'featured-product');                          savingsSquad.forEach((block, idx) => {                const data = block.data || {};                const isFeatured = block.type === 'featured-product';                                const link = data.link || {};                const priceObj = data.price || {};                const image = data.image || {};                                if (data.brand) {                   data.brand = data.brand.replace(/^\d+\.\s*/, '').trim();                }                const externalUrl = isFeatured ? data.url : (link.href || null);                let summaryTitle = isFeatured ? (data.name || data.brand) : (data.productName || link.label || article.articlename);                let description = isFeatured ? (data.strapline || '') : (data.text || '');                                if (!isFeatured && !data.productName && data.text) {                   const brSplit = data.text.split(new RegExp('\x3Cbr\\s*\\/?\\x3E', 'i'));                   if (brSplit.length > 1) {                     summaryTitle = brSplit[0].replace(/<[^>]+>/g, '').trim();                     description = brSplit.slice(1).join(' ').replace(/<br\s*\/?>/gi, ' ').replace(/<\/?(p|div)[^>]*>/gi, ' ').replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').trim();                   } else {                     const match = data.text.match(/\x3Cstrong>(.*?)<\/strong>/);                     if (match) {                       summaryTitle = match[1].replace(/<[^>]+>/g, '').trim();                       if (summaryTitle.endsWith(':')) summaryTitle = summaryTitle.slice(0, -1);                     }                   }                }                                let imageUrl = isFeatured ? image.mos : (image.src || null);                if (imageUrl && imageUrl.startsWith('//')) imageUrl = 'https:' + imageUrl;                                description = description.replace(/<br\s*\/?>/gi, ' ').replace(/<\/?(p|div)[^>]*>/gi, ' ').replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').replace(/View Deal$/i, '').trim();                                let merchantName = data.retailer || '';                if (!merchantName && externalUrl) {                   try {                     merchantName = new URL(externalUrl).hostname.replace('www.', '').split('.')[0];                     merchantName = merchantName.charAt(0).toUpperCase() + merchantName.slice(1);                   }catch(e){ console.warn(e); }                }                if (!merchantName) merchantName = 'Retailer';                const q = (this.currentQuery || '').toLowerCase();                const activeTagLogic = (this.activeDealTag || '').toLowerCase();                if (q.length > 2 && q !== activeTagLogic) {                   const searchTarget = `${summaryTitle || ''} ${description || ''}`.toLowerCase();                   if (!searchTarget.includes(q)) return;                }                let rawPrice = 0;                let rawMsrp = 0;                let currencyStr = '$';                if (isFeatured) {                   rawPrice = typeof data.salePrice === 'number' && data.salePrice > 0 ? data.salePrice : (typeof data.price === 'number' ? data.price : 0);                   rawMsrp = typeof data.salePrice === 'number' && typeof data.price === 'number' && data.price > data.salePrice ? data.price : 0;                   currencyStr = data.currency === 'GBP' ? '£' : '$';                } else {                   rawPrice = priceObj.amount ? parseFloat(priceObj.amount) : 0;                   rawMsrp = priceObj.amountWas ? parseFloat(priceObj.amountWas) : 0;                   currencyStr = priceObj.currency === 'GBP' ? '£' : '$';                }                                let savingAmt = 0;                let savingLabel = '';                if (rawPrice > 0 && rawMsrp > rawPrice) {                   savingAmt = parseFloat((rawMsrp - rawPrice).toFixed(2));                   savingLabel = `Save ${currencyStr}${savingAmt}`;                }                                // Apply Brand filter                if (this.selectedBrands && this.selectedBrands.length > 0) {                   const itemBrand = (data.brand || '').toLowerCase();                   const hasMatch = this.selectedBrands.some(sb => sb.toLowerCase() === itemBrand);                   if (!hasMatch) return;                }                // Apply Price filter                let priceFilterVal = null;                const min = this.customPriceMin ? this.customPriceMin.value : '';                const max = this.customPriceMax ? this.customPriceMax.value : '';                if (min || max) {                   priceFilterVal = `${min}_${max}`;                } else if (this.priceFilter && this.priceFilter.value !== 'all') {                   priceFilterVal = this.priceFilter.value;                }                if (priceFilterVal && rawPrice > 0) {                   if (priceFilterVal === 'under50' && rawPrice >= 50) return;                   if (priceFilterVal === 'over50' && rawPrice <= 50) return;                   if (priceFilterVal === 'over30' && rawPrice <= 30) return;                   if (priceFilterVal === 'over500' && rawPrice <= 500) return;                   if (priceFilterVal.includes('_')) {                      const parts = priceFilterVal.split('_');                      const min = parseFloat(parts[0]);                      const max = parseFloat(parts[1]);                      if (!isNaN(min) && rawPrice < min) return;                      if (!isNaN(max) && rawPrice > max) return;                   }                }                // Apply Discount filter                if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {                   const requiredDiscount = parseInt(this.discountFilter.value);                   if (!isNaN(requiredDiscount) && requiredDiscount > 0) {                      if (!rawMsrp || rawMsrp <= rawPrice) return;                      const ratio = Math.round((1 - (rawPrice / rawMsrp)) * 100);                      if (ratio < requiredDiscount) return;                   }                }                                if (externalUrl) {                   if (seenUrls.has(externalUrl)) return;                  seenUrls.add(externalUrl);                }                                extractedDeals.push({                   id: `airedale-${article.id || Math.random()}-${idx}`,                   url: externalUrl,                   image: imageUrl,                   fallbackImage: imageUrl,                   title: summaryTitle,                   brand: data.brand || '',                   productName: data.productName || '',                   merchant: merchantName,                   rawPrice: rawPrice,                   rawMsrp: rawMsrp,                   price: rawPrice > 0 ? rawPrice.toString() : '',                   msrp: rawMsrp > 0 ? rawMsrp.toString() : '',                   currency: currencyStr,                   isCheckPrice: !rawPrice,                   savingLabel: savingLabel,                   savingType: rawMsrp > rawPrice ? 'amount' : 'none',                   isPrime: false,                   starRating: null,                   description: description,                   text: data.text || '',                   authorName: article.articleauthortext ? article.articleauthortext[0] : (article.articleauthor ? article.articleauthor[0] : ''),                   authorRole: article.articleauthorrole ? article.articleauthorrole[0] : '',                   authorImage: article.articleauthormedia ? article.articleauthormedia[0] : '',                   documentUrl: article.documenturl ? article.documenturl[0] : '',                   modifiedDate: article.contentmodifieddate || article.modifieddate || ''                });             });          });                    const airedaleBrandsList = Object.keys(overallBrandsCounts).map(b => ({              formatted_value: b,              count: overallBrandsCounts[b]          })).sort((a,b) => b.count - a.count);                    if (this.getViewMode() === 'savings_squad') {             this.populateBrandDropdown(airedaleBrandsList.slice(0, 15));             if (this.brandFilterWrapper) {                if (airedaleBrandsList.length === 0) {                    this.brandFilterWrapper.style.display = 'none';                } else {                    this.brandFilterWrapper.style.display = 'flex';                }             }          }                    this.deals = extractedDeals;          this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        isBroadQuery(query) {          const q = query.toLowerCase();          const intentModifiers = ['deals', 'best', 'sale', 'under', 'cheap', 'offers', 'discount'];          return intentModifiers.some(term => q.includes(term));        }        async fetchHawkDeals(query) {          const url = new URL(this.apiUrl);          url.searchParams.append('model_name', query);          const areaCode = this.getAreaCode();          if (areaCode) {            url.searchParams.append('area', areaCode);          }                    if (this.retailerSelect && this.retailerSelect.value) {            url.searchParams.append('filter_merchant_name', this.retailerSelect.value);          }                    if (this.selectedBrands && this.selectedBrands.length > 0) {            url.searchParams.append('filter_label[text_brand]', this.selectedBrands.join(','));          }                    let priceVal = null;          const min = this.customPriceMin ? this.customPriceMin.value : '';          const max = this.customPriceMax ? this.customPriceMax.value : '';          if (min || max) {             priceVal = `${min}_${max}`;          } else if (this.priceFilter && this.priceFilter.value !== 'all') {             priceVal = this.priceFilter.value;          }          if (priceVal) {            if (priceVal === 'under50') {              url.searchParams.append('filter_max_price', '50');            } else if (priceVal === 'over50') {              url.searchParams.append('filter_min_price', '50');            } else if (priceVal === 'over30') {              url.searchParams.append('filter_min_price', '30');            } else if (priceVal === 'over500') {              url.searchParams.append('filter_min_price', '500');            } else if (priceVal.includes('_')) {              const parts = priceVal.split('_');              if (parts[0]) url.searchParams.append('filter_min_price', parts[0]);              if (parts[1]) url.searchParams.append('filter_max_price', parts[1]);            }          }                    if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {            const v = parseInt(this.discountFilter.value);            if (!isNaN(v) && v > 0) {              const ratio = (100 - v) / 100;              url.searchParams.append('min_discount_ratio', ratio.toString());            }          }                    if (this.offerTypeSelect && this.offerTypeSelect.value) {            url.searchParams.append('offer', this.offerTypeSelect.value);          }                    url.searchParams.append('filter_product_types', 'deals');                    url.searchParams.append('rows', this.getRowsLimit().toString());          let response;          try {             response = await fetch(url.toString());          } catch(e) {             if (window.location.protocol === 'file:') {                console.warn("[Tom's Guide Widget] fetch from file:// blocked by local CORS policy, falling back to Adviser mock.");                await this.fetchAdviserDeals(query);                return;             }             console.warn("Hawk fetch failed", e);             this.deals = [];             this.render();             return;          }          if (!response.ok) {            throw new Error('Hawk API Response Error');          }          const rawData = await response.json();          // Safely locate data array from potentially wrapped response          let offers = [];          let modelInfoArray = [];                    let brandFilterData = null;          if (rawData && rawData.widget && rawData.widget.data && Array.isArray(rawData.widget.data.filters)) {             brandFilterData = rawData.widget.data.filters.find(f => f.type === 'label_text_brand');          } else if (rawData && rawData.data && Array.isArray(rawData.data.filters)) {             brandFilterData = rawData.data.filters.find(f => f.type === 'label_text_brand');          }          if (brandFilterData && Array.isArray(brandFilterData.values) && brandFilterData.values.length > 0) {             this.populateBrandDropdown(brandFilterData.values);          } else {             if (this.brandFilterWrapper && this.selectedBrands.length === 0) {                this.brandFilterWrapper.style.display = 'none';             }          }                    if (rawData && rawData.widget && rawData.widget.data) {            if (Array.isArray(rawData.widget.data.offers)) offers = rawData.widget.data.offers;            if (rawData.widget.data.model_info && typeof rawData.widget.data.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.widget.data.model_info) ? rawData.widget.data.model_info : Object.values(rawData.widget.data.model_info);            }          } else if (rawData && rawData.data) {            if (Array.isArray(rawData.data.offers)) offers = rawData.data.offers;            if (rawData.data.model_info && typeof rawData.data.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.data.model_info) ? rawData.data.model_info : Object.values(rawData.data.model_info);            }          } else {            if (Array.isArray(rawData)) offers = rawData;            else if (rawData && Array.isArray(rawData.offers)) offers = rawData.offers;            else if (rawData && rawData.offers && Array.isArray(rawData.offers.offer)) offers = rawData.offers.offer;            else if (rawData && rawData.offers) offers = [].concat(rawData.offers);                        if (rawData && rawData.model_info && typeof rawData.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.model_info) ? rawData.model_info : Object.values(rawData.model_info);            }          }          let modelDetails = {};          modelInfoArray.forEach(m => {            const mId = m.model_id || m.id;            if (mId) {              modelDetails[mId] = {                score: m.score != null ? parseFloat(m.score) : null,                brand: m.brand || null,                parent: (m.parents && Array.isArray(m.parents) && m.parents.length > 0) ? m.parents[0].name : null              };            }          });          offers.forEach(item => {            let data = { ...item };            const mId = data.model_id;            if (mId && modelDetails[mId]) {              data.review_score = modelDetails[mId].score;              data.model_brand = modelDetails[mId].brand;              data.model_parent = modelDetails[mId].parent;            } else {              data.review_score = null;            }                        let itemOffers = [];            if (Array.isArray(item.offers)) itemOffers = item.offers;            else if (Array.isArray(item.offer)) itemOffers = item.offer;            else if (item.offers && typeof item.offers === 'object') itemOffers = [item.offers];            else if (item.offer && typeof item.offer === 'object') itemOffers = [item.offer];            if (itemOffers.length > 0) {              itemOffers.forEach(subItem => {                let subData = { ...item, ...subItem };                const subId = subData.model_id;                if (subId && modelDetails[subId]) {                  subData.review_score = modelDetails[subId].score;                  subData.model_brand = modelDetails[subId].brand;                  subData.model_parent = modelDetails[subId].parent;                } else if (data.review_score != null) {                  subData.review_score = data.review_score;                }                if (subData.merchant && typeof subData.merchant === 'object') {                  subData.merchant_name = subData.merchant.name;                }                this.deals.push(this.extractDealData(subData));              });              return;            }                        if (item.merchant && typeof item.merchant === 'object') {              data.merchant_name = item.merchant.name;            }                        this.deals.push(this.extractDealData(data));          });                    this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        async fetchAdviserDeals(query) {          // ======================================================================          // TODO: ADVISER API REPLACEMENT          // The code below simulates the Adviser API response using mock data.          // Once the real endpoint is ready, remove getAdviserMockData() and           // perform an actual fetch() request similar to fetchHawkDeals().          // Example:          // const area = this.getAreaCode();          // let apiUrl = `https://your-adviser-api.com/search?q=${query}&area=${area}`;          // if (this.priceFilter && this.priceFilter.value !== 'all') {          //   const val = this.priceFilter.value;          //   if (val === 'under50') apiUrl += '&filter_max_price=50';          //   else if (val === '50_100') apiUrl += '&filter_max_price=100';          //   else if (val === '100_200') apiUrl += '&filter_max_price=200';          //   else if (val === '200_500') apiUrl += '&filter_max_price=500';          // }          // const res = await fetch(apiUrl);          // const rawData = await res.json();          // ======================================================================          // Simulating network latency          await new Promise(resolve => setTimeout(resolve, 400));                    const rawData = this.getAdviserMockData();          let offers = [];                    if (rawData && rawData.data && rawData.data.Get && Array.isArray(rawData.data.Get.Deal)) {            offers = rawData.data.Get.Deal;          }                    // Basic client-side filtering for the mock if we want it to react to the query          const q = query.toLowerCase();          const selectedRetailer = (this.retailerSelect && this.retailerSelect.value) ? this.retailerSelect.value.toLowerCase() : null;                    offers.forEach(item => {            const dataObj = item;                        // Apply retailer filter            const itemRetailer = (dataObj.dataRetailer || '').toLowerCase();            if (selectedRetailer && itemRetailer !== selectedRetailer && !itemRetailer.includes(selectedRetailer)) {              return;            }                        // Apply mock price filter            let price = dataObj.dataDiscountedPrice || 0;            if (typeof price === 'string') {              price = parseFloat(price.replace(/[^0-9.]/g, ''));            }            let priceVal = null;            const min = this.customPriceMin ? this.customPriceMin.value : '';            const max = this.customPriceMax ? this.customPriceMax.value : '';            if (min || max) {               priceVal = `${min}_${max}`;            } else if (this.priceFilter && this.priceFilter.value !== 'all') {               priceVal = this.priceFilter.value;            }            if (priceVal) {              if (priceVal === 'under50' && price >= 50) return;              if (priceVal === 'over50' && price <= 50) return;              if (priceVal === 'over30' && price <= 30) return;              if (priceVal === 'over500' && price <= 500) return;              if (priceVal.includes('_')) {                 const parts = priceVal.split('_');                 if (parts[0] && price < parseFloat(parts[0])) return;                 if (parts[1] && price > parseFloat(parts[1])) return;              }            }                        // Map Adviser schema to our widget's expected schema            const mappedData = {              url: dataObj.linkHREF || dataObj.dataLink || '#',              image: dataObj.imageURL || (dataObj.image && dataObj.image.src) || '',              title: dataObj.dataProduct || (dataObj.product && dataObj.product.name) || 'Product Deal',              merchant: dataObj.dataRetailer || 'Retailer',              price: dataObj.dataDiscountedPrice || 0,              currency: dataObj.dataCurrency === 'USD' ? '$' : (dataObj.dataCurrency || '$'),              msrp: dataObj.dataOriginalPrice || null            };                        const titleLow = mappedData.title.toLowerCase();            const merchLow = mappedData.merchant.toLowerCase();                        // Smarter mock filtering            let isMatch = false;            if (q === '' || this.isBroadQuery(q)) {              isMatch = true;            } else if (titleLow.includes(q) || merchLow.includes(q)) {              isMatch = true;            } else if ((q.includes('laptop') || q.includes('mac') || q.includes('pc')) && (titleLow.includes('macbook') || titleLow.includes('laptop'))) {              isMatch = true;            } else if ((q.includes('tv') || q.includes('television')) && (titleLow.includes('tv') || titleLow.includes('oled') || titleLow.includes('qled'))) {              isMatch = true;            } else if ((q.includes('phone') || q.includes('smartphone')) && (titleLow.includes('galaxy') || titleLow.includes('phone'))) {              isMatch = true;            } else if ((q.match(/watch|fitness|run|shoe/)) && (titleLow.includes('forerunner') || titleLow.includes('saucony') || titleLow.includes('watch'))) {              isMatch = true;            }                        if (isMatch) {               this.deals.push(this.extractDealData(mappedData));            }          });                    let rowLimit = this.getRowsLimit();          // Intentionally omitting the slice here to allow "Load More" to work if the API returns more                    this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        getAdviserMockData() {          return {            "data": {              "Get": {                "Deal": [                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 300,                    "dataOriginalPrice": 399,                    "dataProduct": "Samsung Galaxy A36",                    "dataRetailer": "Samsung",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/MqDYsukV3JBG54te6dEs7j.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 14,                    "dataOriginalPrice": 24,                    "dataProduct": "Blink Mini",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/3JurmAjHsDa5tPdaHAwEV8.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 59,                    "dataOriginalPrice": 99,                    "dataProduct": "Ring Video Doorbell",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/rAh4uR7AsAsALCCLTXnLNJ.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 10,                    "dataOriginalPrice": 599,                    "dataProduct": "MacBook Neo",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/Lg4Dvg68j9SbB5CPNrTEpH.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 749,                    "dataOriginalPrice": 849,                    "dataProduct": "65\\\" Fire TV Omni 4K QLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/SG34ZWodUkLTxJvMTbjPYR.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 71,                    "dataOriginalPrice": 160,                    "dataProduct": "Saucony Hurricane 24",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/vxf7UD5T2Am7guVzFoFcZ4.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 649,                    "dataOriginalPrice": 749,                    "dataProduct": "Garmin Forerunner 970",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/3GKnEu7CdhtxPMfnPCMCiA.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1049,                    "dataOriginalPrice": 1499,                    "dataProduct": "LG 48\\\" C4 4K OLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/imvwZV9zoMD6fn9Afuge35.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1499,                    "dataOriginalPrice": 2199,                    "dataProduct": "Samsung 49\\\" Odyssey Neo G9 4K Gaming Monitor",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/XWDEJ5dUAE2nhK8k3Jk7k7.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 299,                    "dataOriginalPrice": 699,                    "dataProduct": "EGOHOME Black Memory Foam Mattress (queen)",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/hMUemtAejNETLVYxNrktzm.jpg"                  }                ]              }            }          };        }        decodeHTML(html) {          if (!html) return '';          const txt = document.createElement("textarea");          txt.innerHTML = String(html);          return txt.value;        }        extractDealData(item) {          const priceRawStr = String(item.price || item.current_price || '0');          const msrpRawStr = String(item.was_price || item.msrp || item.original_price || '0');          const rawPrice = parseFloat(priceRawStr.replace(/[^\d.]/g, '')) || 0;          const rawMsrp = parseFloat(msrpRawStr.replace(/[^\d.]/g, '')) || 0;          const isCheckPrice = rawPrice === 0 || priceRawStr === '0.00' || priceRawStr === '0';                    let originalImageUrl = item.image || item.image_url || item.product_image || '';          let imageUrl = originalImageUrl;          if ((!imageUrl || isCheckPrice) && item.model_image_url) {             imageUrl = item.model_image_url;             originalImageUrl = imageUrl;          } else if ((!imageUrl || isCheckPrice) && item.model_image) {             imageUrl = item.model_image;             originalImageUrl = imageUrl;          }                    if (imageUrl) {            imageUrl = imageUrl.replace(/-(\d+)-(\d+)(\.[a-z.]+)$/i, '$3');          }                    let fallbackImage = '';          if (originalImageUrl && originalImageUrl !== imageUrl) {             fallbackImage = originalImageUrl;          } else if (item.model_image && item.model_image !== imageUrl) {             fallbackImage = item.model_image;          } else if (item.model_image_url && item.model_image_url !== imageUrl) {             fallbackImage = item.model_image_url;          }                    const rawCurrency = item.currency || item.currency_symbol || '$';                    let savingLabel = item.percentage_saving_label || '';          if (!savingLabel && rawMsrp > rawPrice && rawPrice > 0) {            const pct = Math.round(((rawMsrp - rawPrice) / rawMsrp) * 100);            if (pct > 0) {              savingLabel = `${pct}% OFF`;            }          }                    const isPrime = item.shipping && item.shipping.prime === true;                    let scoreRaw = (item.review_score !== undefined && item.review_score !== null && item.review_score > 0) ? parseFloat(item.review_score) : null;          let starRating = 0;          if (scoreRaw !== null) {            starRating = Math.round((scoreRaw > 10 ? scoreRaw / 20 : scoreRaw / 2) * 2) / 2;          }                    return {            id: item.offer_id || item.link || item.url || item.offer_link || Math.random().toString(),            url: item.link || item.url || item.offer_link || '#',            image: imageUrl,            fallbackImage: fallbackImage,            title: item.name || item.title || item.model_name || item.product_name || 'Unknown Product',            brand: item.brand || '',            productName: item.model_name || item.product_name || item.name || '',            merchant: item.merchant_name || item.merchant || item.retailer || 'Retailer',            price: item.price !== undefined ? String(item.price) : '0.00',            currency: this.decodeHTML(rawCurrency),            msrp: item.was_price || item.msrp || item.original_price || null,            rawPrice: rawPrice,            rawMsrp: rawMsrp,            hasWasPrice: (item.was_price !== undefined && item.was_price !== null),            isCheckPrice: isCheckPrice,            savingLabel: savingLabel,            isPrime: isPrime,            starRating: starRating > 0 ? starRating : null,            modelId: item.model_id || '',            productKey: item.product_key || '',            merchantId: (item.merchant && typeof item.merchant === 'object') ? item.merchant.id || '' : '',            matchId: item.match_id || '',            merchantNetwork: (item.merchant && typeof item.merchant === 'object') ? item.merchant.an || '' : '',            merchantUrl: (item.merchant && typeof item.merchant === 'object') ? item.merchant.url || '' : '',            modelBrand: item.model_brand || item.brand || '',            modelParent: item.model_parent || ''          };        }        sortData() {          const sortVal = this.sortSelect ? this.sortSelect.value : 'date_desc';          if (sortVal === 'price_asc') {            this.deals.sort((a, b) => a.rawPrice - b.rawPrice);          } else if (sortVal === 'price_desc') {            this.deals.sort((a, b) => b.rawPrice - a.rawPrice);          } else if (sortVal === 'discount_desc') {            this.deals.sort((a, b) => {              const aDiscount = a.rawMsrp > a.rawPrice ? (a.rawMsrp - a.rawPrice) : 0;              const bDiscount = b.rawMsrp > b.rawPrice ? (b.rawMsrp - b.rawPrice) : 0;              return bDiscount - aDiscount;            });          } else if (sortVal === 'date_desc') {             this.deals.sort((a, b) => {                let dateA = 0;                let dateB = 0;                if (a && a.modifiedDate) {                   const valA = Array.isArray(a.modifiedDate) ? a.modifiedDate[0] : a.modifiedDate;                   dateA = new Date(valA).getTime();                   if (isNaN(dateA)) dateA = 0;                }                if (b && b.modifiedDate) {                   const valB = Array.isArray(b.modifiedDate) ? b.modifiedDate[0] : b.modifiedDate;                   dateB = new Date(valB).getTime();                   if (isNaN(dateB)) dateB = 0;                }                return dateB - dateA;             });          }        }        getFilteredDeals() {          let filteredDeals = [...this.deals];                    if (this.dealModeToggle && this.dealModeToggle.checked) {            filteredDeals = filteredDeals.filter(d => d.hasWasPrice || (d.msrp && d.rawMsrp > d.rawPrice));          }                    return filteredDeals;        }        showLoading() {          const _div = '<' + '/div>';          const skeletonCardHtml = `            \x3Cdiv class="tg-df-card">              \x3Cdiv class="tg-df-card-image-box">                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-img">${_div}              ${_div}              \x3Cdiv class="tg-df-card-body">                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short">${_div}                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text title">${_div}                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text title">${_div}                \x3Cdiv class="tg-df-card-footer mt-auto">                  \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="height:24px;">${_div}                ${_div}              ${_div}              \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text" style="height:44px; margin:0; border-radius:0;">${_div}            ${_div}`;          this.grid.innerHTML = Array(4).fill(skeletonCardHtml).join('');        }        showError() {          const _div = '<' + '/div>';          this.grid.innerHTML = `\x3Cdiv class="tg-df-message">            An error occurred while finding deals. Please check your connection and try again.          ${_div}`;        }        escapeHTML(str) {          if (!str) return '';          return String(str).replace(/[&<>'"]/g, tag => ({              '&': '&', '<': '<', '>': '>', "'": ''', '"': '"'          }[tag] || tag));        }                bindCouponButtons() {          const btns = this.root.querySelectorAll('.tg-df-tag-coupons');          btns.forEach(btn => {            btn.addEventListener('click', (e) => {              e.preventDefault();              e.stopPropagation();              const merchant = btn.getAttribute('data-merchant');              this.openVouchersModal(merchant);            });          });                    const closeBtn = this.root.querySelector('#tg-df-vouchers-close');          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          if (closeBtn) {            closeBtn.onclick = () => this.closeVouchersModal();          }          if (backdrop) {            backdrop.onclick = (e) => {              if (e.target === backdrop) this.closeVouchersModal();            };          }        }                closeVouchersModal() {          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          if (backdrop) backdrop.classList.remove('active');        }                async checkMerchantsCouponsBulk(merchants) {          if (!merchants || merchants.length === 0) return {};          const controller = new AbortController();          const timeoutId = setTimeout(() => controller.abort(), 4000);          try {            const area = this.getAreaCode();            const url = new URL('https://search-api.fie.future.net.uk/widget.php');            url.searchParams.append('model_name', 'Everything');            url.searchParams.append('language', 'en-GB');            if (area) url.searchParams.append('area', area);            url.searchParams.append('combine_product_types', '1');            url.searchParams.append('filter_merchant_name', merchants.join(','));            url.searchParams.append('all_filters', 'false');            url.searchParams.append('exclude_unlabelled', 'false');            url.searchParams.append('include_specs', 'false');            url.searchParams.append('sort', 'voucher');            url.searchParams.append('distinct_merchants', 'natural');            url.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');            url.searchParams.append('rows', '120');            url.searchParams.append('origin', 'widgets-clientside');                        let res; try { res = await fetch(url.toString(), { signal: controller.signal }); } catch (e) { return {}; }            clearTimeout(timeoutId);            if (!res.ok) return {};            const data = await res.json();                        let offers = [];            if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {              offers = data.widget.data.offers;            } else if (data && data.data && Array.isArray(data.data.offers)) {              offers = data.data.offers;            } else if (Array.isArray(data)) {              offers = data;            } else if (data && Array.isArray(data.offers)) {              offers = data.offers;            } else if (data && data.offers && Array.isArray(data.offers.offer)) {              offers = data.offers.offer;            } else if (data && Array.isArray(data.data)) {              offers = data.data;            }                        const foundMerchants = new Set();            offers.forEach(o => {              let mName = o.merchant_name || o.merchant || o.retailer;              if (mName && typeof mName === 'object') mName = mName.name;              if (mName) foundMerchants.add(String(mName).toLowerCase());            });            const resultMap = {};            merchants.forEach(m => {              if (m) resultMap[m] = foundMerchants.has(String(m).toLowerCase());            });            return resultMap;          } catch (e) {            return {};          }        }                async openVouchersModal(merchantName) {          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          const title = this.root.querySelector('#tg-df-vouchers-title');          const content = this.root.querySelector('#tg-df-vouchers-content');                    if (!backdrop || !content) return;                    // HACK: Hide closing tags          const _div = '<' + '/div>';          const _span = '<' + '/span>';          const _a = '<' + '/a>';          const _h4 = '<' + '/h4>';          const _svg = '<' + '/svg>';          const _circle = '<' + '/circle>';          const _polyline = '<' + '/polyline>';          const _rect = '<' + '/rect>';          const _path = '<' + '/path>';                    title.innerText = `${merchantName} Coupons & Deals`;          content.innerHTML = `\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text">${_div}                               \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text">${_div}`;          backdrop.classList.add('active');                    try {            const area = this.getAreaCode();            const url = new URL('https://search-api.fie.future.net.uk/widget.php');            url.searchParams.append('model_name', 'Everything');            url.searchParams.append('language', 'en-GB');            if (area) url.searchParams.append('area', area);            url.searchParams.append('combine_product_types', '1');            url.searchParams.append('filter_merchant_name', merchantName);            url.searchParams.append('all_filters', 'false');            url.searchParams.append('exclude_unlabelled', 'false');            url.searchParams.append('include_specs', 'false');            url.searchParams.append('sort', 'voucher');            url.searchParams.append('distinct_merchants', 'natural');            url.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');            url.searchParams.append('rows', '50');            url.searchParams.append('origin', 'widgets-clientside');                        const res = await fetch(url.toString());            if (!res.ok) throw new Error('API Error');            const data = await res.json();                        let offers = [];            if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {              offers = data.widget.data.offers;            } else if (data && data.data && Array.isArray(data.data.offers)) {              offers = data.data.offers;            } else if (Array.isArray(data)) {              offers = data;            } else if (data && Array.isArray(data.offers)) {              offers = data.offers;            } else if (data && data.offers && Array.isArray(data.offers.offer)) {              offers = data.offers.offer;            } else if (data && Array.isArray(data.data)) {              offers = data.data;            }                        if (offers.length === 0) {              content.innerHTML = `\x3Cdiv class="tg-df-message">No vouchers currently available for ${this.escapeHTML(merchantName)}.${_div}`;              return;            }                        content.innerHTML = offers.map((v, idx) => {              let offerObj = v;              if (v.offers && v.offers.offer) {                offerObj = Array.isArray(v.offers.offer) ? v.offers.offer[0] : v.offers.offer;              } else if (v.offer) {                offerObj = Array.isArray(v.offer) ? v.offer[0] : v.offer;              }              let logoUrl = v.logo_url || offerObj.logo_url || '';              if (!logoUrl && v.merchant) {                if (Array.isArray(v.merchant) && v.merchant.length > 0) logoUrl = v.merchant[0].logo_url || '';                else logoUrl = v.merchant.logo_url || '';              }                            const offerName = offerObj.name || offerObj.title || v.name || v.title || 'Special Offer';              const endTime = offerObj.end_time || v.end_time || '';              const linkUrl = offerObj.link || offerObj.url || v.link || v.url || '#';                            let foundVoucherCode = '';              const findVoucherCode = (obj) => {                if (!obj || typeof obj !== 'object') return;                if (obj.type === 'voucher_code' && obj.display_value) {                  foundVoucherCode = obj.display_value;                  return;                }                if (Array.isArray(obj)) {                  for (const item of obj) {                    findVoucherCode(item);                    if (foundVoucherCode) return;                  }                } else {                  for (const k in obj) {                    if (Object.prototype.hasOwnProperty.call(obj, k)) {                      findVoucherCode(obj[k]);                      if (foundVoucherCode) return;                    }                  }                }              };              findVoucherCode(offerObj);              if (!foundVoucherCode) findVoucherCode(v);                            const voucherCode = foundVoucherCode || offerObj.voucher_code || v.voucher_code || '';              const codeHtml = voucherCode ? `\x3Cspan class="tg-df-voucher-code" data-action="copy-code" data-code="${this.escapeHTML(voucherCode)}" title="Copy to clipboard">                \x3Cspan class="tg-df-voucher-code-text">${this.escapeHTML(voucherCode)}${_span}                \x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-left:6px;flex-shrink:0;" class="tg-df-voucher-copy-icon">                  \x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2">${_rect}                  \x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">${_path}                ${_svg}              ${_span}` : '';                            const logoHtml = logoUrl                 ? `\x3Cimg src="${this.escapeHTML(logoUrl)}" alt="${this.escapeHTML(offerName)}" class="tg-df-voucher-logo" />`                 : `\x3Cdiv class="tg-df-voucher-logo" style="background:#e2e8f0;">${_div}`;                            let expiryHtml = '';              if (endTime) {                let dStr = endTime;                if (!isNaN(dStr) && String(dStr).length === 10) dStr = Number(dStr) * 1000;                const d = new Date(dStr);                if (!isNaN(d.getTime())) {                  const options = { year: 'numeric', month: 'short', day: 'numeric' };                  expiryHtml = `                    \x3Cdiv class="tg-df-voucher-expiry">                      \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">                        \x3Ccircle cx="12" cy="12" r="10">${_circle}                        \x3Cpolyline points="12 6 12 12 16 14">${_polyline}                      ${_svg}                      Expires ${d.toLocaleDateString(undefined, options)}                    ${_div}`;                }              }              const revenueIdVal = generateRevenueId(linkUrl, offerName, merchantName, null);              const rewrittenLinkUrl = rewriteAffiliateLink(linkUrl, area, revenueIdVal);              return `                \x3Ca href="${this.escapeHTML(rewrittenLinkUrl)}" target="_blank" rel="noopener nofollow" class="tg-df-voucher-item"                  data-action="voucher-click"                  data-product-name="${this.escapeHTML(offerName)}"                  data-merchant-name="${this.escapeHTML(merchantName)}"                  data-analytics-id="${this.escapeHTML(offerObj.offer_id || offerObj.id || v.id || '')}"                  data-price=""                  data-previous-price=""                  data-original-link="${this.escapeHTML(linkUrl)}"                  data-revenue-id="${revenueIdVal}"                  data-index="${idx}"                  data-total="${offers.length}"                  data-in-stock="true"                  data-currency="USD"                  data-model-id="${this.escapeHTML(offerObj.model_id || v.model_id || offerObj.id || v.id || '')}"                  data-merchant-id="${this.escapeHTML(offerObj.merchant_id || offerObj.merchant?.id || '')}"                >                  ${logoHtml}                  \x3Cdiv class="tg-df-voucher-content">                    \x3Ch4 class="tg-df-voucher-title">${this.escapeHTML(offerName)}${_h4}                    ${codeHtml}                    ${expiryHtml}                  ${_div}                ${_a}              `;            }).join('');                        // Attach copy functionality            const copyBtns = content.querySelectorAll('[data-action="copy-code"]');            copyBtns.forEach(btn => {              btn.addEventListener('click', async (e) => {                e.preventDefault();                e.stopPropagation();                                const code = btn.getAttribute('data-code');                if (!code) return;                                try {                  const copyToClipboard = async (text) => {                     if (window.navigator.clipboard && window.isSecureContext) {                        try { await window.navigator.clipboard.writeText(text); return; } catch (e) {}                     }                     const textArea = document.createElement("textarea");                     textArea.value = text;                     textArea.style.position = "fixed";                     document.body.appendChild(textArea);                     textArea.focus();                     textArea.select();                     document.execCommand('copy');                     textArea.remove();                  };                  await copyToClipboard(code);                                    // Visual feedback                  btn.classList.add('copied');                  const textSpan = btn.querySelector('.tg-df-voucher-code-text');                  const iconSvg = btn.querySelector('.tg-df-voucher-copy-icon');                                    const origText = textSpan.innerText;                  const origIcon = iconSvg.innerHTML;                                    textSpan.innerText = 'Copied!';                  iconSvg.innerHTML = `\x3Cpolyline points="20 6 9 17 4 12">${_polyline}`;                                    setTimeout(() => {                    if (btn) {                      btn.classList.remove('copied');                      if (textSpan) textSpan.innerText = origText;                      if (iconSvg) iconSvg.innerHTML = origIcon;                    }                  }, 2000);                                    trackElementInteraction({                    id: 'voucher-code-copy',                    name: 'Copy Voucher Code',                    label: `Copied ${code} for ${merchantName}`                  });                } catch (err) {                  console.warn('Failed to copy text: ', err);                }              });            });            // Attach voucher click tracking            const voucherBtns = content.querySelectorAll('[data-action="voucher-click"]');            voucherBtns.forEach(btn => {              btn.addEventListener('click', (e) => {                if (e.target.closest('[data-action="copy-code"]')) return;                                const productName = btn.getAttribute('data-product-name');                const merchantNameAttr = btn.getAttribute('data-merchant-name');                const productId = btn.getAttribute('data-analytics-id');                const price = parseFloat(btn.getAttribute('data-price')) || null;                const prevPriceStr = btn.getAttribute('data-previous-price');                const previousPrice = prevPriceStr ? parseFloat(prevPriceStr) : null;                const originalLink = btn.getAttribute('data-original-link');                const rewrittenLink = btn.getAttribute('href');                const revenueId = btn.getAttribute('data-revenue-id');                const index = parseInt(btn.getAttribute('data-index'), 10) || 0;                const inStock = btn.getAttribute('data-in-stock') === 'true';                const totalText = btn.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: btn.getAttribute('data-model-id') || null,                    matchId: btn.getAttribute('data-match-id') || null,                    brand: btn.getAttribute('data-model-brand') || null,                    parent: btn.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: btn.getAttribute('data-merchant-id') || null,                    network: btn.getAttribute('data-merchant-network') || null,                    url: btn.getAttribute('data-merchant-url') || null,                    name: merchantNameAttr                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: btn.getAttribute('data-currency') || 'USD'                };                if (typeof trackDealClick === 'function') {                  trackDealClick(trackingParams);                }              });            });                                  } catch (e) {            console.warn(e);            content.innerHTML = `\x3Cdiv class="tg-df-message">Failed to load vouchers.${_div}`;          }        }        render() {          try {            if (this.getViewMode() === 'savings_squad' && this.airedaleTags.length > 0) {              if (this.categoryFilterWrapper) {                 this.categoryFilterWrapper.style.display = 'flex';              }              if (this.categoryFilter) {                 const _option = '<' + '/option>';                 let optionsHtml = `\x3Coption value="all">All Categories${_option}`;                 this.airedaleTags.forEach(tag => {                    const isSelected = this.activeDealTag === tag ? 'selected' : '';                    optionsHtml += `\x3Coption value="${this.escapeHTML(tag)}" ${isSelected}>${this.escapeHTML(tag)}${_option}`;                 });                 this.categoryFilter.innerHTML = optionsHtml;                 this.categoryFilter.value = this.activeDealTag || 'all';              }            } else {               if (this.categoryFilterWrapper) {                  this.categoryFilterWrapper.style.display = 'none';               }            }            const displayDeals = this.getFilteredDeals();          // HACK: Hide closing tags from the CMS HTML sanitizer so it doesn't strip them during in-page injection          const _div = '<' + '/div>';          const _span = '<' + '/span>';          const _a = '<' + '/a>';          const _h3 = '<' + '/h3>';          const _p = '<' + '/p>';          const _strong = '<' + '/strong>';          const _sup = '<' + '/sup>';          const _button = '<' + '/button>';          if (displayDeals.length === 0) {            if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {              if (this.deals.length > 0) {                 this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                  No deals match your selected filters.                ${_div}`;              } else if (this.getViewMode() === 'savings_squad' && this.currentQuery.length <= 2) {                 // Do not show "no exact matches" if query is empty for savings_squad                 this.grid.innerHTML = '';              } else {                 this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                  No exact matches found for "\x3Cstrong>${this.escapeHTML(this.currentQuery)}${_strong}". Try adjusting your search term.                ${_div}`;              }            } else {              this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                Search product or category names to discover the best deals from across the web.              ${_div}`;            }            return;          }          let dealsHtml = displayDeals.slice(0, this.displayLimit).map((deal, index) => {            try {               const currencySym = this.escapeHTML(deal.currency);               const isoCurrencyCode = normalizeCurrency(currencySym);               const escapedPrice = this.escapeHTML(deal.price);               const escapedMsrp = this.escapeHTML(deal.msrp);               const areaCode = this.getAreaCode();                              const revenueId = generateRevenueId(deal.url, deal.title, deal.merchant, null);               const originalLink = deal.url;               const rewrittenLink = rewriteAffiliateLink(deal.url, areaCode, revenueId);                        const productCategoryName = 'deals';            const dataAttr = `              data-action="${deal.isCheckPrice ? 'view-similar-click' : 'deal-click'}"              data-analytics-id="${this.escapeHTML(deal.externalProductId || deal.id || '')}"              data-product-name="${this.escapeHTML(deal.title)}"              data-merchant-name="${this.escapeHTML(deal.merchant)}"              data-price="${deal.rawPrice || ''}"              data-previous-price="${deal.rawMsrp || ''}"              data-original-link="${this.escapeHTML(originalLink)}"              data-revenue-id="${revenueId}"              data-index="${index}"              data-total="${displayDeals.length}"              data-in-stock="${deal.inStock !== false}"              data-currency="${this.escapeHTML(isoCurrencyCode)}"              data-model-id="${this.escapeHTML(deal.modelId || '')}"              data-product-key="${this.escapeHTML(deal.productKey || '')}"              data-merchant-id="${this.escapeHTML(deal.merchantId || '')}"            `;                        let priceGroupHtml = '';            let isSavingsSquadMode = this.getViewMode() === 'savings_squad';            let ctaText = 'View Deal';            let formattedPrice = '';            let msrpHtml = '';                        if (deal.isCheckPrice) {              ctaText = 'View Deal';              if (isSavingsSquadMode) {                priceGroupHtml = ``;              } else {                priceGroupHtml = `                  \x3Cdiv class="tg-df-card-price-group">                    \x3Cspan class="tg-df-card-price" style="font-size: 15px; font-weight: 500; font-style: italic;">See price at retailer${_span}                  ${_div}                `;              }            } else {              // Format Price              formattedPrice = escapedPrice.includes(currencySym)                 ? escapedPrice                 : `${currencySym}${escapedPrice}`;                              // Format MSRP              msrpHtml = deal.msrp && deal.rawMsrp > deal.rawPrice                ? `\x3Cspan class="tg-df-card-msrp">${escapedMsrp.includes(currencySym) ? escapedMsrp : currencySym + escapedMsrp}${_span}`                : '';                              priceGroupHtml = isSavingsSquadMode ? `` : `                \x3Cdiv class="tg-df-card-price-group">                  \x3Cspan class="tg-df-card-price">${formattedPrice}${_span}                  ${msrpHtml}                ${_div}              `;            }                        const discountBadgeHtml = deal.savingLabel && !deal.isCheckPrice              ? `\x3Cspan class="tg-df-card-discount-badge">${this.escapeHTML(deal.savingLabel)}${_span}`              : '';                          // HACK for CMS            const _button = '<' + '/button>';            const _svg = '<' + '/svg>';            const _path = '<' + '/path>';            const _rect = '<' + '/rect>';            const _circle = '<' + '/circle>';            const _polyline = '<' + '/polyline>';            const _line = '<' + '/line>';                        let badgesHtml = '';            const primeBadge = deal.isPrime ? `              \x3Cspan class="tg-df-tag tg-df-tag-prime">                \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">                  \x3Cpath d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z">${_path}                ${_svg} Prime              ${_span}            ` : '';                        const couponsBadge = deal.merchant && deal.merchant.toLowerCase().includes('amazon') ? '' : `              \x3Cdiv class="tg-df-coupon-wrapper" data-merchant="${this.escapeHTML(deal.merchant)}" style="display:inline-flex; align-items:center;">                \x3Cdiv class="tg-df-coupon-spinner">${_div}                \x3Cbutton type="button" class="tg-df-tag tg-df-tag-coupons" data-action="coupons-click" data-merchant="${this.escapeHTML(deal.merchant)}" style="display:none;">                  \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">                    \x3Cpath d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z">${_path}                    \x3Cline x1="7" y1="7" x2="7.01" y2="7">${_line}                  ${_svg} Coupons                ${_button}              ${_div}            `;                        // Note: We always add coupons badge if there's a chance, but to allow 3-line titles we check wrapper display state            badgesHtml = `              \x3Cdiv class="tg-df-card-badges">                ${primeBadge}                ${couponsBadge}              ${_div}            `;            const _linearGradient = '<' + '/linearGradient>';            const _polygon = '<' + '/polygon>';            const _stop = '<' + '/stop>';            const _defs = '<' + '/defs>';                        let starHtml = '';            if (deal.starRating) {              let rating = deal.starRating;                            if (rating > 0) {                const fullStars = Math.floor(rating);                const halfStar = (rating - fullStars) >= 0.5 ? 1 : 0;                const emptyStars = Math.max(0, 5 - fullStars - halfStar);                const blue = '#1f69ff'; // Tom's guide brand color from VIEW DEAL button                const gray = '#cbd5e1';                                const starSvgFull = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="${blue}" stroke="${blue}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26">${_polygon}${_svg}`;                                const gradId = 'half_grad_' + Math.floor(Math.random()*1000000);                const starSvgHalf = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" stroke="${blue}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cdefs>\x3ClinearGradient id="${gradId}" x1="0" x2="1" y1="0" y2="0">\x3Cstop offset="50%" stop-color="${blue}">${_stop}\x3Cstop offset="50%" stop-color="transparent">${_stop}${_linearGradient}${_defs}                  \x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26" fill="url(#${gradId})">${_polygon}${_svg}`;                                  const starSvgEmpty = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="${gray}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26">${_polygon}${_svg}`;                                let stars = [];                for (let i=0; i<fullStars; i++) stars.push(starSvgFull);                if (halfStar) stars.push(starSvgHalf);                for (let i=0; i<emptyStars; i++) stars.push(starSvgEmpty);                                starHtml = `\x3Cdiv class="tg-df-card-stars" style="display:flex;align-items:center;margin-bottom:8px;font-size:13px;font-weight:600;color:var(--tg-df-text-muted);">                  \x3Cspan style="margin-right:6px;">Tom's Guide:${_span}                  \x3Cdiv style="display:flex;gap:2px;">                    ${stars.join('')}                  ${_div}                ${_div}`;              }            }            let htmlOutput = '';            if (isSavingsSquadMode) {              htmlOutput += `              \x3Cdiv class="hawk-deal-widget-container tg-df-mobile-only" data-collapsible="true">                ${this.editorMode ? `\x3Cinput type="checkbox" class="tg-df-deal-checkbox" data-id="${this.escapeHTML(deal.id)}" ${this.selectedDeals.has(deal.id) ? 'checked' : ''} style="margin-bottom: 10px;">` : ''}                \x3Cdiv class="hawk-deal-widget-wrap">                  \x3Cdiv class="hawk-deal-widget-image-container">                    \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" rel="sponsored noopener" target="_blank" class="hawk-affiliate-link-deal-widget" ${dataAttr}>                      \x3Cimg ${deal.image ? `src="${this.escapeHTML(deal.image)}"` : ''} alt="${this.escapeHTML(deal.title)}" class="hawk-lazy-image-deal-widget" loading="lazy" width="140" height="160" onerror="${deal.fallbackImage ? `if(!this.dataset.fb) { this.dataset.fb='1'; this.src='${this.escapeHTML(deal.fallbackImage)}'; } else { this.style.opacity='0'; }` : `this.style.opacity='0';`}">                    ${_a}                  ${_div}                  \x3Cdiv class="hawk-deal-widget-text-cta-container">                    \x3Cdiv class="hawk-deal-widget-text-body-container">                      \x3Cdiv class="hawk-deal-widget-text-body-main">                        \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                          ${deal.isCheckPrice ? `                            \x3Cspan class="hawk-deal-widget-title-product-title">${this.escapeHTML(deal.title)}${_span}                          ` : `                            \x3Cspan class="hawk-deal-widget-title-product-title">${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_span}                          `}                        ${_a}                        ${!deal.isCheckPrice && deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `                          \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                            \x3Cspan class="hawk-deal-widget-title-was-price">was ${currencySym}${escapedMsrp}${_span}                          ${_a}                        ` : ''}                        \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                          \x3Cspan class="hawk-deal-widget-title-retailer-price">                            ${!deal.isCheckPrice ? `                              \x3Cspan class="hawk-deal-widget-title-price">now ${formattedPrice}${_span}                              \x3Cspan class="hawk-deal-widget-title-retailer"> at ${this.escapeHTML(deal.merchant)}${_span}                            ` : `                              \x3Cspan class="hawk-deal-widget-title-price">See price at ${this.escapeHTML(deal.merchant)}${_span}                            `}                          ${_span}                        ${_a}                        ${deal.description ? `\x3Cdiv class="hawk-deal-widget-text-body-description tg-df-card-desc-container" style="margin-bottom: 12px; position: relative;">                          \x3Cp class="tg-df-card-desc-content" style="font-size: 13px; color: var(--tg-df-text-muted); margin-bottom: 0; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;">${this.escapeHTML(deal.description)}${_p}                          \x3Cbutton type="button" class="tg-df-card-desc-btn" style="display: none; appearance: none; border: none; color: #000000; font-size: 11px; font-weight: 700; text-transform: uppercase; cursor: pointer; font-family: inherit; position: absolute; bottom: 2px; right: 0; background: linear-gradient(to right, transparent, #fff 20%, #fff); padding: 0 0 0 16px;" onclick="                            var c = this.parentNode;                            if (this.dataset.expanded === 'true') {                              var pd = (c.tagName === 'P') ? c : this.previousElementSibling;                              if (c.tagName === 'P') { c.parentNode.appendChild(this); pd = c; }                              pd.style.display = '-webkit-box';                              pd.style.webkitLineClamp = '3';                              this.textContent = 'READ MORE';                              this.style.position = 'absolute';                              this.style.background = 'linear-gradient(to right, transparent, #fff 20%, #fff)';                              this.style.paddingLeft = '16px';                              this.dataset.expanded = 'false';                            } else {                              var pd = this.previousElementSibling;                              pd.style.display = 'inline';                              pd.style.webkitLineClamp = 'unset';                              this.textContent = 'READ LESS';                              this.style.position = 'static';                              this.style.background = 'transparent';                              this.style.paddingLeft = '4px';                              this.dataset.expanded = 'true';                              pd.appendChild(this);                            }                          ">READ MORE${_button}                        \x3C/div>` : ''}                      ${_div}                    ${_div}                    ${deal.authorName ? `                      \x3Cdiv class="tg-df-author-line-mobile" style="padding: 0 0 12px 0; background: transparent;">                         \x3Cdiv style="display: flex; align-items: center; gap: 12px;">                            ${deal.authorImage ? `\x3Cimg src="${this.escapeHTML(deal.authorImage)}" alt="${this.escapeHTML(deal.authorName)}" class="tg-df-author-img" width="40" height="40" style="border-radius: 50%; object-fit: cover; flex-shrink: 0; aspect-ratio: 1 / 1; min-width: 40px; min-height: 40px;">` : ''}                            \x3Cdiv style="display: flex; flex-direction: column;">                               \x3Cdiv style="font-size: 10px; color: var(--tg-df-text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 2px; font-weight: 600;">\x3Cspan style="color: #FF6600;">${this.escapeHTML(deal.merchant)}${_span} deal recommended by:${_div}                               \x3Cdiv style="font-size: 11px; color: var(--tg-df-text); line-height: 1.3;">                                  \x3Cstrong>\x3Ca href="https://www.tomsguide.com/${this.escapeHTML(deal.documentUrl || '').replace(/^\/+/, '')}" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit; border-bottom: 1px dotted var(--tg-df-text-muted);">${this.escapeHTML(deal.authorName)}${_a}${_strong}                                  ${deal.authorRole && !['null', 'nul', 'undefined'].includes(String(deal.authorRole).toLowerCase()) ? ` • ${this.escapeHTML(deal.authorRole)}` : ''}                                  ${deal.modifiedDate ? `\x3Cdiv style="color: var(--tg-df-text-muted); margin-top: 2px;">${getTimeAgo(deal.modifiedDate)}${_div}` : ''}                               ${_div}                            ${_div}                         ${_div}                      ${_div}                    ` : ''}                    \x3Cdiv class="hawk-deal-widget-footer">                      \x3Cdiv class="hawk-deal-widget-button-wrapper">                        \x3Cdiv class="hawk-deal-widget-preferred-partner-wrapper">                          \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-deal-button" rel="sponsored noopener" target="_blank" ${dataAttr}>                            \x3Cspan>View Deal${_span}                          ${_a}                        ${_div}                      ${_div}                    ${_div}                  ${_div}                ${_div}              ${_div}              `;            }            htmlOutput += `              \x3Cdiv class="tg-df-card ${isSavingsSquadMode ? 'tg-df-desktop-only' : ''}">                ${this.editorMode ? `\x3Cinput type="checkbox" class="tg-df-deal-checkbox" data-id="${this.escapeHTML(deal.id)}" ${this.selectedDeals.has(deal.id) ? 'checked' : ''}>` : ''}                \x3Cdiv class="tg-df-card-image-box">                  ${discountBadgeHtml}                  \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" style="display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;">                    \x3Cimg ${deal.image ? `src="${this.escapeHTML(deal.image)}"` : ''} alt="${this.escapeHTML(deal.title)}" class="tg-df-card-image" loading="lazy" onerror="${deal.fallbackImage ? `if(!this.dataset.fb) { this.dataset.fb='1'; this.src='${this.escapeHTML(deal.fallbackImage)}'; } else { this.style.opacity='0'; }` : `this.style.opacity='0';`}">                  ${_a}                  \x3Cdiv class="tg-df-card-merchant-wrapper" style="position: absolute; bottom: 0; right: 0; background: transparent; padding: 8px 12px; z-index: 10;">                     \x3Cspan class="tg-df-card-merchant-pill" style="text-align: right; margin-bottom: 0;" title="${this.escapeHTML(deal.merchant)}">${this.escapeHTML(deal.merchant)}${_span}                  ${_div}                ${_div}                \x3Cdiv class="tg-df-card-body">                  ${starHtml}                  ${badgesHtml}                  \x3Ch3 class="tg-df-card-title tg-df-custom-savings-squad-title" title="${this.escapeHTML(deal.title)}">                    \x3Ca href="${this.escapeHTML(rewrittenLink)}" disable-tracking="true" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit;">                      ${isSavingsSquadMode                         ? (deal.isCheckPrice                             ? (deal.title && deal.title.includes(':')                                 ? `\x3Cstrong>${this.escapeHTML(deal.title.substring(0, deal.title.indexOf(':') + 1))}${_strong}\x3Cspan style="color: #1f69ff; font-weight: normal;">${this.escapeHTML(deal.title.substring(deal.title.indexOf(':') + 1))}${_span}`                                : this.escapeHTML(deal.title)                              )                             : `\x3Cstrong>${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_strong} ${deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `\x3Cspan style="color: #d0021b; text-decoration: line-through; font-weight: normal; margin-right: 4px;">was ${currencySym}${escapedMsrp}${_span} ` : ''}\x3Cspan style="color: #1f69ff; font-weight: normal;">now ${formattedPrice} at ${this.escapeHTML(deal.merchant)}${_span}`                          )                        : this.escapeHTML(deal.title)                      }                    ${_a}                  ${_h3}                  ${deal.description ? `\x3Cdiv class="tg-df-card-desc-container" style="margin-bottom: 12px; position: relative;">                    \x3Cp class="tg-df-card-desc-content" style="font-size: 13px; color: var(--tg-df-text-muted); margin-bottom: 0; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;">${this.escapeHTML(deal.description)}${_p}                    \x3Cbutton type="button" class="tg-df-card-desc-btn" style="display: none; appearance: none; border: none; color: #000000; font-size: 11px; font-weight: 700; text-transform: uppercase; cursor: pointer; font-family: inherit; position: absolute; bottom: 2px; right: 0; background: linear-gradient(to right, transparent, #fff 20%, #fff); padding: 0 0 0 16px;" onclick="                      var c = this.parentNode;                      if (this.dataset.expanded === 'true') {                        var pd = (c.tagName === 'P') ? c : this.previousElementSibling;                        if (c.tagName === 'P') { c.parentNode.appendChild(this); pd = c; }                        pd.style.display = '-webkit-box';                        pd.style.webkitLineClamp = '3';                        this.textContent = 'READ MORE';                        this.style.position = 'absolute';                        this.style.background = 'linear-gradient(to right, transparent, #fff 20%, #fff)';                        this.style.paddingLeft = '16px';                        this.dataset.expanded = 'false';                      } else {                        var pd = this.previousElementSibling;                        pd.style.display = 'inline';                        pd.style.webkitLineClamp = 'unset';                        this.textContent = 'READ LESS';                        this.style.position = 'static';                        this.style.background = 'transparent';                        this.style.paddingLeft = '4px';                        this.dataset.expanded = 'true';                        pd.appendChild(this);                      }                    ">READ MORE${_button}                  \x3C/div>` : ''}                  \x3Cdiv class="tg-df-card-footer">                    ${deal.authorName ? `                    \x3Cdiv class="tg-df-author-line-desktop" style="padding: 0 0 ${isSavingsSquadMode ? 0 : 12}px 0;">                       \x3Cdiv style="display: flex; align-items: center; gap: 10px;">                          ${deal.authorImage ? `\x3Cimg src="${this.escapeHTML(deal.authorImage)}" alt="${this.escapeHTML(deal.authorName)}" class="tg-df-author-img" width="36" height="36" style="border-radius: 50%; object-fit: cover; flex-shrink: 0; aspect-ratio: 1 / 1; min-width: 36px; min-height: 36px;">` : ''}                          \x3Cdiv style="display: flex; flex-direction: column;">                             \x3Cdiv style="font-size: 10px; color: var(--tg-df-text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 2px; font-weight: 600;">Recommended by:${_div}                             \x3Cdiv style="font-size: 11px; color: var(--tg-df-text); line-height: 1.2;">                                \x3Cstrong>\x3Ca href="https://www.tomsguide.com/${this.escapeHTML(deal.documentUrl || '').replace(/^\/+/, '')}" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit; border-bottom: 1px dotted var(--tg-df-text-muted);">${this.escapeHTML(deal.authorName)}${_a}${_strong}                                ${deal.authorRole && !['null', 'nul', 'undefined'].includes(String(deal.authorRole).toLowerCase()) ? ` • ${this.escapeHTML(deal.authorRole)}` : ''}                                ${deal.modifiedDate ? `\x3Cspan style="color: var(--tg-df-text-muted);"> • ${getTimeAgo(deal.modifiedDate)}${_span}` : ''}                             ${_div}                          ${_div}                       ${_div}                    ${_div}                    ` : ''}                    ${priceGroupHtml}                  ${_div}                ${_div}                \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" class="tg-df-card-cta" style="text-decoration: none; border-radius: 0;">${ctaText}${_a}              ${_div}            `;                        return htmlOutput;            } catch (e) {               console.log("Error rendering deal in map for index", index, typeof deal === 'object' ? JSON.stringify(deal) : deal, "MSG:", e.message);               return '';            }          }).join('');                    if (displayDeals.length > this.displayLimit) {            dealsHtml += `              \x3Cdiv style="width: 100%; display: flex; justify-content: center; margin-top: 16px; grid-column: 1 / -1;">                \x3Cbutton type="button" class="tg-df-tag-outline tg-df-load-more" style="padding: 8px 24px; border-radius: 100px; font-weight: 600; font-size: 14px; cursor: pointer;">Load More${_button}              ${_div}            `;          }                    this.grid.innerHTML = dealsHtml;          // Inject JSON-LD          try {            let targetNode = this.hostContainer || document.head;            let jsonLdScript = targetNode.querySelector('#tg-df-json-ld-' + this.widgetId);            if (!jsonLdScript) {                jsonLdScript = document.createElement('script');                jsonLdScript.type = 'application/ld+json';                jsonLdScript.id = 'tg-df-json-ld-' + this.widgetId;                targetNode.appendChild(jsonLdScript);            }            const jsonLdData = {              "@context": "https://schema.org",              "@type": "ItemList",              "itemListElement": displayDeals.slice(0, this.displayLimit).map((deal, index) => {                 let isoCurrency = "USD";                 if (deal.currency === '£') isoCurrency = "GBP";                 else if (deal.currency === '€') isoCurrency = "EUR";                 else if (deal.currency === 'A$') isoCurrency = "AUD";                 else if (deal.currency === 'CA$') isoCurrency = "CAD";                 const areaCode = typeof this.getAreaCode === 'function' ? this.getAreaCode() : 'US';                 const revenueId = typeof generateRevenueId === 'function' ? generateRevenueId(deal.url, deal.title, deal.merchant, null) : '';                 const rewrittenLink = typeof rewriteAffiliateLink === 'function' ? rewriteAffiliateLink(deal.url, areaCode, revenueId) : deal.url;                 return {                   "@type": "ListItem",                   "position": index + 1,                   "item": {                     "@type": "Product",                     "name": deal.title,                     "image": deal.image || "",                     "description": deal.description || "",                     "brand": {                       "@type": "Brand",                       "name": deal.brand || ""                     },                     "offers": {                       "@type": "Offer",                       "priceCurrency": isoCurrency,                       "price": deal.rawPrice || 0,                       "url": rewrittenLink,                       "seller": {                         "@type": "Organization",                         "name": deal.merchant || ""                       }                     }                   }                 };              }).filter(item => item.item.name)            };            jsonLdScript.textContent = JSON.stringify(jsonLdData);          } catch(e) { console.warn("JSON-LD generation failed", e); }          setTimeout(() => {            const contents = this.root.querySelectorAll('.tg-df-card-desc-content');            contents.forEach(p => {              if (p.scrollHeight > p.clientHeight || p.scrollHeight > 60) {                if (p.nextElementSibling) {                  p.nextElementSibling.style.display = 'block';                }              }            });                        // Allow hawklinks.js to discover and rewrite our widget links             // by appending the .article-body class and manually triggering processArticle.            let container = this.root.classList.contains('tg-df-container') ? this.root : this.root.querySelector('.tg-df-container');            if (container && !container.classList.contains('article-body')) {               container.classList.add('article-body');            }            if (this.grid && !this.grid.classList.contains('article-body')) this.grid.classList.add('article-body');            document.dispatchEvent(new CustomEvent('processArticle', { detail: { element: this.root } }));          }, 50);          const loadMoreBtn = this.grid.querySelector('.tg-df-load-more');          if (loadMoreBtn) {            loadMoreBtn.addEventListener('click', () => {              if (typeof trackElementInteraction === 'function') {                trackElementInteraction({ id: 'load-more', name: 'Load more', label: 'Load More Results' });              }              this.displayLimit += this.getRowsLimit();              this.render();            });          }                      this.bindCouponButtons();            this.checkAndUpdateCoupons();          } catch(e) {            console.warn("Widget render error", e);          }        }                async checkAndUpdateCoupons() {          const wrappers = Array.from(this.root.querySelectorAll('.tg-df-coupon-wrapper'));          if (wrappers.length === 0) return;                    const merchants = [...new Set(wrappers.map(w => w.getAttribute('data-merchant')).filter(Boolean))];          if (merchants.length === 0) return;          const couponResultsMap = await this.checkMerchantsCouponsBulk(merchants);                    for (const merchant of merchants) {            const hasCoupons = !!couponResultsMap[merchant];            const merchantWrappers = wrappers.filter(w => w.getAttribute('data-merchant') === merchant);            merchantWrappers.forEach(wrapper => {              const spinner = wrapper.querySelector('.tg-df-coupon-spinner');              const btn = wrapper.querySelector('.tg-df-tag-coupons');                            if (spinner) spinner.style.display = 'none';                            if (hasCoupons && btn) {                btn.style.display = 'inline-flex';              } else if (!hasCoupons) {                wrapper.style.display = 'none';              }            });          }        }        updateFloatingCopyBar() {          if (!this.editorBar || !this.editorSelectedCount) return;          if (this.editorMode && this.selectedDeals.size > 0) {            this.editorBar.style.display = 'flex';            this.editorSelectedCount.innerText = this.selectedDeals.size;          } else {            this.editorBar.style.display = 'none';          }        }        async copySelectedDealsToCMS() {           function htmlToSlate(htmlString) {              if (!htmlString) return [{ type: 'paragraph', children: [{ text: '' }] }];              let doc;              if (typeof window !== 'undefined' && window.DOMParser) {                 doc = new DOMParser().parseFromString(htmlString, 'text/html');              } else {                 doc = document.implementation.createHTMLDocument('');                 doc.body.innerHTML = htmlString;              }                            function parseNode(node, marks = {}) {                  if (node.nodeType === 3) {                      const text = node.textContent;                      if (!text) return null;                      return { text: text, ...marks };                  }                  if (node.nodeType === 1) {                      const tagName = node.tagName.toLowerCase();                      if (tagName === 'br') {                          return { type: 'line-break', children: [{ text: '' }] };                      }                      if (tagName === 'p') {                          let children = Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                          if (children.length === 0) children.push({ text: "" });                          return { type: 'paragraph', children };                      }                      if (tagName === 'strong' || tagName === 'b') {                          const newMarks = { ...marks, bold: true };                          return Array.from(node.childNodes).map(child => parseNode(child, newMarks)).flat().filter(Boolean);                      }                      if (tagName === 'em' || tagName === 'i') {                          const newMarks = { ...marks, italic: true };                          return Array.from(node.childNodes).map(child => parseNode(child, newMarks)).flat().filter(Boolean);                      }                      if (tagName === 'a') {                          const href = node.getAttribute('href') || '';                          let children = Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                          if (children.length === 0) children.push({ text: "" });                          return {                              type: 'link',                              url: href,                              isNoFollow: (node.getAttribute('rel') || '').includes('nofollow'),                              isSponsored: (node.getAttribute('rel') || '').includes('sponsored'),                              isOpenNewTab: node.getAttribute('target') === '_blank',                              isPreventDataRewrite: false,                              children: children                          };                      }                      return Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                  }                  return null;              }                            let blocksArray = [];              let currentParagraphChildren = [];              function flushParagraph() {                  if (currentParagraphChildren.length > 0) {                      blocksArray.push({ type: 'paragraph', children: currentParagraphChildren });                      currentParagraphChildren = [];                  }              }              Array.from(doc.body.childNodes).forEach(node => {                  const parsed = parseNode(node, {});                  const parsedItems = Array.isArray(parsed) ? parsed : (parsed ? [parsed] : []);                  parsedItems.forEach(item => {                      if (item.type === 'paragraph') {                          flushParagraph();                          blocksArray.push(item);                      } else {                          currentParagraphChildren.push(item);                      }                  });              });              flushParagraph();              if (blocksArray.length === 0) {                  blocksArray = [{ type: 'paragraph', children: [{ text: '' }] }];              }              return blocksArray;           }           const blocks = [];                      this.editorCopyBtn.innerHTML = '\x3Cspan class="tg-df-coupon-spinner" style="display:inline-block; margin-right:8px; border-top-color:#fff;">' + '<' + '/span> Copying...';           for (const deal of Array.from(this.selectedDeals.values())) {              const url = deal.url;              const merchant = deal.merchant;              const title = deal.title;              const image = deal.image;              const currentPrice = deal.currency + deal.rawPrice;              const wasPrice = deal.hasWasPrice && deal.rawMsrp > deal.rawPrice ? deal.currency + deal.rawMsrp : '';                            let couponsChildren = [];              try {                  const area = this.getAreaCode();                  const apiUrl = new URL('https://search-api.fie.future.net.uk/widget.php');                  apiUrl.searchParams.append('model_name', 'Everything');                  apiUrl.searchParams.append('language', 'en-GB');                  apiUrl.searchParams.append('area', area);                  apiUrl.searchParams.append('combine_product_types', '1');                  apiUrl.searchParams.append('filter_merchant_name', merchant);                  apiUrl.searchParams.append('all_filters', 'false');                  apiUrl.searchParams.append('exclude_unlabelled', 'false');                  apiUrl.searchParams.append('include_specs', 'false');                  apiUrl.searchParams.append('sort', 'voucher');                  apiUrl.searchParams.append('distinct_merchants', 'natural');                  apiUrl.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');                  apiUrl.searchParams.append('rows', '3');                  apiUrl.searchParams.append('origin', 'widgets-clientside');                                    let res; try { res = await fetch(apiUrl.toString()); } catch (e) { return; }                  if (res.ok) {                      const data = await res.json();                      let offers = [];                      if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {                        offers = data.widget.data.offers;                      } else if (data && data.data && Array.isArray(data.data.offers)) {                        offers = data.data.offers;                      }                                            if (offers.length > 0) {                          couponsChildren.push({ text: "Also check out these coupons: ", bold: true });                          offers.slice(0, 3).forEach((offer, idx) => {                              const actualOffer = offer.offer || offer;                              const offerName = actualOffer.name || actualOffer.title || offer.model_name || offer.title || offer.name || 'Coupon';                              const linkUrl = actualOffer.link || actualOffer.url || actualOffer.offer_link || '#';                              couponsChildren.push({ type: "line-break", children: [{ text: "" }] });                              couponsChildren.push({ text: "🎟️ " });                              couponsChildren.push({                                  type: "link",                                  url: linkUrl,                                  isNoFollow: true,                                  isSponsored: false,                                  isOpenNewTab: true,                                  isPreventDataRewrite: false,                                  children: [{ text: offerName, bold: true }]                              });                          });                      }                  }              } catch (err) {                  console.warn('Failed to fetch coupons for', merchant, err);              }              let descriptionValue = [];              if (deal.text) {                 descriptionValue = htmlToSlate(deal.text);              } else {                 const dealDescriptions = [                   `Don't miss out on this fantastic deal for the ${title}. It is currently available at ${merchant} for a highly competitive price.`,                   `We've spotted an excellent price drop on the ${title}. Grab it now at ${merchant} before it's gone.`,                   `The ${title} is currently seeing a generous discount over at ${merchant}. This is a perfect time to buy if you've been holding out.`,                   `If you're in the market for the ${title}, ${merchant} has just the deal for you.`,                   `Score the ${title} for less at ${merchant} right now. This is a rare chance to save big.`,                   `Upgrade your setup with the ${title}, now available at a stellar price via ${merchant}.`                 ];                 const randomDescription = dealDescriptions[Math.floor(Math.random() * dealDescriptions.length)];                 descriptionValue = [                    { type: "paragraph", children: [{ text: randomDescription }] }                 ];              }                            if (couponsChildren.length > 0) {                 let lastBlock = descriptionValue[descriptionValue.length - 1];                 if (lastBlock && lastBlock.type === 'paragraph') {                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children.push({ text: "Also check out these coupons: ", bold: true });                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children = lastBlock.children.concat(couponsChildren);                 } else {                     descriptionValue.push({                         type: "paragraph",                         children: [                             { type: "line-break", children: [{ text: "" }] },                             { type: "line-break", children: [{ text: "" }] },                             { text: "Also check out these coupons: ", bold: true },                             { type: "line-break", children: [{ text: "" }] },                             ...couponsChildren                         ]                     });                 }              }              function normalizeCurrencyToISO(symbol) {                const map = { '£': 'GBP', '$': 'USD', 'A$': 'AUD', 'CA$': 'CAD', '€': 'EUR' };                return map[symbol] || symbol;              }              const isoCurrency = normalizeCurrencyToISO(deal.currency);              blocks.push({                 id: (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : 'cms-' + Date.now() + Math.random(),                 blockTypeName: "deal",                 excludeFrom: [],                 collapsible: false,                 props: {                    description: {                       value: descriptionValue,                       touched: false,                       validationMessage: ""                    },                    image: {                       value: {                          credit: [{ type: "paragraph", children: [{ text: merchant }] }],                          dateCreated: Date.now(),                          dateModified: Date.now(),                          distribution: [],                          fileSize: 0,                          height: 1000,                          id: deal.id,                          imageRights: "",                          src: image,                          name: title + ".jpg",                          tags: [],                          width: 1000                       },                       touched: false,                       validationMessage: ""                    },                    showDealButton: { value: true, touched: false, validationMessage: "" },                    isPreferredPartner: { value: false, touched: false, validationMessage: "" },                    linkHref: { value: url, touched: false, validationMessage: "" },                    linkLabel: { value: "", touched: false, validationMessage: "" },                    linkIsNoFollow: { value: true, touched: false, validationMessage: "" },                    linkIsSponsored: { value: false, touched: false, validationMessage: "" },                    linkIsOpenNewWindow: { value: true, touched: false, validationMessage: "" },                    customPromoFlags: { value: [], touched: false, validationMessage: "" },                    showStarDeal: { value: false, touched: false, validationMessage: "" },                    savingType: { value: "none", touched: false, validationMessage: "" },                    starDealPromoFlag: { value: "", touched: false, validationMessage: "" },                    showEditorsChoice: { value: false, touched: false, validationMessage: "" },                    editorsChoiceTitle: { value: "", touched: false, validationMessage: "" },                    hawkPriceCurrency: { value: { value: isoCurrency, label: isoCurrency }, touched: false, validationMessage: "" },                    hawkPrice: { value: deal.hasWasPrice ? String(deal.rawMsrp) : String(deal.rawPrice), touched: false, validationMessage: "" },                    hawkSalePrice: { value: String(deal.rawPrice), touched: false, validationMessage: "" },                    lastCheckedPriceDate: { value: "", touched: false, validationMessage: "" },                    hawkModel: { touched: false, validationMessage: "" },                    productId: { value: "", touched: false, validationMessage: "" },                    voucherId: { value: "", touched: false, validationMessage: "" },                    brand: { value: deal.brand || merchant, touched: false, validationMessage: "" },                    productName: { value: title, touched: false, validationMessage: "" },                    label: { value: "", touched: false, validationMessage: "" },                    retailer: { value: merchant, touched: false, validationMessage: "" },                    priceCheckError: false                 },                 failedFetchError: ""              });           }           const payload = {              type: "articleBuilderPages",              data: blocks           };           const jsonStr = JSON.stringify(payload);                      if (navigator.clipboard && navigator.clipboard.writeText) {              navigator.clipboard.writeText(jsonStr).then(() => {                 this.editorCopyBtn.innerHTML = 'Copied!';                 setTimeout(() => {                    this.editorCopyBtn.innerHTML = '\x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2"><' + '/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"><' + '/path><' + '/svg> Copy to CMS';                 }, 2000);              }).catch(err => {                 console.warn('Failed to copy text: ', err);                 alert('Failed to copy deals to clipboard. See console.');              });           } else {              // Fallback              const textArea = document.createElement("textarea");              textArea.value = jsonStr;              document.body.appendChild(textArea);              textArea.focus();              textArea.select();              try {                 document.execCommand('copy');                 this.editorCopyBtn.innerHTML = 'Copied!';                 setTimeout(() => {                    this.editorCopyBtn.innerHTML = '\x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2"><' + '/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"><' + '/path><' + '/svg> Copy to CMS';                 }, 2000);              } catch (err) {                 console.warn('Fallback: Oops, unable to copy', err);                 alert('Fallback: Failed to copy deals to clipboard.');              }              document.body.removeChild(textArea);           }        }      }      // Initialize the Widget      if (document.readyState === 'loading') {        document.addEventListener('DOMContentLoaded', () => new DealsFinderWidget({ rootId: 'signal-deals-finder-root', rootNode: shadowRoot, hostContainer: hostContainer }));      } else {        new DealsFinderWidget({ rootId: 'signal-deals-finder-root', rootNode: shadowRoot, hostContainer: hostContainer });      }    })();  </script></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Apple increased the price of iPhone 18 Pro battery repairs — here's how much you'll pay now ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Today is the day the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro and iPhone 18 Pro Max </a>are released. One of the things most buyers will have noticed is that both phones are <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-vs-iphone-17-pro-biggest-upgrades-explained#section-iphone-17-pro-vs-iphone-18-pro-price">$100 more expensive compared to last year</a>. However, the list price isn't the only thing that's increased, since Apple has raised the price of out-of-warranty battery repairs as well.</p><p>If you need an official battery service for <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-17-pro-review">iPhone 17 Pro </a>and<a href="https://www.tomsguide.com/phones/iphones/iphone-17-pro-max-review"> Pro Max</a>, Apple will charge you $119 (plus tax). However, with the iPhone 18 Pro and Pro Max, that price has risen by $10 to $129 — a difference of around 8%.</p><p>Thankfully, other out-of-warranty repair costs have stayed the same for the time being. But with an official Apple repair of miscellaneous damage costing more than two-thirds the price of a new iPhone ($849 on an iPhone 18 Pro), <a href="https://www.tomsguide.com/news/what-is-applecare">AppleCare+</a> starts to look appealing.</p><div ><table><caption>Apple out-of-warranty repair costs</caption><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro</strong></p></td><td  ><p><strong>iPhone 17 Pro</strong></p></td><td  ><p><strong>iPhone 18 Pro Max</strong></p></td><td  ><p><strong>iPhone 17 Pro Max</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Battery</strong></p></td><td  ><p>$129</p></td><td  ><p>$119</p></td><td  ><p>$129</p></td><td  ><p>$119</p></td></tr><tr><td class="firstcol " ><p><strong>Back Glass</strong></p></td><td  ><p>$159</p></td><td  ><p>$159</p></td><td  ><p>$159</p></td><td  ><p>$159</p></td></tr><tr><td class="firstcol " ><p><strong>Rear Camera</strong></p></td><td  ><p>$249</p></td><td  ><p>$249</p></td><td  ><p>$249</p></td><td  ><p>$249</p></td></tr><tr><td class="firstcol " ><p><strong>Screen</strong></p></td><td  ><p>$329</p></td><td  ><p>$329</p></td><td  ><p>$379</p></td><td  ><p>$379</p></td></tr><tr><td class="firstcol " ><p><strong>Screen & back glass</strong></p></td><td  ><p>$419</p></td><td  ><p>$419</p></td><td  ><p>$469</p></td><td  ><p>$469</p></td></tr><tr><td class="firstcol " ><p><strong>Other damage</strong></p></td><td  ><p>$849</p></td><td  ><p>$849</p></td><td  ><p>$899</p></td><td  ><p>$899</p></td></tr></tbody></table></div><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X81bve"></div>                            </div>                            <script src="https://kwizly.com/embed/X81bve.js" async></script><p>These fees only apply to out-of-warranty repairs, and any legitimate warranty claim will be free of charge. That said, there aren't many circumstances where actual damage to your iPhone would be considered a fault with the phone itself. Certainly not when you remember that Apple has previously brushed away user complaints like <a href="https://www.tomsguide.com/phones/iphones/apple-responds-to-iphone-17-scratchgate-worn-magsafe-risers-to-blame-for-material-transfer">scratchgate,</a> <a href="https://www.tomsguide.com/us/ipad-bendgate-apple-quality-control,news-28901.html">bendgate</a> and <a href="https://www.tomsguide.com/us/pictures-story/1418-biggest-apple-fails.html">antennaegate</a>.</p><p>Having AppleCare+ reduces those repair costs considerably. Battery servicing is free, while fixing damage to the display and back glass costs $29 each. Inner display damage comes with a $99 fee, as does any other accidental damage repair. AppleCare+ also features coverage for stolen and lost iPhones, with a $149 deductible.</p><p>AppleCare+ costs $10 a month for an iPhone, or $20 a month if you cover two other devices as<a href="https://www.tomsguide.com/phones/iphones/apple-announces-applecare-one-for-covering-multiple-devices-under-one-plan-starts-at-usd19-a-month"> part of the AppleCare One plan.</a> Apple also recently launched the<a href="https://www.tomsguide.com/phones/iphones/applecare-one-family-now-live-for-usd50-a-month-in-time-for-iphone-18-pro-launch-heres-what-it-actually-covers"> $50 a month AppleCare One plan</a>, which covers all Apple devices for up to six people, so long as they're relatively recent or already have AppleCare coverage.</p><p>Those of you who already ordered an iPhone 18 Pro or Pro Max without AppleCare+ can still add coverage for up to 60 days after purchase.</p><h2 id="what-39-s-the-deal-with-the-price-hike">What's the deal with the price hike?</h2><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="473VNvCMPfhDkYKpe3aJjK" name="iPhone 18 Pro and Pro Max-12" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/473VNvCMPfhDkYKpe3aJjK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The last time we saw the cost of battery servicing go up was with the release of iPhone 16 Pro, <a href="https://www.tomsguide.com/phones/iphones/iphone-16-pro-and-pro-max-battery-replacements-just-got-a-price-hike-heres-what-youll-pay">when the price rose from $99 to $119</a>. That was also the last time the iPhone 16 Pro got a price hike, as Apple ditched the 128GB storage option that year.</p><p>Whether that's a coincidence or not, the truth is that the iPhone 18 Pro and Pro Max batteries are a little different. <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-battery-capacity-confirmed-in-europe-heres-how-they-compare-to-iphone-17-pro">According to EU listings,</a> the iPhone 18 Pro Max battery is a whopping 11% larger than the iPhone 17 Pro Max, and that extra capacity doesn't come cheap. </p><p>The iPhone 18 Pro is less impressive, with a battery that's a mere 1.44% larger than its predecessor. However Apple has promised that the new batteries employ a different design, which would also explain the price increase. Better batteries are more expensive to make, which means they're going to be more expensive to replace.</p><p>Plus we have to remember that things are generally more expensive nowadays — especially when it comes to manufacturing electronics. Batteries don't have the same issues as RAM or storage, but that doesn't mean they're cheap. This means the cost of a replacement can be pretty high, even if other official repair work costs considerably more.</p><p>So if you're not going to buy AppleCare coverage, be sure to at least put a case and screen protector on your phone to <a href="https://www.tomsguide.com/phones/iphones/i-knew-better-than-to-carry-around-a-naked-phone-then-my-iphone-17-pro-max-met-the-asphalt">minimize any damage that might happen</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/phones/iphones/11-best-ios-27-hidden-features-you-cant-afford-to-miss">11 best iOS 27 hidden features you can't afford to miss</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">I tested iPhone 18 Pro Max variable aperture camera and I can (almost) ditch my mirrorless</a></li><li><a href="https://www.tomsguide.com/phones/iphones/the-iphone-duo-has-a-lot-of-hype-but-this-poll-has-a-surprising-reveal-for-samsungs-foldable">The iPhone Duo has a lot of hype, but this poll has a surprising reveal for Samsung's foldable</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/apple-increased-the-price-of-iphone-18-pro-battery-repairs-heres-how-much-youll-pay-now</link>
                                                                            <description>
                            <![CDATA[ iPhone 18 Pro's price hike isn't the only extra expense this year, thanks to Apple raising the price of battery repairs. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">GGaXUGzzHuSpF2abbkVNoH</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/Qr2cmEDabLpBg6St8Ca5xJ-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 18 Sep 2026 11:20:43 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ tom.pritchard@futurenet.com (Tom Pritchard) ]]></author>                    <dc:creator><![CDATA[ Tom Pritchard ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/biCewUkKfSA6QnT2HxVc3f-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/Qr2cmEDabLpBg6St8Ca5xJ-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Apple iPhone 18 Pro and Pro Max shown in hand]]></media:description>                                                            <media:text><![CDATA[Apple iPhone 18 Pro and Pro Max shown in hand]]></media:text>
                                <media:title type="plain"><![CDATA[Apple iPhone 18 Pro and Pro Max shown in hand]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/Qr2cmEDabLpBg6St8Ca5xJ-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Today is the day the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro and iPhone 18 Pro Max </a>are released. One of the things most buyers will have noticed is that both phones are <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-vs-iphone-17-pro-biggest-upgrades-explained#section-iphone-17-pro-vs-iphone-18-pro-price">$100 more expensive compared to last year</a>. However, the list price isn't the only thing that's increased, since Apple has raised the price of out-of-warranty battery repairs as well.</p><p>If you need an official battery service for <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-17-pro-review">iPhone 17 Pro </a>and<a href="https://www.tomsguide.com/phones/iphones/iphone-17-pro-max-review"> Pro Max</a>, Apple will charge you $119 (plus tax). However, with the iPhone 18 Pro and Pro Max, that price has risen by $10 to $129 — a difference of around 8%.</p><p>Thankfully, other out-of-warranty repair costs have stayed the same for the time being. But with an official Apple repair of miscellaneous damage costing more than two-thirds the price of a new iPhone ($849 on an iPhone 18 Pro), <a href="https://www.tomsguide.com/news/what-is-applecare">AppleCare+</a> starts to look appealing.</p><div ><table><caption>Apple out-of-warranty repair costs</caption><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>iPhone 18 Pro</strong></p></td><td  ><p><strong>iPhone 17 Pro</strong></p></td><td  ><p><strong>iPhone 18 Pro Max</strong></p></td><td  ><p><strong>iPhone 17 Pro Max</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Battery</strong></p></td><td  ><p>$129</p></td><td  ><p>$119</p></td><td  ><p>$129</p></td><td  ><p>$119</p></td></tr><tr><td class="firstcol " ><p><strong>Back Glass</strong></p></td><td  ><p>$159</p></td><td  ><p>$159</p></td><td  ><p>$159</p></td><td  ><p>$159</p></td></tr><tr><td class="firstcol " ><p><strong>Rear Camera</strong></p></td><td  ><p>$249</p></td><td  ><p>$249</p></td><td  ><p>$249</p></td><td  ><p>$249</p></td></tr><tr><td class="firstcol " ><p><strong>Screen</strong></p></td><td  ><p>$329</p></td><td  ><p>$329</p></td><td  ><p>$379</p></td><td  ><p>$379</p></td></tr><tr><td class="firstcol " ><p><strong>Screen & back glass</strong></p></td><td  ><p>$419</p></td><td  ><p>$419</p></td><td  ><p>$469</p></td><td  ><p>$469</p></td></tr><tr><td class="firstcol " ><p><strong>Other damage</strong></p></td><td  ><p>$849</p></td><td  ><p>$849</p></td><td  ><p>$899</p></td><td  ><p>$899</p></td></tr></tbody></table></div><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X81bve"></div>                            </div>                            <script src="https://kwizly.com/embed/X81bve.js" async></script><p>These fees only apply to out-of-warranty repairs, and any legitimate warranty claim will be free of charge. That said, there aren't many circumstances where actual damage to your iPhone would be considered a fault with the phone itself. Certainly not when you remember that Apple has previously brushed away user complaints like <a href="https://www.tomsguide.com/phones/iphones/apple-responds-to-iphone-17-scratchgate-worn-magsafe-risers-to-blame-for-material-transfer">scratchgate,</a> <a href="https://www.tomsguide.com/us/ipad-bendgate-apple-quality-control,news-28901.html">bendgate</a> and <a href="https://www.tomsguide.com/us/pictures-story/1418-biggest-apple-fails.html">antennaegate</a>.</p><p>Having AppleCare+ reduces those repair costs considerably. Battery servicing is free, while fixing damage to the display and back glass costs $29 each. Inner display damage comes with a $99 fee, as does any other accidental damage repair. AppleCare+ also features coverage for stolen and lost iPhones, with a $149 deductible.</p><p>AppleCare+ costs $10 a month for an iPhone, or $20 a month if you cover two other devices as<a href="https://www.tomsguide.com/phones/iphones/apple-announces-applecare-one-for-covering-multiple-devices-under-one-plan-starts-at-usd19-a-month"> part of the AppleCare One plan.</a> Apple also recently launched the<a href="https://www.tomsguide.com/phones/iphones/applecare-one-family-now-live-for-usd50-a-month-in-time-for-iphone-18-pro-launch-heres-what-it-actually-covers"> $50 a month AppleCare One plan</a>, which covers all Apple devices for up to six people, so long as they're relatively recent or already have AppleCare coverage.</p><p>Those of you who already ordered an iPhone 18 Pro or Pro Max without AppleCare+ can still add coverage for up to 60 days after purchase.</p><h2 id="what-39-s-the-deal-with-the-price-hike">What's the deal with the price hike?</h2><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="473VNvCMPfhDkYKpe3aJjK" name="iPhone 18 Pro and Pro Max-12" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/473VNvCMPfhDkYKpe3aJjK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The last time we saw the cost of battery servicing go up was with the release of iPhone 16 Pro, <a href="https://www.tomsguide.com/phones/iphones/iphone-16-pro-and-pro-max-battery-replacements-just-got-a-price-hike-heres-what-youll-pay">when the price rose from $99 to $119</a>. That was also the last time the iPhone 16 Pro got a price hike, as Apple ditched the 128GB storage option that year.</p><p>Whether that's a coincidence or not, the truth is that the iPhone 18 Pro and Pro Max batteries are a little different. <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-battery-capacity-confirmed-in-europe-heres-how-they-compare-to-iphone-17-pro">According to EU listings,</a> the iPhone 18 Pro Max battery is a whopping 11% larger than the iPhone 17 Pro Max, and that extra capacity doesn't come cheap. </p><p>The iPhone 18 Pro is less impressive, with a battery that's a mere 1.44% larger than its predecessor. However Apple has promised that the new batteries employ a different design, which would also explain the price increase. Better batteries are more expensive to make, which means they're going to be more expensive to replace.</p><p>Plus we have to remember that things are generally more expensive nowadays — especially when it comes to manufacturing electronics. Batteries don't have the same issues as RAM or storage, but that doesn't mean they're cheap. This means the cost of a replacement can be pretty high, even if other official repair work costs considerably more.</p><p>So if you're not going to buy AppleCare coverage, be sure to at least put a case and screen protector on your phone to <a href="https://www.tomsguide.com/phones/iphones/i-knew-better-than-to-carry-around-a-naked-phone-then-my-iphone-17-pro-max-met-the-asphalt">minimize any damage that might happen</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/phones/iphones/11-best-ios-27-hidden-features-you-cant-afford-to-miss">11 best iOS 27 hidden features you can't afford to miss</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">I tested iPhone 18 Pro Max variable aperture camera and I can (almost) ditch my mirrorless</a></li><li><a href="https://www.tomsguide.com/phones/iphones/the-iphone-duo-has-a-lot-of-hype-but-this-poll-has-a-surprising-reveal-for-samsungs-foldable">The iPhone Duo has a lot of hype, but this poll has a surprising reveal for Samsung's foldable</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Siri in iOS 27 actually lives up to the hype — here are 3 truly unique uses ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I’ll be the first to admit I stopped relying on Siri years ago for anything more than quick kitchen timers or checking the weather. Like many iPhone users, I had grown accustomed to its limitations. </p><p>But after spending time testing the new Siri experience in iOS 27, I'm actually shocked by how much it's improved. Instead of just answering basic questions, Siri <em>finally</em> feels full integrated into your phone. </p><p>If you've been ignoring the feature like I was, here are the three unique tools that actually changed my daily routine.</p><section class="howto-block">                    <h3>1. Generating Shortcuts just by describing them</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/m2aRzEcBtNcDYXrixKrMZG.jpg"                                        alt="Shortcut prompt in iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/m2aRzEcBtNcDYXrixKrMZG.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>Setting up custom shortcuts used to feel overwhelming unless you really knew what you were doing. In iOS 27, Siri handles all the heavy lifting. </p><p>All you have to do is <strong>open the Shortcuts app, tap the + icon</strong> at the top right, <strong>and hit the new Prompt bar</strong>. Then just <strong>describe your routine</strong>. Once you tap the arrow, Siri hands you a ready to use routine in seconds. Just glance over the steps and <strong>tap</strong> <strong>Done</strong> to save it.</p><p>What makes this so cool is that it opens up real automation to everyone. You no longer need to be super tech-savvy or spend ages troubleshooting, you just tell your phone what you need, and it builds the routine for you. </p></p>                </section><section class="howto-block">                    <h3>2. Grabbing dates and details right off your screen</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/h9JniavCow2waqDirGgn9e.jpg"                                        alt="Creating a calendar invite using Siri iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/h9JniavCow2waqDirGgn9e.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>The most practical tweak in iOS 27 is that Siri can now look at what’s right in front of you on the display. </p><p>Normally, when someone texts you event details, you have to copy the info, switch apps, open your calendar, and type everything in yourself. Now, Siri cuts out that annoying back-and-forth entirely.</p><p>If you're looking at an email with flight times, a group chat about dinner, or a website with concert dates, you<strong> just activate Siri and say "Add this to my calendar"</strong>. </p><p>Siri scans the screen, pulls out the event title, time, and address, and pops up a ready-to-go calendar invite right over your active app. You just tap once to confirm, and you're right back to what you were doing.</p></p>                </section><section class="howto-block">                    <h3>3. Keeping ongoing chats open in the new Siri app</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/6hpZGeCFMvHA4MjJbknwsE.jpg"                                        alt="Asking a follow up question in the Siri app iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/6hpZGeCFMvHA4MjJbknwsE.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>In older versions of iOS, asking Siri a second question would instantly wipe away your previous search, forcing you to start all over if you got interrupted. </p><p>Apple finally fixed that by giving Siri its own standalone workspace app in iOS 27, letting you keep research threads saved throughout the day.</p><p>You can<strong> open the Siri app directly from your Home Screen</strong> and drop in a broad query, like "Help me plan a weekend trip to Bristol". </p><p>As recommendations pop up, you can ask follow-up questions in that same chat thread — like filtering for cheap places to eat or grouping things by neighborhood, without losing your original notes. </p></p>                </section><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X81pNe"></div>                            </div>                            <script src="https://kwizly.com/embed/X81pNe.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/ios-27-7-features-you-need-to-try-first-after-updating">iOS 27: 7 features you need to try first after updating</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-tried-the-new-ios-27-safari-features-heres-3-settings-worth-using">I tried the new iOS 27 Safari features — here's 3 settings worth using</a></li><li><a href="https://www.tomsguide.com/phones/iphones/apple-added-a-suite-of-photo-editing-tools-in-ios-27-and-theyre-absolute-game-changers">iOS 27 Photos features that transform your pictures — here's how to use them</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/siri-in-ios-27-actually-lives-up-to-the-hype-here-are-the-3-truly-unique-uses</link>
                                                                            <description>
                            <![CDATA[ Apple overhauled Siri in iOS 27. Here are 3 game-changing features you’ll actually want to use. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Rrkq2PjGY3EF97dAVxz2QJ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/iopeLDvPGawviRJFdMxca5-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 18 Sep 2026 09:30:00 +0000</pubDate>                                                                                                                                <updated>Fri, 18 Sep 2026 13:03:44 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ kaycee.hill@futurenet.com (Kaycee Hill) ]]></author>                    <dc:creator><![CDATA[ Kaycee Hill ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/xHn6RmpEqg87cvtLwrBu9G-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/iopeLDvPGawviRJFdMxca5-1920-80.jpg">
                                                            <media:credit><![CDATA[John Velasco / Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iOS 27 Siri AI running on iPhone 17 Pro.]]></media:description>                                                            <media:text><![CDATA[iOS 27 Siri AI running on iPhone 17 Pro.]]></media:text>
                                <media:title type="plain"><![CDATA[iOS 27 Siri AI running on iPhone 17 Pro.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/iopeLDvPGawviRJFdMxca5-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I’ll be the first to admit I stopped relying on Siri years ago for anything more than quick kitchen timers or checking the weather. Like many iPhone users, I had grown accustomed to its limitations. </p><p>But after spending time testing the new Siri experience in iOS 27, I'm actually shocked by how much it's improved. Instead of just answering basic questions, Siri <em>finally</em> feels full integrated into your phone. </p><p>If you've been ignoring the feature like I was, here are the three unique tools that actually changed my daily routine.</p><section class="howto-block">                    <h3>1. Generating Shortcuts just by describing them</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/m2aRzEcBtNcDYXrixKrMZG.jpg"                                        alt="Shortcut prompt in iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/m2aRzEcBtNcDYXrixKrMZG.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>Setting up custom shortcuts used to feel overwhelming unless you really knew what you were doing. In iOS 27, Siri handles all the heavy lifting. </p><p>All you have to do is <strong>open the Shortcuts app, tap the + icon</strong> at the top right, <strong>and hit the new Prompt bar</strong>. Then just <strong>describe your routine</strong>. Once you tap the arrow, Siri hands you a ready to use routine in seconds. Just glance over the steps and <strong>tap</strong> <strong>Done</strong> to save it.</p><p>What makes this so cool is that it opens up real automation to everyone. You no longer need to be super tech-savvy or spend ages troubleshooting, you just tell your phone what you need, and it builds the routine for you. </p></p>                </section><section class="howto-block">                    <h3>2. Grabbing dates and details right off your screen</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/h9JniavCow2waqDirGgn9e.jpg"                                        alt="Creating a calendar invite using Siri iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/h9JniavCow2waqDirGgn9e.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>The most practical tweak in iOS 27 is that Siri can now look at what’s right in front of you on the display. </p><p>Normally, when someone texts you event details, you have to copy the info, switch apps, open your calendar, and type everything in yourself. Now, Siri cuts out that annoying back-and-forth entirely.</p><p>If you're looking at an email with flight times, a group chat about dinner, or a website with concert dates, you<strong> just activate Siri and say "Add this to my calendar"</strong>. </p><p>Siri scans the screen, pulls out the event title, time, and address, and pops up a ready-to-go calendar invite right over your active app. You just tap once to confirm, and you're right back to what you were doing.</p></p>                </section><section class="howto-block">                    <h3>3. Keeping ongoing chats open in the new Siri app</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/6hpZGeCFMvHA4MjJbknwsE.jpg"                                        alt="Asking a follow up question in the Siri app iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/6hpZGeCFMvHA4MjJbknwsE.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>In older versions of iOS, asking Siri a second question would instantly wipe away your previous search, forcing you to start all over if you got interrupted. </p><p>Apple finally fixed that by giving Siri its own standalone workspace app in iOS 27, letting you keep research threads saved throughout the day.</p><p>You can<strong> open the Siri app directly from your Home Screen</strong> and drop in a broad query, like "Help me plan a weekend trip to Bristol". </p><p>As recommendations pop up, you can ask follow-up questions in that same chat thread — like filtering for cheap places to eat or grouping things by neighborhood, without losing your original notes. </p></p>                </section><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X81pNe"></div>                            </div>                            <script src="https://kwizly.com/embed/X81pNe.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/ios-27-7-features-you-need-to-try-first-after-updating">iOS 27: 7 features you need to try first after updating</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-tried-the-new-ios-27-safari-features-heres-3-settings-worth-using">I tried the new iOS 27 Safari features — here's 3 settings worth using</a></li><li><a href="https://www.tomsguide.com/phones/iphones/apple-added-a-suite-of-photo-editing-tools-in-ios-27-and-theyre-absolute-game-changers">iOS 27 Photos features that transform your pictures — here's how to use them</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tested the iPhone 18 Pro Max's variable aperture camera — here's the results ]]></title>
                                                                                                <dc:content><![CDATA[ <p>With every iPhone release, Apple hypes up camera performance through a blend of new hardware and computational photography improvements. Even now, I still dream about a phone that could replace my dedicated mirrorless body — and the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro and 18 Pro Max</a> certainly put that dream to the test.</p><p>For years, carrying a heavy mirrorless kit was the only way to obtain genuine optical depth of field and true creative control. Apple’s iPhone 18 Pro Max comes dangerously close to changing that reality by introducing a <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-variable-aperture-camera-explained-heres-what-it-actually-does">physical variable-aperture system</a> to its 48MP main camera. Because of this, the phone is no longer entirely reliant on software-simulated background blur because the optics finally deliver natural focus falloff.</p><p>Paired with a revamped interface packed with Apple’s new Pro Controls, it’s a massive leap forward that puts more creative power directly into shooters' hands. Here’s what I found.</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/QJVNbFMd-zQ" allowfullscreen></iframe></div></div><h2 id="why-aperture-matters">Why aperture matters</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="5kKUCv7Eef6yGkMMGEgbvJ" name="iPhone 18 Pro and Pro Max-9" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/5kKUCv7Eef6yGkMMGEgbvJ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Most people don’t have the urge to dig into camera specs, but breaking down the differences between the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-vs-iphone-17-pro-biggest-upgrades-explained">iPhone 18 Pro and iPhone 17 Pro</a> is important this time around. On top of introducing a mechanical variable aperture, Apple made another critical upgrade: swapping in a faster f/1.48 lens. That alone is a meaningful leap over the fixed f/1.78 aperture found on the 48MP main cameras of the previous generation.</p><p>With access to a wider f/1.48 lens, the iPhone 18 Pro draws significantly more light into the sensor than the 17 Pro’s fixed glass. This improvement delivers cleaner low-light exposures, faster shutter speeds, and authentic optical depth of field — without leaning on artificial Portrait mode blurring algorithms.</p><p>In low-light situations, a faster aperture shortens exposure times in Night mode. Because you need to stay as still as possible, any handshake can easily blur a shot. By having a faster lens,  it helps prevent motion blur better while also keeping digital noise from creeping into the shadows.</p><h2 id="authentic-background-blur">Authentic background blur</h2><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/FtwWZwwe3Mr4rrUu6ghsMM-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption>f/1.48<small role="credit">Tom's Guide / John Velasco</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/xQRnQUKKpkFQB9Cp3WZinM-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption>f/4<small role="credit">Tom's Guide / John Velasco</small></figcaption></figure></figure><p>The iPhone 18 Pro and 18 Pro Max offer four different aperture values to choose from: f/1.48, f/1.8, f/2.8, and f/4. Depending on the look you’re going for, each delivers a distinct result. I’d typically use f/1.48 for portraits and close-ups when I want to isolate my subject, giving backgrounds that creamy, blurred-out look. Meanwhile, I’d switch to f/4 when I want to keep the entire frame sharp.</p><p>You can see from the shots of my colleague above how these two extremes perform when shot from a slight distance. If you zoom in on the wall art in the far background, you’ll notice that at f/1.48, the words are soft and blurred — whereas at f/4, they’re crisp and legible.</p><p>What makes the f/1.48 shot stand out over Portrait Mode is that it doesn’t rely on software to guess edge boundaries, which often leads to messy cutouts. Instead, this wider physical aperture delivers the natural optical falloff I’d expect from a dedicated mirrorless camera.</p><h2 id="distance-plays-a-roll-with-the-bokeh-intensity">Distance plays a roll with the bokeh intensity</h2><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/NCtnpbCXEDqARRCcYanbSM-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption>f/1.48<small role="credit">Tom's Guide / John Velasco</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/eT6cd3zYHk8RTNQcLeiXyM-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption>f/4<small role="credit">Tom's Guide / John Velasco</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/rzxZ5jnoE2K5rfW7Pj6ZcM-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption>f/1.48<small role="credit">Tom's Guide / John Velasco</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/3GH6kW43L6a5ZtWcCW82zM-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption>f/4<small role="credit">Tom's Guide / John Velasco</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/mCZJusKEjtsXKZqzTotR2N-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption>f/1.48<small role="credit">Tom's Guide / John Velasco</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/b5iDHwgKyLto9iJHgFbb6N-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption>f/4<small role="credit">Tom's Guide / John Velasco</small></figcaption></figure></figure><p>If you really want the background to be blurred out, distance plays a crucial role. Take the other shots of my colleague above, which illustrate the effect at varying distances. The first set shows the disparity between shooting at f/1.48 and f/4 at roughly three feet away, with the former blurring the background dramatically — while at f/4, more of the frame remains in focus.</p><p>Stepping back to five feet, the effect is still quite noticeable because the food menus directly behind Mark remain soft and blurred at f/1.48. It’s a genuine optical blur — and I  can tell because the planter off to the left, which sits much closer to Mark than the menus do, stays noticeably sharper.</p><p>Finally, at seven feet away, there's virtually no noticeable difference between the two aperture settings, proving that depth of field and bokeh intensity are heavily dictated by your distance to the subject.</p><h2 id="you-also-get-control-when-recording-video">You also get control when recording video</h2><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/MCLdhssnwR846ECoqMBnAM-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption><small role="credit">Tom's Guide / John Velasco</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/uqjfbpy99YingAUAQq9S7M-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption><small role="credit">Tom's Guide / John Velasco</small></figcaption></figure></figure><p>The variable aperture isn't just for stills — you get direct control over those blades when shooting video, too. This has been a long time coming; the historical lack of granular manual controls prevented me from using an iPhone as my dedicated B-camera, often pushing me toward Samsung’s flagships instead.</p><p>As you can see from the screenshots above, adjusting the lens aperture slider lets me toggle between settings on the fly, right alongside the other Pro Controls. At f/1.8, the lens opens wide to isolate the DualSense controller, softening the background cabinets and shelving with smooth, genuine optical blur.</p><p>Switching to f/4.0 stops the mechanical iris down, visibly deepening the field of focus. The wood grain along the table stays sharp much further back, and background details gain noticeably clearer definition. Having the ability to manually control the aperture gives me exact control over the cinematic aesthetic I want for any given scene.</p><h2 id="bottom-line-11">Bottom line</h2><p>Apple has come a long way to finally give enthusiasts like me the meaningful tools we’ve been demanding for years. The addition of a true variable aperture gives me the optical control to dial in a very specific look — delivering authentic background separation and natural focus falloff that almost makes me want to leave my mirrorless camera behind.</p><p>The only real catch is that this system is strictly limited to the 48MP main camera, leaving the telephoto lens stuck with a fixed aperture. Telephoto focal lengths naturally compress a scene and crave genuine depth-of-field control even more for tight framing. If Apple could bring this variable aperture system to the zoom lens next, it would add unprecedented depth and versatility that I wouldn’t have thought possible just a few years ago.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Ozn90O"></div>                            </div>                            <script src="https://kwizly.com/embed/Ozn90O.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/phones/iphones/apple-hid-a-retro-mac-easter-egg-inside-ios-27-heres-how-to-find-it">iOS 27 has a hidden Mac Easter egg — here's how to trigger it</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen">iPhone 18 Pro benchmarks: Apple just built the most powerful phones we've ever seen</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-18-pro-battery-life-tested-the-results-are-surprising">iPhone 18 Pro Max and 18 Pro battery life tested — the results are surprising</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless</link>
                                                                            <description>
                            <![CDATA[ I tried out the new variable aperture camera on the iPhone 18 Pro Max and iPhone 18 Pro, which lets me dial in the settings I want for a specific look. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">bGmmzheecF52MNjVh3DEf8</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/Ps5cuSJ8Gtww8vSAKrrAFU-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 18 Sep 2026 05:30:00 +0000</pubDate>                                                                                                                                <updated>Fri, 18 Sep 2026 21:20:27 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ john.velasco@futurenet.com (John Velasco) ]]></author>                    <dc:creator><![CDATA[ John Velasco ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/TSj224oX8d5ERXaDs8pDGd-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/Ps5cuSJ8Gtww8vSAKrrAFU-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 18 Pro variable aperture camera]]></media:description>                                                            <media:text><![CDATA[iPhone 18 Pro variable aperture camera]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 18 Pro variable aperture camera]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/Ps5cuSJ8Gtww8vSAKrrAFU-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>With every iPhone release, Apple hypes up camera performance through a blend of new hardware and computational photography improvements. Even now, I still dream about a phone that could replace my dedicated mirrorless body — and the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro and 18 Pro Max</a> certainly put that dream to the test.</p><p>For years, carrying a heavy mirrorless kit was the only way to obtain genuine optical depth of field and true creative control. Apple’s iPhone 18 Pro Max comes dangerously close to changing that reality by introducing a <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-variable-aperture-camera-explained-heres-what-it-actually-does">physical variable-aperture system</a> to its 48MP main camera. Because of this, the phone is no longer entirely reliant on software-simulated background blur because the optics finally deliver natural focus falloff.</p><p>Paired with a revamped interface packed with Apple’s new Pro Controls, it’s a massive leap forward that puts more creative power directly into shooters' hands. Here’s what I found.</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/QJVNbFMd-zQ" allowfullscreen></iframe></div></div><h2 id="why-aperture-matters">Why aperture matters</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="5kKUCv7Eef6yGkMMGEgbvJ" name="iPhone 18 Pro and Pro Max-9" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/5kKUCv7Eef6yGkMMGEgbvJ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Most people don’t have the urge to dig into camera specs, but breaking down the differences between the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-vs-iphone-17-pro-biggest-upgrades-explained">iPhone 18 Pro and iPhone 17 Pro</a> is important this time around. On top of introducing a mechanical variable aperture, Apple made another critical upgrade: swapping in a faster f/1.48 lens. That alone is a meaningful leap over the fixed f/1.78 aperture found on the 48MP main cameras of the previous generation.</p><p>With access to a wider f/1.48 lens, the iPhone 18 Pro draws significantly more light into the sensor than the 17 Pro’s fixed glass. This improvement delivers cleaner low-light exposures, faster shutter speeds, and authentic optical depth of field — without leaning on artificial Portrait mode blurring algorithms.</p><p>In low-light situations, a faster aperture shortens exposure times in Night mode. Because you need to stay as still as possible, any handshake can easily blur a shot. By having a faster lens,  it helps prevent motion blur better while also keeping digital noise from creeping into the shadows.</p><h2 id="authentic-background-blur">Authentic background blur</h2><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/FtwWZwwe3Mr4rrUu6ghsMM-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption>f/1.48<small role="credit">Tom's Guide / John Velasco</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/xQRnQUKKpkFQB9Cp3WZinM-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption>f/4<small role="credit">Tom's Guide / John Velasco</small></figcaption></figure></figure><p>The iPhone 18 Pro and 18 Pro Max offer four different aperture values to choose from: f/1.48, f/1.8, f/2.8, and f/4. Depending on the look you’re going for, each delivers a distinct result. I’d typically use f/1.48 for portraits and close-ups when I want to isolate my subject, giving backgrounds that creamy, blurred-out look. Meanwhile, I’d switch to f/4 when I want to keep the entire frame sharp.</p><p>You can see from the shots of my colleague above how these two extremes perform when shot from a slight distance. If you zoom in on the wall art in the far background, you’ll notice that at f/1.48, the words are soft and blurred — whereas at f/4, they’re crisp and legible.</p><p>What makes the f/1.48 shot stand out over Portrait Mode is that it doesn’t rely on software to guess edge boundaries, which often leads to messy cutouts. Instead, this wider physical aperture delivers the natural optical falloff I’d expect from a dedicated mirrorless camera.</p><h2 id="distance-plays-a-roll-with-the-bokeh-intensity">Distance plays a roll with the bokeh intensity</h2><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/NCtnpbCXEDqARRCcYanbSM-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption>f/1.48<small role="credit">Tom's Guide / John Velasco</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/eT6cd3zYHk8RTNQcLeiXyM-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption>f/4<small role="credit">Tom's Guide / John Velasco</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/rzxZ5jnoE2K5rfW7Pj6ZcM-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption>f/1.48<small role="credit">Tom's Guide / John Velasco</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/3GH6kW43L6a5ZtWcCW82zM-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption>f/4<small role="credit">Tom's Guide / John Velasco</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/mCZJusKEjtsXKZqzTotR2N-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption>f/1.48<small role="credit">Tom's Guide / John Velasco</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/b5iDHwgKyLto9iJHgFbb6N-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption>f/4<small role="credit">Tom's Guide / John Velasco</small></figcaption></figure></figure><p>If you really want the background to be blurred out, distance plays a crucial role. Take the other shots of my colleague above, which illustrate the effect at varying distances. The first set shows the disparity between shooting at f/1.48 and f/4 at roughly three feet away, with the former blurring the background dramatically — while at f/4, more of the frame remains in focus.</p><p>Stepping back to five feet, the effect is still quite noticeable because the food menus directly behind Mark remain soft and blurred at f/1.48. It’s a genuine optical blur — and I  can tell because the planter off to the left, which sits much closer to Mark than the menus do, stays noticeably sharper.</p><p>Finally, at seven feet away, there's virtually no noticeable difference between the two aperture settings, proving that depth of field and bokeh intensity are heavily dictated by your distance to the subject.</p><h2 id="you-also-get-control-when-recording-video">You also get control when recording video</h2><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/MCLdhssnwR846ECoqMBnAM-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption><small role="credit">Tom's Guide / John Velasco</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/uqjfbpy99YingAUAQq9S7M-1920-80.jpg" alt="iPhone 18 Pro Max & iPhone 18 Pro variable aperture camera." /><figcaption><small role="credit">Tom's Guide / John Velasco</small></figcaption></figure></figure><p>The variable aperture isn't just for stills — you get direct control over those blades when shooting video, too. This has been a long time coming; the historical lack of granular manual controls prevented me from using an iPhone as my dedicated B-camera, often pushing me toward Samsung’s flagships instead.</p><p>As you can see from the screenshots above, adjusting the lens aperture slider lets me toggle between settings on the fly, right alongside the other Pro Controls. At f/1.8, the lens opens wide to isolate the DualSense controller, softening the background cabinets and shelving with smooth, genuine optical blur.</p><p>Switching to f/4.0 stops the mechanical iris down, visibly deepening the field of focus. The wood grain along the table stays sharp much further back, and background details gain noticeably clearer definition. Having the ability to manually control the aperture gives me exact control over the cinematic aesthetic I want for any given scene.</p><h2 id="bottom-line-11">Bottom line</h2><p>Apple has come a long way to finally give enthusiasts like me the meaningful tools we’ve been demanding for years. The addition of a true variable aperture gives me the optical control to dial in a very specific look — delivering authentic background separation and natural focus falloff that almost makes me want to leave my mirrorless camera behind.</p><p>The only real catch is that this system is strictly limited to the 48MP main camera, leaving the telephoto lens stuck with a fixed aperture. Telephoto focal lengths naturally compress a scene and crave genuine depth-of-field control even more for tight framing. If Apple could bring this variable aperture system to the zoom lens next, it would add unprecedented depth and versatility that I wouldn’t have thought possible just a few years ago.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Ozn90O"></div>                            </div>                            <script src="https://kwizly.com/embed/Ozn90O.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/phones/iphones/apple-hid-a-retro-mac-easter-egg-inside-ios-27-heres-how-to-find-it">iOS 27 has a hidden Mac Easter egg — here's how to trigger it</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen">iPhone 18 Pro benchmarks: Apple just built the most powerful phones we've ever seen</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-18-pro-battery-life-tested-the-results-are-surprising">iPhone 18 Pro Max and 18 Pro battery life tested — the results are surprising</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ The iPhone Duo has a lot of hype, but this poll has a surprising reveal for Samsung's foldable ]]></title>
                                                                                                <dc:content><![CDATA[ <p>We asked Tom's Guide readers if they would rather pick up Apple's new <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> or the <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-review-wide-for-the-win">Samsung Galaxy Z Fold 8</a>, and the winner was quite surprising. </p><p>With 2,761 votes, one device proved far more popular than the other by more than double the votes, but was it the Apple iPhone Duo or Samsung Galaxy Z Fold 8? Check out the results below.</p><h2 id="which-flagship-foldable-would-you-rather-purchase">Which flagship foldable would you rather purchase?</h2><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-exgNKX"></div>                            </div>                            <script src="https://kwizly.com/embed/exgNKX.js" async></script><ul><li><strong>1st place: </strong>62%, Samsung Galaxy Z Fold 8</li><li><strong>2nd place: </strong>23%, iPhone Duo</li><li><strong>3rd place: </strong>15%, Neither</li></ul><p>With a total of 1,705 votes, 62% of respondents said the Samsung foldable is their preferred foldable phone. Apple's Duo came in a distant second with 632 votes, or 23%. </p><p>Meanwhile, 424 people said they weren't interested in either phone. If you find yourself in that camp, what would you buy instead? Or is this category too pricey for you?</p><h2 id="the-galaxy-z-fold-8-is-the-winner-but-why">The Galaxy Z Fold 8 is the winner, but why?</h2><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="8SvD4aoQkrBzEjS7QrbW5S" name="Samsung Galaxy Z Fold 8" alt="Samsung Galaxy Z Fold 8" src="https://cdn.mos.cms.futurecdn.net/8SvD4aoQkrBzEjS7QrbW5S-1920-80.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>So why did the Galaxy Z Fold 8 dominate our poll over the iPhone Duo. </p><p>I think it comes down to a few of factors in the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-vs-samsung-galaxy-z-fold-8-which-foldable-is-best-for-you#section-iphone-duo-vs-samsung-galaxy-z-fold-8-price-availability">battle between the Z Fold 8 and iPhone Duo</a>: design, price and expertise.</p><p>The Duo starts at $1,999 for the 256GB version and goes up to over $3k for the 2TB option. Samsung's foldable starts at $1,899, not a big difference but with how expensive the world has gotten in the last two years every dollar matters. No, Samsung doesn't offer a 2TB variant but the top-end 1TB model will cost you $2,499, again $100 than the equivalent Duo version.</p><p>Additionally, the Z Fold 8 offers a thinner and lighter design than the iPhone Duo. And Samsung lets you run more than two apps at once, which is better for multitasking. Plus, Samsung has been iterating foldables for eight generations, while this is Apple's first attempt.</p><p>There is concern over visibility and brightness with the matte finish on the Duo display, which is meant to hide the crease. Pictures of CEO John Ternus at the Emmys recently <a href="https://www.reddit.com/r/iPhoneFold/comments/1whl32i/john_ternus_shows_iphone_duo_at_the_emmys/" target="_blank">stirred up controversy online</a>, but we thought it was plenty bright in our hands-on time.</p><p>As we've found, though, the iPhone Duo <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-vs-samsung-galaxy-z-fold-8-7-ways-apples-foldable-beats-its-rival-from-ip68-to-faster-charging-and-more">has multiple features</a> that the Z Fold 8 doesn't, including iP68 durability, stylus support, faster charging, and a vapor chamber for better cooling.</p><h2 id="what-you-have-said">What you have said</h2><p>One reader said <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-vs-samsung-galaxy-z-fold-8-7-ways-apples-foldable-beats-its-rival-from-ip68-to-faster-charging-and-more#viafoura-comments">in a comment </a>that they were staying away from all things Apple as they didn't want to get sucked into another ecosystem. "I have Samsungs 8 ultra, and I am impressed with it," they said.</p><p>As a counterpoint, <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-vs-samsung-galaxy-z-fold-8-which-foldable-is-best-for-you#viafoura-comments">another reader wrote</a> that the "crucial factor" when comparing Samsung and Apple is Apple's "after-purchase service experience." </p><p>"Functionally, I have liked both platforms, but there is a fundamental difference in corporate philosophy. Apple actively invests in both technology and the customer service infrastructure required to support it. Samsung, on the other hand, focuses almost entirely on tech specs while leaving its customer support framework completely neglected," they said.</p><h2 id="bottom-line-12">Bottom line</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="NE3m4C3QUpw7U8uQfUAmea" name="iPhone-Duo-vs-Galaxy-Z-Fold-8-LEDE3" alt="IPhone duo vs galaxy Z Fold 8" src="https://cdn.mos.cms.futurecdn.net/NE3m4C3QUpw7U8uQfUAmea-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The iPhone Duo may be the belle of the ball after its recent announcement, but you won't be able to actually <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-is-official-price-release-date-specs-and-everything-you-need-to-know">hold it in your hands </a>until October 23. </p><p>Meanwhile, the Z Fold 8 is available right now and is a pretty impressive foldable, even if Apple's device beats it in some areas.</p><p>Let us know: why would you pick the Duo or the Z Fold 8? Don't like either? What's your replacement?</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-ultra-4-review"><strong>Apple Watch Ultra 4 review: I ran 22 miles to test Apple’s ultimate adventure watch</strong></a></li><li><a href="https://www.tomsguide.com/phones/iphones/11-best-ios-27-hidden-features-you-cant-afford-to-miss"><strong>11 best iOS 27 hidden features you can't afford to miss</strong></a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen"><strong>iPhone 18 Pro and Pro Max benchmarks: These are the fastest phones we've ever tested</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/the-iphone-duo-has-a-lot-of-hype-but-this-poll-has-a-surprising-reveal-for-samsungs-foldable</link>
                                                                            <description>
                            <![CDATA[ Tom's Guide readers let us know which foldable they're more interested in: the iPhone Duo or Galaxy Z Fold 8. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">e3iVtPLZ23jEbY9wPGgcUn</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/ENFN2u4hpSYiQYfbA6WbcL-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 17 Sep 2026 21:09:50 +0000</pubDate>                                                                                                                                <updated>Mon, 21 Sep 2026 09:51:53 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Samsung Phones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                    <category><![CDATA[Android Phones]]></category>
                                                                                                <author><![CDATA[ scott.younker@futurenet.com (Scott Younker) ]]></author>                    <dc:creator><![CDATA[ Scott Younker ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/RZsUpqcJ6Uj2q83oCUwNhQ-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Scott Younker is the West Coast Reporter at Tom’s Guide. He covers all the latest tech news, including phones, computing and more. He’s been involved in tech since 2011 covering everything from cameras and swimming pool equipment to the latest gaming consoles and smart TVs. He is on a seemingly never ending hunt to build the easiest to use home media system. &lt;/p&gt;&lt;p&gt;Before Tom’s Guide, Scott worked for publications like &lt;em&gt;Digital Trends, Outdoor Photographer, Dead Beats Panel&lt;/em&gt;, and in a brief detour, &lt;em&gt;America’s Funniest Home Videos&lt;/em&gt;. Yes, he has seen more pratfalls, silly pets and ridiculous home movie fails than is reasonably healthy. &lt;/p&gt;&lt;p&gt;When not writing about the latest devices or advances in chipsets, be sure to ask about Scott about disc golf and sustainability, or just if you’re being cheeky, ask about his noodle arm. If you truly want to get nerdy, bring up board games and his ongoing losing streak. &lt;/p&gt;&lt;p&gt;Scott joined Tom&#039;s Guide in 2024 as the West Coast Reporter. He graduated from the School of Journalism at the University of Oregon with a degree in magazine journalism and a minor in communications. While there he blogged or wrote for several magazines including the Fluxx, Ethos and the Oregon Commentator. He briefly wrote and managed a moderately successful blog focused on web comics. &lt;br&gt;Send secure tips on Signal: scyo1.55.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/ENFN2u4hpSYiQYfbA6WbcL-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Apple iPhone Duo shown in hand]]></media:description>                                                            <media:text><![CDATA[Apple iPhone Duo shown in hand]]></media:text>
                                <media:title type="plain"><![CDATA[Apple iPhone Duo shown in hand]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/ENFN2u4hpSYiQYfbA6WbcL-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>We asked Tom's Guide readers if they would rather pick up Apple's new <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> or the <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-review-wide-for-the-win">Samsung Galaxy Z Fold 8</a>, and the winner was quite surprising. </p><p>With 2,761 votes, one device proved far more popular than the other by more than double the votes, but was it the Apple iPhone Duo or Samsung Galaxy Z Fold 8? Check out the results below.</p><h2 id="which-flagship-foldable-would-you-rather-purchase">Which flagship foldable would you rather purchase?</h2><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-exgNKX"></div>                            </div>                            <script src="https://kwizly.com/embed/exgNKX.js" async></script><ul><li><strong>1st place: </strong>62%, Samsung Galaxy Z Fold 8</li><li><strong>2nd place: </strong>23%, iPhone Duo</li><li><strong>3rd place: </strong>15%, Neither</li></ul><p>With a total of 1,705 votes, 62% of respondents said the Samsung foldable is their preferred foldable phone. Apple's Duo came in a distant second with 632 votes, or 23%. </p><p>Meanwhile, 424 people said they weren't interested in either phone. If you find yourself in that camp, what would you buy instead? Or is this category too pricey for you?</p><h2 id="the-galaxy-z-fold-8-is-the-winner-but-why">The Galaxy Z Fold 8 is the winner, but why?</h2><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="8SvD4aoQkrBzEjS7QrbW5S" name="Samsung Galaxy Z Fold 8" alt="Samsung Galaxy Z Fold 8" src="https://cdn.mos.cms.futurecdn.net/8SvD4aoQkrBzEjS7QrbW5S-1920-80.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>So why did the Galaxy Z Fold 8 dominate our poll over the iPhone Duo. </p><p>I think it comes down to a few of factors in the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-vs-samsung-galaxy-z-fold-8-which-foldable-is-best-for-you#section-iphone-duo-vs-samsung-galaxy-z-fold-8-price-availability">battle between the Z Fold 8 and iPhone Duo</a>: design, price and expertise.</p><p>The Duo starts at $1,999 for the 256GB version and goes up to over $3k for the 2TB option. Samsung's foldable starts at $1,899, not a big difference but with how expensive the world has gotten in the last two years every dollar matters. No, Samsung doesn't offer a 2TB variant but the top-end 1TB model will cost you $2,499, again $100 than the equivalent Duo version.</p><p>Additionally, the Z Fold 8 offers a thinner and lighter design than the iPhone Duo. And Samsung lets you run more than two apps at once, which is better for multitasking. Plus, Samsung has been iterating foldables for eight generations, while this is Apple's first attempt.</p><p>There is concern over visibility and brightness with the matte finish on the Duo display, which is meant to hide the crease. Pictures of CEO John Ternus at the Emmys recently <a href="https://www.reddit.com/r/iPhoneFold/comments/1whl32i/john_ternus_shows_iphone_duo_at_the_emmys/" target="_blank">stirred up controversy online</a>, but we thought it was plenty bright in our hands-on time.</p><p>As we've found, though, the iPhone Duo <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-vs-samsung-galaxy-z-fold-8-7-ways-apples-foldable-beats-its-rival-from-ip68-to-faster-charging-and-more">has multiple features</a> that the Z Fold 8 doesn't, including iP68 durability, stylus support, faster charging, and a vapor chamber for better cooling.</p><h2 id="what-you-have-said">What you have said</h2><p>One reader said <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-vs-samsung-galaxy-z-fold-8-7-ways-apples-foldable-beats-its-rival-from-ip68-to-faster-charging-and-more#viafoura-comments">in a comment </a>that they were staying away from all things Apple as they didn't want to get sucked into another ecosystem. "I have Samsungs 8 ultra, and I am impressed with it," they said.</p><p>As a counterpoint, <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-vs-samsung-galaxy-z-fold-8-which-foldable-is-best-for-you#viafoura-comments">another reader wrote</a> that the "crucial factor" when comparing Samsung and Apple is Apple's "after-purchase service experience." </p><p>"Functionally, I have liked both platforms, but there is a fundamental difference in corporate philosophy. Apple actively invests in both technology and the customer service infrastructure required to support it. Samsung, on the other hand, focuses almost entirely on tech specs while leaving its customer support framework completely neglected," they said.</p><h2 id="bottom-line-12">Bottom line</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="NE3m4C3QUpw7U8uQfUAmea" name="iPhone-Duo-vs-Galaxy-Z-Fold-8-LEDE3" alt="IPhone duo vs galaxy Z Fold 8" src="https://cdn.mos.cms.futurecdn.net/NE3m4C3QUpw7U8uQfUAmea-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The iPhone Duo may be the belle of the ball after its recent announcement, but you won't be able to actually <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-is-official-price-release-date-specs-and-everything-you-need-to-know">hold it in your hands </a>until October 23. </p><p>Meanwhile, the Z Fold 8 is available right now and is a pretty impressive foldable, even if Apple's device beats it in some areas.</p><p>Let us know: why would you pick the Duo or the Z Fold 8? Don't like either? What's your replacement?</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-ultra-4-review"><strong>Apple Watch Ultra 4 review: I ran 22 miles to test Apple’s ultimate adventure watch</strong></a></li><li><a href="https://www.tomsguide.com/phones/iphones/11-best-ios-27-hidden-features-you-cant-afford-to-miss"><strong>11 best iOS 27 hidden features you can't afford to miss</strong></a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen"><strong>iPhone 18 Pro and Pro Max benchmarks: These are the fastest phones we've ever tested</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Your iPhone Duo deserves better than a cheap case — here are 9 life-savers ]]></title>
                                                                                                <dc:content><![CDATA[ <p>The much-hyped new iPhone Duo was announced a few weeks ago — and while it's not available until October 23, there are already plenty of deals on cases for the new gadget. We previously <a href="https://www.tomsguide.com/phones/iphones/dont-let-a-drop-ruin-your-day-these-9-iphone-duo-cases-are-total-lifesavers">rounded-up a selection of great cases</a> to keep this exciting – and <em>expensive </em>– new smartphone safe, but even more designs are now available as the hype steadily builds for the new device.</p><p>In the article I've picked out nine designs that will keep your iPhone Duo in mint condition, protecting it from dings and scratches, while looking good in the process. </p><p>There are some clean and simple cases for those who like to keep things elegant, as well as some flashier and more colorful designs. Whatever your style, you should be able to find an iPhone Duo case here.</p>        <div class="featured_product_block featured_block_hero" data-id="e1031548-b2a9-11f1-858a-97c9d84568a3">            <a href="https://www.esrtech.com/products/frosted-misty-blue-iphone-duo-magnetic-hybrid-phone-case-folding-stand" data-model-name="iPhone Duo Classic Hybrid Case (Misty Blue)" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/rJZiKXypmx3pUqetft6xVW.jpg" alt="Iphone Duo Classic Hybrid Magnetic Case With Flex Stand - Frosted Misty Blue"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>ESR</div>                                        <div class="featured__title">iPhone Duo Classic Hybrid Case (Misty Blue)</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="e10315ac-b2a9-11f1-bc7b-f594d287416e">            <a href="https://www.esrtech.com/products/luxury-burgundy-red-leather-iphone-duo-foldable-stand-case" data-model-name="iPhone Duo Magnetic Case (Deep Burgundy)" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/2GqgFucgKakob6TZjZGUaW.jpg" alt="Iphone Duo Atelier Magnetic Case With Flex Stand - Deep Burgundy"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>ESR</div>                                        <div class="featured__title">iPhone Duo Magnetic Case (Deep Burgundy)</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="e103128c-b2a9-11f1-b2c8-8dc67aafae92">            <a href="https://www.mous.co/products/super-thin-magsafe-compatible-phone-case-aramid_fibre?variant=41635147644986" data-model-name="Ultra Thin Aramid Fibre Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:125.42%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/KoXqsXqJREZ2DipgY6CXMh.jpg" alt="iPhone Duo case."></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>mous</div>                                        <div class="featured__title">Ultra Thin Aramid Fibre Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="e103135e-b2a9-11f1-b00b-571fd2ef0b84">            <a href="https://burga.us/products/curated-iphone-duo-case?variant=62446326088067&case-type=Elite%20Dark%20(MagSafe)&case-details-color=Gold" data-model-name="iPhone Duo Elite Dark Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/tkGp8bdE46rvw4jB8Z3jEX.jpg" alt="Curated - Iphone Duo Case - Elite Dark (magsafe) / Gold"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Burga</div>                                        <div class="featured__title">iPhone Duo Elite Dark Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="e10313c2-b2a9-11f1-a750-fb99be9e8ca1">            <a href="https://burga.us/products/bookmark-iphone-duo-case?variant=62446388183427&case-type=Elite%20Dark%20(MagSafe)&case-details-color=Gold" data-model-name="iPhone Duo Bookmark Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/hnur7z8FGbofH5zYQrhhzU.jpg" alt="Bookmark - Iphone Duo Case - Elite Dark (magsafe) / Gold"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Burga</div>                                        <div class="featured__title">iPhone Duo Bookmark Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="e1031426-b2a9-11f1-955d-355306bbf09a">            <a href="https://burga.us/products/velvet-night-iphone-duo-case?variant=62405770903939&case-type=Elite%20Dark%20(MagSafe)&case-details-color=Gold" data-model-name="Velvet Night iPhone Duo Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/D45zk2CYZfhW5VwefCuKKV.jpg" alt="Velvet Night - Iphone Duo Case - Elite Dark (magsafe) / Gold"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Burga</div>                                        <div class="featured__title">Velvet Night iPhone Duo Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="e1031480-b2a9-11f1-84e4-7de3b325d6d9">            <a href="https://www.mous.co/products/limitless-magnetic-compatible-phone-case-speckled-fabric?variant=41635148234810" data-model-name="Speckled Fabric iPhone Duo Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:133.33%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/6HunxzeSUfiKD2B3zcm9yd.jpg" alt="Speckled Fabric iPhone Duo case"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>mous</div>                                        <div class="featured__title">Speckled Fabric iPhone Duo Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="e103120a-b2a9-11f1-b25f-a54daf95b93b">            <a href="https://www.mous.co/products/limitless-magnetic-compatible-phone-case-aramid_fibre?variant=41635148398650" data-model-name="Limitless Phone Case - Aramid Fibre" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:133.33%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/D2zCLC4d4qKeEZJAtLJAjQ.jpg" alt="mous Limitless Phone Case"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Aramid Fibre</div>                                        <div class="featured__title">Limitless Phone Case - Aramid Fibre</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="e10312fa-b2a9-11f1-91c7-cbb7f55286fd">            <a href="https://www.alcanside.com/products/iphone-duo-alcantara-case-midnight-green-1?gad_campaignid=23903723718&gad_source=1&gbraid=0AAAABCqNy3Z8mqWC_DavZDPxfyUNMCfDT&gclid=CjwKCAjwn67VBhBnEiwAXUIN1Wy1XKlmBSizzElNaIUa2C8lGryJU2blw0Rp3W98zBKS2X1pa0xgPhoCMIIQAvD_BwE&tw_adid=811729639675&tw_campaign=23903723718&tw_kwdid=pla-2500631752961&tw_source=google&shpxid=fa757669-00c8-420e-bb6b-fce8e406ab78" data-model-name="iPhone Duo Alcantara Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/uqyY5UsQszq84rf7ekbKsU.jpg" alt="Iphone Duo - Alcantara Case - Midnight Green"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Alcanside</div>                                        <div class="featured__title">iPhone Duo Alcantara Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/your-iphone-duo-deserves-better-than-a-cheap-case-here-are-9-life-savers</link>
                                                                            <description>
                            <![CDATA[ The iPhone Duo is coming soon – which means that even more protective cases are coming out. Keep your expensive new toy safe from harm with one of these nine picks. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">i3AWLUAxd6SuEbCdyuo64i</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/ENVihrGoKnZQQGJwMeKBJP-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 17 Sep 2026 19:00:00 +0000</pubDate>                                                                                                                                <updated>Thu, 17 Sep 2026 19:37:22 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                                    <dc:creator><![CDATA[ Will Salmon ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/HpRWP7Mh9ErgRGoTvZBbBJ-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Will Salmon is Tom&#039;s Guide&#039;s Collections Editor, curating advice on the best products to spend your money on. Will has been writing about tech and entertainment for almost 20 years, including stints as GamesRadar+&#039;s Streaming Editor, editing comics website Newsarama, and writing for lots and lots of magazines.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/ENVihrGoKnZQQGJwMeKBJP-1920-80.jpg">
                                                            <media:credit><![CDATA[Edited with Gemini]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone Duo cases]]></media:description>                                                            <media:text><![CDATA[iPhone Duo cases]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone Duo cases]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/ENVihrGoKnZQQGJwMeKBJP-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The much-hyped new iPhone Duo was announced a few weeks ago — and while it's not available until October 23, there are already plenty of deals on cases for the new gadget. We previously <a href="https://www.tomsguide.com/phones/iphones/dont-let-a-drop-ruin-your-day-these-9-iphone-duo-cases-are-total-lifesavers">rounded-up a selection of great cases</a> to keep this exciting – and <em>expensive </em>– new smartphone safe, but even more designs are now available as the hype steadily builds for the new device.</p><p>In the article I've picked out nine designs that will keep your iPhone Duo in mint condition, protecting it from dings and scratches, while looking good in the process. </p><p>There are some clean and simple cases for those who like to keep things elegant, as well as some flashier and more colorful designs. Whatever your style, you should be able to find an iPhone Duo case here.</p>        <div class="featured_product_block featured_block_hero" data-id="e1031548-b2a9-11f1-858a-97c9d84568a3">            <a href="https://www.esrtech.com/products/frosted-misty-blue-iphone-duo-magnetic-hybrid-phone-case-folding-stand" data-model-name="iPhone Duo Classic Hybrid Case (Misty Blue)" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/rJZiKXypmx3pUqetft6xVW.jpg" alt="Iphone Duo Classic Hybrid Magnetic Case With Flex Stand - Frosted Misty Blue"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>ESR</div>                                        <div class="featured__title">iPhone Duo Classic Hybrid Case (Misty Blue)</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="e10315ac-b2a9-11f1-bc7b-f594d287416e">            <a href="https://www.esrtech.com/products/luxury-burgundy-red-leather-iphone-duo-foldable-stand-case" data-model-name="iPhone Duo Magnetic Case (Deep Burgundy)" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/2GqgFucgKakob6TZjZGUaW.jpg" alt="Iphone Duo Atelier Magnetic Case With Flex Stand - Deep Burgundy"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>ESR</div>                                        <div class="featured__title">iPhone Duo Magnetic Case (Deep Burgundy)</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="e103128c-b2a9-11f1-b2c8-8dc67aafae92">            <a href="https://www.mous.co/products/super-thin-magsafe-compatible-phone-case-aramid_fibre?variant=41635147644986" data-model-name="Ultra Thin Aramid Fibre Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:125.42%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/KoXqsXqJREZ2DipgY6CXMh.jpg" alt="iPhone Duo case."></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>mous</div>                                        <div class="featured__title">Ultra Thin Aramid Fibre Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="e103135e-b2a9-11f1-b00b-571fd2ef0b84">            <a href="https://burga.us/products/curated-iphone-duo-case?variant=62446326088067&case-type=Elite%20Dark%20(MagSafe)&case-details-color=Gold" data-model-name="iPhone Duo Elite Dark Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/tkGp8bdE46rvw4jB8Z3jEX.jpg" alt="Curated - Iphone Duo Case - Elite Dark (magsafe) / Gold"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Burga</div>                                        <div class="featured__title">iPhone Duo Elite Dark Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="e10313c2-b2a9-11f1-a750-fb99be9e8ca1">            <a href="https://burga.us/products/bookmark-iphone-duo-case?variant=62446388183427&case-type=Elite%20Dark%20(MagSafe)&case-details-color=Gold" data-model-name="iPhone Duo Bookmark Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/hnur7z8FGbofH5zYQrhhzU.jpg" alt="Bookmark - Iphone Duo Case - Elite Dark (magsafe) / Gold"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Burga</div>                                        <div class="featured__title">iPhone Duo Bookmark Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="e1031426-b2a9-11f1-955d-355306bbf09a">            <a href="https://burga.us/products/velvet-night-iphone-duo-case?variant=62405770903939&case-type=Elite%20Dark%20(MagSafe)&case-details-color=Gold" data-model-name="Velvet Night iPhone Duo Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/D45zk2CYZfhW5VwefCuKKV.jpg" alt="Velvet Night - Iphone Duo Case - Elite Dark (magsafe) / Gold"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Burga</div>                                        <div class="featured__title">Velvet Night iPhone Duo Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="e1031480-b2a9-11f1-84e4-7de3b325d6d9">            <a href="https://www.mous.co/products/limitless-magnetic-compatible-phone-case-speckled-fabric?variant=41635148234810" data-model-name="Speckled Fabric iPhone Duo Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:133.33%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/6HunxzeSUfiKD2B3zcm9yd.jpg" alt="Speckled Fabric iPhone Duo case"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>mous</div>                                        <div class="featured__title">Speckled Fabric iPhone Duo Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="e103120a-b2a9-11f1-b25f-a54daf95b93b">            <a href="https://www.mous.co/products/limitless-magnetic-compatible-phone-case-aramid_fibre?variant=41635148398650" data-model-name="Limitless Phone Case - Aramid Fibre" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:133.33%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/D2zCLC4d4qKeEZJAtLJAjQ.jpg" alt="mous Limitless Phone Case"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Aramid Fibre</div>                                        <div class="featured__title">Limitless Phone Case - Aramid Fibre</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="e10312fa-b2a9-11f1-91c7-cbb7f55286fd">            <a href="https://www.alcanside.com/products/iphone-duo-alcantara-case-midnight-green-1?gad_campaignid=23903723718&gad_source=1&gbraid=0AAAABCqNy3Z8mqWC_DavZDPxfyUNMCfDT&gclid=CjwKCAjwn67VBhBnEiwAXUIN1Wy1XKlmBSizzElNaIUa2C8lGryJU2blw0Rp3W98zBKS2X1pa0xgPhoCMIIQAvD_BwE&tw_adid=811729639675&tw_campaign=23903723718&tw_kwdid=pla-2500631752961&tw_source=google&shpxid=fa757669-00c8-420e-bb6b-fce8e406ab78" data-model-name="iPhone Duo Alcantara Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/uqyY5UsQszq84rf7ekbKsU.jpg" alt="Iphone Duo - Alcantara Case - Midnight Green"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Alcanside</div>                                        <div class="featured__title">iPhone Duo Alcantara Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
            </channel>
</rss>