Far from Colombia's tourist hubs, the Mavecure Mountains rise from the Amazon jungle. Once off-limits during conflict, they now draw adventurous visitors to rare wildlife, sacred sites and vast views.
(Image credit: John Otis)
The National Transportation Safety Board temporarily pulled its docket system offline after digital images were used to reconstruct cockpit voice recordings of the pilots in a recent crash.
(Image credit: Joel Rose)
The Keychron K3 HE is an analog keyboard with a minimalist form that belies its wealth of features.
The first thing I noticed was just how compact it is. Even for a board with a 75% layout, it’s small across all dimensions. It’s also quite light, which makes it a good portable option.
More impressive is the fact that build quality doesn’t appear to have been sacrificed. It feels solid and premium, rivaling the best gaming keyboard constructions. I also liked the wooden edge trim, which lends it a certain style that sets it apart from most in this sector, dominated as it is by plastics and metals.
However, despite being quite thin, my wrists still had to bend upwards to a slightly uncomfortable degree. The K3 HE is certainly worth pairing with a wrist rest, and it’s a shame one isn’t included. The two-stage feet don’t provide enough of a tilt to mitigate this, either.
(Image credit: Future)The K3 HE also lacks the dipped middle row typical of many keyboards. What’s more, the keycaps are slanted forward, which, while I found comfortable, others might not.
On top of this, the keys also feel a little heavier than I'm used to, but they’re still quick and responsive. They provide plenty of feedback and sufficient dampening.
Since the K3 HE has analog switches, there are plenty of adjustments you can make to their feel and response in Keychron’s web app. This app is based on the open-source QMK firmware. Aside from adjusting the actuation point, you can also enable Rapid Trigger, assign multiple inputs to a single key, and even adjust the curve profile, to alter sensitivity as the key travels past certain points. There’s also an option to emulate controller inputs, but I couldn’t get this mode to work in practice.
The software is clearly laid out, but there’s no standalone app, and you can only use it when the K3 HE is connected via the USB cable. What’s more, updating the firmware is needlessly complicated, and there are a few usability issues that may prove frustrating when tinkering frequently.
However, the K3 HE represents good value when you consider all that it offers. Not many can compete with its quality and feature set at this price point. If you don't mind the unique key shape and can live with slightly inefficient software, the K3 HE is a good pick for those after plenty of analog functionality without spending the earth.
(Image credit: Future)Keychron K3 HE review: Price & availabilityThe Keychron K3 HE costs $119.99 (about £90 / AU$170) and is available now in two colorways: black and white.
This is a good price for an analog keyboard, and a hot-swappable one at that. It’s slightly less expensive than the Turtle Beach Vulcan 2 TKL Pro. Like the K3 HE, this board features various customization options, including controller emulation — which actually worked when I tested this model. However, it doesn’t feel quite as premium, and it’s not so great for typing.
For a more luxury analog experience, the Steelseries Apex Pro can’t be beat. This is probably the best analog keyboard I’ve ever used. The key feel is glorious, allowing for superb control, and the whole unit is built like a tank. It’s seriously expensive, though.
Keychron K3 HE review: SpecsLayout
TKL
Switch
Analog (TMR magnetic)
Programmable keys
Yes
Dimensions
12.56 x 4.96 x 0.98 inches / 319 x 126 x 25mm
RGB or backlighting
Yes (customizable)
(Image credit: Future)Keychron K3 HE review: Design and featuresThe Keychron K3 HE cuts a minimal figure. It’s pleasingly light and compact, which makes it easy to move around or take with you on your travels.
It looks smart, too, and although I wasn’t sure about the wooden sides at first, they grew on me quickly. They also offer a nice counterpoint to the inorganic slabs adopted by many gaming keyboards. The RGB backlighting adds some vibrancy, but it doesn’t shine through the keycap characters, which is a shame as this would’ve made them easier to see in dark environments.
Build quality is also admirable. The plastic chassis feels smooth and solid, while the two-stage feet fold out with ease and offer a surprising amount of stability, preventing me from accidentally moving the board around, as I’ve experienced with others.
(Image credit: Future)Despite the compact layout, you still get arrow and navigation keys, which I’m always pleased to see for productivity’s sake. There are also some basic but useful FN shortcuts on the F row, including one for screenshotting and several for media playback. These are all clearly labelled.
The K3 HE doesn’t feature a dipped middle row common on many keyboards, but the unique forward slant of the keycaps compensates for this somewhat. Along with their low profile, It makes it easier to hit them flush. However, I can imagine some won’t like this unique design.
Even taking into account the compact nature of the K3 HE, it still sits quite high off the ground, while the feet, despite having two-stages, fail to create much tilt. These aspects mean your wrists have to bend further than you might think to reach the keys. Using a wrist rest helped to alleviate my discomfort, but you’ll have to provide your own, since the K3 HE doesn’t come with one.
I appreciated the location of the switches for toggling connectivity modes and operating systems, too. They’re on the left side of the unit, rather than at the back as is typical, which makes them easier to reach.
(Image credit: Future)However, the USB-C port is also on this side, which may prove a little inconvenient for certain setups. At least the included USB cable has an L-shaped jack, which means it doesn’t protrude as much as a standard one.
To customize the inputs of the K3 HE, you’ll need to use Keychron’s web app in a browser (there’s no standalone app you can download). You also need to be in wired mode. You can only use the web app in wireless mode to update the firmware of the 2.4GHz dongle.
However, updating the firmware is a convoluted process. You first need to download the Toolbox Driver, and then follow the process in the web app, although it’s not entirely clear when the update is complete. During this whole process, I encountered an error, with a dialog box instructing me to upload a required JSON file. It gave me no hint as to what file specifically was needed or where to acquire it, but somehow I got around the issue and the firmware successfully updated.
To update the firmware of the keyboard itself, you have to hold the escape key and disconnect the cable before reconnecting it. I then had to disconnect and reconnect the cable after this finished in order for it to be recognized again by the web app.
(Image credit: Future)Keychron K3 HE review: PerformanceThe Keychron K3 HE is a competent keyboard, whether you’re gaming or typing. The keys are a mixture of thocky and clicky, although they’re slightly biased towards the latter. Dampening is reasonable, but they don’t feel very well lubed. Presses can certainly be heard, but they’re far from the noisiest out there.
What stands out most of all, though, is their resistance. They’re heavier than you might expect, but since you can adjust their actuation point, they’re still capable of responding instantly. This resistance can be beneficial, too, as it can make typing more forgiving. The generous spacing between the keys can also help to prevent erroneous presses.
Despite their resistance, I didn’t find them a chore to use. They rebound quickly, making them snappier than they otherwise would. When playing games such as Counter-Strike 2, I didn’t find the WASD keys onerous to hold for long periods at a time.
(Image credit: Future)The weight also provides greater control when pressing keys part way, which you’ll need to do if you want to make full use of the K3 HE’s analog functionality. Speaking of which, there is a smorgasbord of options in this area.
In addition to setting the actuation point (which has a range of 0.2 to 2.8mm), you can also enable Rapid Trigger. This is a common feature on many analog keyboards, but with the K3 HE, you can adjust both the trigger and the reset distances, rather than just the latter.
You can toggle a progress bar to show the travel of key presses in real time, which is something I’m always pleased to see in analog keyboard software. However, Keychron’s goes one step further by accompanying this with a readout in millimeters. This is even more helpful, and not something I’ve seen before in such visualizers.
It’s a shame, however, that this visualizer doesn’t show the effects of your Rapid Trigger settings, which is the area most deserving of visual representation, given its not-so-obvious operation. It’s also annoying that you have to turn the visualizer back on every time you make adjustments to the actuation point or Rapid Trigger, or whenever you navigate back from a different section of the software. What’s more, the visualizer is only available when adjusting one key at a time, but not multiple.
(Image credit: Future)Other analog functions on the K3 HE include the ability to assign up to four inputs to a single key, which trigger based on how far down you press said key. You can also adjust the curve profile by selecting one of two presets or creating your own. This is done by dragging four points on a graph to adjust sensitivity over the course of a key’s travel. This kind of adjustment is more common on the best PC controllers, but rarely seen on analog keyboards.
Speaking of which, there’s also a gamepad emulation feature in the web app, which includes the ability to mimic the analog control of joysticks and triggers. However, I couldn’t get this to work on the games I tried. This isn’t an issue with the games themselves, since I’ve got similar features to work on other analog keyboards.
In addition to analog-based customizations, the web app also has a SOCD function with a generous number of settings, and there are plenty of key mapping options. Naturally, there’s also a macro recording facility.
The K3 HE connected well via its different methods, and I didn’t experience any lag or dropouts while using the board. Hot-switching between devices was quick and easy for the most part, although there were times when it failed to re-establish a connection, particularly when switching from wired to wireless mode.
Battery life isn’t particularly great, either. After only a couple of days of using a mixture of connectivity methods, it died. Also, I couldn’t see a battery life indicator anywhere for the K3 HE, either on the board itself or in the web app, which seems like a gross oversight.
Should I buy the Keychron K3 HE?ScorecardAttributes
Notes
Rating
Value
The K3 HE is very well-priced for a hot-swappable analog keyboard with multiple connectivity options and plenty of customizations.
4.5 / 5
Design and features
The K3 HE is surprisingly compact and light, yet sturdy. The slanted keycaps might deter some users, though.
4 / 5
Performance
The switches are surprisingly heavy, but they’re responsive and offer good control. The finicky web app and poor battery life are blemishes.
3.5 / 5
Overall rating
The Keychron K3 HE is a very competent analog keyboard for the price. It performs well and features plenty of customizations, but it has a few drawbacks besides.
3.5 / 5
Buy it if…You want plenty of analog options
There are numerous in-depth tweaks and features for the switches — more so than on many of its rivals.
You want to get a lot for your money
Not many keyboards offer analog switches and this many features for such a low price.
You want slick software
The K3 HE has no standalone app, only a web app, and it can only be used when connected via the USB cable. It also has some usability issues.
You want a long battery life
The K3 HE didn’t last more than a couple of days during my testing, and for some reason there’s no battery indicator.
Turtle Beach Vulcan 2 TKL Pro
The Vulcan 2 Pro is another reasonably priced analog keyboard. It too has a controller emulation feature, but unlike the K3 HE, it actually works. It doesn’t feel quite as premium, though, and the narrow and prominently floating keycaps hamper typing somewhat. Read our full Turtle Beach Vulcan 2 TKL Pro review.
SteelSeries Apex Pro TKL Wireless
The supreme analog keyboard. You’re unlikely to find a unit better built than this, and the switches feel incredible to use, operating smoothly and offering plenty of control. You’ll have to part with a lot of cash, mind, but if you’re serious about gaming with keyboards, it could be worth it. Read our full SteelSeries Apex Pro TKL Wireless Gen 3 review.
I tested the Keychron K3 HE for several days. I used it for gaming, working, and general browsing. I used all of its connectivity modes.
I used its web app to make as many adjustments and enable as many of its analog features as I could. I played games such as Counter-Strike 2 to test its gaming prowess.
I’ve reviewed plenty of keyboards in my time, from everyday workhorses to gaming powerhouses, with varying price points, form factors, and switch types.
The tour comes as Myanmar's new government tries to consolidate its political position regionally, while continuing to wage a brutal civil war.
(Image credit: Aung Shine Oo)
Some lawmakers are speaking out against closed, single-party primaries, which they see as part of a system that limits voter choice and incentivizes elected officials to prioritize party loyalty.
(Image credit: Matthew Hatcher)
Soon after winning the Texas Republican Senate primary runoff, Ken Paxton attacked Democratic nominee, state Rep. James Talarico as "too low-T for Texas," putting manhood front and center in the race.
(Image credit: Danielle Villasana)
The Meraki Espresso Machine Gen 2 is a manual coffee machine that sits more at the prosumer end of the market. Its whole raison d'être is around helping you make barista-quality coffee by hand and, it achieves this thanks to the assistance of some smart features that help streamline the process, while leaving control fully in your hands.
As a complete package, the Meraki Espresso Machine Gen 2 is an undeniably polished product. It has a silhouette just sleek enough to fulfil its prosumer aspirations and its tiltable touchscreen is super easy to use. It also comes with almost every accessory you could want and each is engineered to such a high standard that they’re a real pleasure to use, especially the hefty tamper and coffee distributor.
Beneath the hood, it has hardware as impressive as any of the best coffee makers we’ve tested. Its rotary pump maintains pressure better than the vibration pump many mass market machines rock, while its dual boilers ensure the steam wand won’t start to sputter out part way through foaming your milk.
It’s the Meraki’s smart features that really set it apart from other machines though — rather than automating every part of your coffee making routine, it augments them. For example, its built-in scale allows you to grind coffee to a specific weight every time, while a second scale lets you brew your coffee by weight, making it far easier to dial in a very specific grind to extraction ratio. Meanwhile, an integrated temperature sensor in the steam wand means you can set it to cut out when your milk hits your target heat, which is easier than relying on temperature alone.
So what’s it like in use? Honestly, pretty slick. Dialing in your perfect grind and dose feels far more granular than usual, thanks to the integrated scales. Those solidly built accessories make transferring, evening out and tamping your coffee far easier, then you can easily set to extract a ristretto or long black depending on your preference. Frothing milk is rarely my favorite part of making a coffee, yet that temperature sensor allowed me to concentrate more on honing my technique.
(Image credit: Future)As a result, the whole manual process felt as rewarding as ever, while producing delicious and exceedingly consistent coffee. I was able to extract just the right flavor profile out of even cheaper beans over and over, while the one brew I produced with a more premium batch really let its exquisite mango tasting notes shine through. Despite the fact I’m not a major fan of milk in coffee, even the macchiato I whipped up using its steaming wand tasted great, with just the right amount of foam to add texture without overpowering the flavor of the coffee.
Really my only substantial criticism of the Meraki Espresso Machine Gen 2 is its cost. Coming in at $1,799 / £1,599 / AU$2,799, it resides firmly at the premium end of the market and I imagine there will be quite a few people who balk at the idea of dropping that much on a manual coffee maker. However, cost is not the same as value: the experience of using this machine and the quality results you’ll get out of it totally warrant that price for those that can stretch to it.
(Image credit: Future)Meraki Espresso Machine Gen 2 review: price & availabilityHaving first been available for pre-order in March 2026, the Meraki Espresso Machine Gen 2 is available now. It comes in two colorways: black or white. And barring a knock box, it comes with pretty much every accessory you could need, whether that’s a tamper, coffee distributor, cleaning brush, or blind portafilter basket for backflushing.
You’ll pay a premium for this premium device though. At a list price of $1,799 / £1,599 / AU$2,799, this is an undeniably prosumer device that comes in at the top price range of the best bean-to-cup makers we’ve featured. While it’s not quite as spendy as something like the $2,799.95 / £1,915 (around AU$3,865) Breville Oracle Touch (known under the brand name Sage in the UK) or the £2,199 (around $2,970 / AU$4,100) Siemens EQ900 Plus, it’s an expensive machine and doesn’t come with as many automated features as some machines. I’d argue it’s well worth the price you’ll pay but such a premium manual machine won’t be for everyone.
(Image credit: Future)Meraki Espresso Machine Gen 2 review: specsCategory
Specification
Type
Manual espresso machine
Dimensions
14.57 x 14.57 x 16.34 inches / 370 x 370 x 415mm
Weight
32 lbs / 14.5kg
Water tank capacity
2.1 quarts / 2 liters
Steam wand
360-degree articulating with temperature sensor
Max pressure
9 bar extraction
(Image credit: Future)Meraki Espresso Machine Gen 2 review: designI’ll be upfront here: I flat out love the way the Meraki Espresso Machine Gen 2 looks. At 14.57 x 14.57 x 16.34 inches / 370 x 370 x 415mm, it’s hardly the sveltest machine I’ve ever tested. But the fact its water tank, bean hopper and boilers are all separate towers prevents it from looking too hulking on my countertop, while the combo of its chrome fixtures and pivotable touch screen give it just enough flair to stand out from your average coffee machine.
But it’s not just the Meraki’s aesthetics that are finished to a high standard. All the accessories packaged with it feel seriously premium, and there weren’t any glaring omissions. Everything has a reassuring solidity to it: the portafilter has a wonderfully tactile wooden handle, while the solid metal of both the coffee distributor and tamp has sufficient heft to give you real confidence when producing the perfect puck of grounds. Extra little touches like the wooden box for storing the accessories on just add that final polish to the experience.
Don’t be fooled by this focus on looks though. Underneath the Meraki’s sleek exterior beats the ferocious industrial heart of a prosumer espresso machine. Discrete boilers for the brew system and steam wand should mean that you don’t have to worry about the wand’s pressure giving out part way through steaming, while its rotary pump maintains nine bars of pressure more consistently than the vibration pump used by many home machines.
(Image credit: Future)The Meraki also has a decent amount of capacity. The water tank itself has a volume of 2.1qt / 2,000ml, which I’d say is pretty average for a coffee maker — you’ll get plenty of brews out of that, even if it’s not as colossal as something like the huge 2.6qt / 2.5L Breville Oracle Touch. Meanwhile, the Meraki’s bean hopper measures 2.36 inches high by 4.06 inches diameter / 60 x 103mm. Generally I found that was sufficient to fuel around four double espressos but, naturally, your mileage will vary depending on how you like to dose your grounds.
One of the things I love about the Meraki is that it sits firmly in the camp of a manual espresso machine — there’s no bean-to-cup function here — but it comes crammed with features to make you better at pulling shots and foaming milks.
Perhaps the most explicitly ‘smart’ function is its CoffeeSense feature. This allows you to scan a tag on compatible Meraki coffee bags and it will suggest the recommended grind size, dosing weight and extraction temperature for those beans to help you get the best result out of those beans. I can definitely see how that would be a neat feature for someone who’s happy to stick with one brand of beans but part of the joy of coffee for me is trying different varieties and growers, so I’m not sure I’d get as much use out of this as some.
(Image credit: Future)But it also offers other ways to make dialing in your perfect brew easier. Built-in scales beneath both the grinder and grouphead allow you to grind your beans and express your coffee by weight, giving you really precise control over each. Meanwhile, Auto mode calculates the right brew weight based on how much coffee you’ve ground, making it easy to manually fix yourself a coffee without needing too much trial and error balancing brew time and grind. These are fantastic as a guide, allowing you to really build confidence before you start improvising like a true manual maestro.
Another impressive element of the Meraki Espresso Machine Gen 2’s design is its steam wand. It has a cool-touch design — although the head still gets hot so careful not to brush against it — and it’s super flexible, making it easy to get it at a perfect angle for frothing your milk. More innovatively, it has a built-in temperature sensor that allows you to stop steaming milk at the perfect temperature, rather than having to rely on touch alone.
None of these features are forced on you and they’re suitably light touch that it’s really easy to start trusting your own instincts once you’re ready. But I’ve never used an espresso machine that’s helped guide me so well between amateur and prosumer coffee making before — it’s just the right amount of support without making you dependent on its help.
So how easy is it to make coffee using the Meraki Espresso Machine Gen 2? Well, honestly, at first I found it a little unpredictable. Tiny variations in tamping pressure seemed to produce wildly different results — the first brew ran through the puck incontinently despite the fine grind I’d used, while the second over-extracted to such an extreme it made my mouth pucker like I’d licked an ibuprofen. Then I realized my mistake.
Turns out I’d slightly underestimated the Meraki’s grinder — as it’s calibrated for espresso, my default instinct to whack the grinder on one of the lowest settings was producing a silt that easily channeled or clogged the portafilter basket depending on how firmly it was tamped. After a bit of experimentation, I was able to dial in on my perfect results though, settling on a grind of 10.
Fortunately, the Meraki’s grinder perfectly suits this kind of tinkering. Not only do you have very granular control over the fineness of your grind, but the fact that you can dose using the built-in scale beneath the grinder makes tweaking the exact quantity of coffee you want super-repeatable. In automatic mode, I could simply dial in 18g for a double shot and it would stop grinding once it hit my desired dose, or I could go off-piste and simply grind it up manually using my best judgement.
(Image credit: Future)Preparing the puck always felt like a breeze — all I had to do was place the portafilter on top of the dosing cup, flip it and then give it a few taps to transfer my grounds. A few twists of the coffee distributor and the grounds would be nicely distributed, meaning all I had to do was tamp it down with that wonderfully sturdy tamper. Each tool is so well put together that it’s a really satisfying process and it feels easy to get professional results.
And with that, I was ready to go — or at least once the water was heated up. While the two minutes and 10 seconds it took the dual boiler to heat up the first time is slower than some consumer coffee machines, it’s actually pretty fast compared to many prosumer units, which can sometimes take upwards of 15 minutes. Additionally, another neat feature of the Meraki is your ability to set the boiler to come on at a specific time of day, meaning it can be all warmed up and ready to go for your first coffee of the day.
Once I’d actually properly calibrated my grind and dosing, extracting properly was a breeze. In Automatic mode, I simply had to set the weight of my drink — for example, 36g for an espresso — and set it to run, whereas in Manual mode I could simply run it until I was happy with the quantity. Thanks to that rotary pump, it produced a steady stream of espresso, neither hemorrhaging coffee too fast nor letting it dribble out in fits and starts. It’s also pretty quiet, hitting just 65dB and making more of a whir than the juddering noise I’m used to from vibration-pumped machines.
(Image credit: Future)Steaming milk has never really been my forte. As a black coffee drinker, I’ve never had much need to develop the knack. But the Meraki also makes this a lot easier. Not only does its dual boiler mean that it maintained constant pressure throughout steaming but, thanks to its built-in thermostat, the steam wand clicked off when my milk had reached my target temperature, meaning I could just focus on creating the right level of foam and getting it swirling. Not only did this help me whip up a passable macchiato but, when I’d gained a bit more confidence, I was able to make a decent manual latte using touch alone.
So what were the results like? Pretty sensational. Even trying with some relatively affordable decaf beans, the coffee the Meraki produced had a stable, beautifully caramel crema, just the right velvety texture and not straying too far into bitterness or acidity. Each shot I poured remained consistent, showing how easy it is to keep getting these great results. And when I tested it out with a premium bag of Dahwe beans from Ritual Coffee Roasters, the results genuinely blew me away: the flavor was flat out gorgeous, maintaining a pitch perfect balance of not being aggressively floral but confidently communicating its mango overtones.
(Image credit: Future)I’ll admit that I much prefer making coffee than scrubbing up the mess I’ve made but cleaning up here is pretty straightforward. Everyday use really only requires you to purge the steam wand, then give it, the portafilter and the grouphead a wipedown with a damp cloth. Even doing the deep clean at the end of my review wasn’t particularly arduous. Cleaning the steam wand involves running it for bursts of 10 seconds multiple times while submerged in cold water. Making sure the machine’s innards stay squeaky clean is even easier — just pop in the blind portafilter basket, pop it in the machine and then select the cleaning option and a tutorial will walk you through the rest.
There’s always something deeply satisfying about making coffee yourself and that’s why I’ve always been a big fan of manual machines. But what I like most about the Meraki Espresso Machine is that it makes it much easier to take your hand-crafted coffee to the next level. Automated features don’t remove your agency — they instead support it, allowing you to freestyle more and more as your skills grow. And the end result is wonderfully extracted and thoroughly consistent coffee. So ultimately, if you like getting hands on with your coffee and money’s not an object, you’re going to get great results out of the Meraki.
Attribute
Notes
Score
Value
This is undeniably a premium espresso machine. But given its quality and the consistent results it achieves, I’d argue it’s worth every cent.
4.5/5
Design
Sleekly designed with really well engineered accessories. Dual boiler and rotary pump help maintain consistent temperature and pressure. Smart features really streamline your coffee-making without taking you out of the driving seat. However, the CoffeeSense feature only works with Meraki beans.
4.5/5
Performance
Warms up quickly, easy to dial in your perfect quantity of grounds and coffee size, temperature sensor in steam wand makes steaming milk easier, produces excellently well-extracted coffee that tastes consistent time after time, easy enough to clean.
5/5
Buy it if…You love consistent espresso and well-foamed milk
Thanks to its rotary pump and dual-boiler, the Meraki maintains both temperature and pressure incredibly well, allowing you to pull consistently great shots every time.
You want clever features for streamlining your manual coffee making
With smart functionality like grinding and brewing by weight, and its steam wand’s built-in temperature sensor, the Meraki makes your coffee making workflow easier — without taking away your control.
You don’t have a big budget
The Meraki Espresso Machine is unabashedly premium in its price. If the idea of dropping $1,799 / £1,599 / AU$2,799 on a coffee machine makes you break out in a cold sweat, it’s probably not for you.
You want coffee at the press of a button
Despite its automated features, this is still firmly a manual machine. If you just want fantastic coffee for minimal effort, you’ll likely prefer a fully automatic bean-to-cup machine.
Category
Meraki Espresso Gen 2
Breville Barista Touch Impress (Cold Extraction)
La Pavoni Europiccola (Millennium)
Type
Dual Boiler / Integrated Grinder
Single Boiler (ThermoJet) / Integrated Grinder
Manual Lever / Single Boiler
Dimensions
14.57 x 14.57 x 16.34 inches / 370 x 370 x 415 mm
16.42 x 13.11 x 13.50 inches / 417 x 333 x 343 mm
12.6 x 7.87 x 11.42 inches / 320 x 200 x 290 mm
Weight
32 lbs / 14.5kg
24.2 lbs / 11kg
12.1 lbs / 5.5kg
Water tank capacity
2.1 quarts / 2 litres
2.1 quarts / 2 litres
0.8 quarts / 0.8 litres
Steam wand
Professional 360° articulating cool-touch
Auto MilQ
Manual
Max pressure
9 bar
9 bar
Manual
Breville Barista Touch Impress with Cold Extraction
If you’re looking for a slightly more automated coffee, the Barista Touch Impress with Cold Extraction is a great fit. It still helps you dial in your perfect dose with the grinder but also allows you to tamp it in place without removing it. Once you’ve slotted the portafilter beneath the grouphead, you can then select from a range of 14 hot and cold drinks, including cold brew, and the AutoMilq steam wand will then froth your milk to order. Read our full Breville Barista Touch Impress with Cold Extraction review.
La Pavoni Europiccola
Alternatively, if you’re one of those people that despises any automation and thinks that even using a pump to extract your coffee is cheating, the La Pavoni Europiccola is definitely for you. Using a lever to generate the required pressure, it allows you to get literally hands on with your coffee and produces absolutely fantastic results. It’s not for the faint of heart though: it has a steep learning curve to master, heats slowly and it’s not cheap given you’re doing all the hard work yourself. Read our full La Pavoni Europiccola review.
When testing the Meraki Espresso Machine Gen 2, I used it over the course of several weeks. I experimented with different grind levels, used different varieties of beans and tamped at a range of pressures to see how consistent its results were. I also tried to make a variety of drinks and steamed several different varieties of milk to see how the steam wand performed.
To understand how well the Meraki worked as a manual machine, I made sure to extract several coffees without using the automatic dosing and steamed milk using touch alone, rather than relying purely on the steam wand’s temperature sensor. When assessing the performance of the boiler and pump, I not only timed how long it took to heat up in the morning but I also used a sound level meter to record how much noise it made during extraction.
When it comes to my own experience, I’ve been making and drinking coffee on a daily basis for well over two decades. I’ve also gotten hands on with a wide range of machines, whether they’re De’longhi, Breville or Gaggia. My preferred tipple to make with a machine is a double espresso or long black, although any time the weather is not positively arctic, cold brew is my go-to.
The Sonic Kids Battery Toothbrush is Ordo's entry-level electric toothbrush designed for children aged 4+. My six-year-old daughter and I tested the Squishmallows-branded model, but there is also a Wicked version for a slightly older demographic. If you prefer rechargeable toothbrushes, then Ordo sells an almost identical model but with an internal battery and a charging stand.
The design of the toothbrush is unashamedly targeted at young children. This begins with the fun and playful Squishmallows branding alongside bright and bold colors, but it also extends to the free-flowing and curvy shape. My child loved having her own age-appropriate toothbrush, and when I told her that she had to go back to her regular 'boring' toothbrush, she was genuinely disappointed.
One of the standout features of the toothbrush is that the heads are replaceable. Unlike the best electric toothbrushes aimed at adults, in which replaceable heads are almost a given, this is far from guaranteed with children's toothbrushes. Some electric toothbrushes aimed at children, such as Colgate's Kids Battery Toothbrushes and others from the likes of Oral-B, will only last a few months before the bristles lose their strength and the whole device is consigned to landfill.
Replaceable heads, just like an adult's brush, sets the Ordo apart and will help to ensure the longevity of the toothbrush as a whole.
(Image credit: Future / Paul Hatton)Despite the replacement heads which Ordo will recycle for you, free of charge, the toothbrush itself doesn't score particularly highly from a sustainability point of view. It's constructed of almost 100% plastic and is powered by a single AA battery, which lasts 60 days.
The toothbrush produces 18,000 pulses/vibrations per minute, which offers reasonable performance in terms of bacteria and plaque removal. Older children will benefit from a more vigorous clean, but the Ordo delivers just about enough for children aged around four or five.
My child's regular toothbrush has an oscillating head, and so the sonic motion of the Ordo took a little getting used to. She also found that the vibrations ran right through the handle, causing an uncomfortable feeling in her hand. Sonic versus oscillating is a long-standing debate, and if you're wondering which to go for, our sonic vs rotating toothbrushes guide is worth a look.
(Image credit: Future / Paul Hatton)This Ordo toothbrush doesn't feature any additional modes beyond vibrating, and there are no timers in sight, not even a two-minute one. This was an issue for my daughter, who had no idea whether she had reached the magic two minutes and so relied on me to help her estimate that. The lack of 30-second pacing timers is unsurprising at this price point but would have been nice to have.
The features on offer and the performance delivered make the Ordo Sonic Kids Toothbrush a strong contender for a place amongst the best electric toothbrushes. If Ordo could integrate a two-minute timer and improve its sustainability credentials, then we'd have a five-star performer on our hands.
Ordo Squishmallows Sonic Kids: SpecificationsComponent
Value
Battery life
60 days
Sonic vibrations
18,000 pulses/vibrations per minute
Charging stand
No. Powered by a single AA Battery
Timer
No
Noise
Decibel level not published
Settings
1
(Image credit: Future / Paul Hatton)Ordo Squishmallows Sonic Kids: Price and availabilityThe Ordo Squishmallows Sonic Kids battery toothbrush is reasonably priced given its build quality and replacement head capability. In the box are the toothbrush handle, two heads, and an AA battery.
Each head will last around three months, which means the upfront cost will provide six months' worth of toothbrushing. A 2-pack of replacement heads is almost as expensive as the toothbrush itself, so you'll need to factor this ongoing cost into your buying decision.
If your child is into characters such as Barbie, Batman, Minions, or Pokémon, then Colgate is the alternative brand to go for. They are usually around half the price compared to the Ordo, but the head isn't replaceable. That means once the bristles wear down, you throw the whole plastic handle away, making Ordo much more eco-friendly and cost-effective in the long run.
Category
Comment
Score
Value
Reasonably priced toothbrush but the cost of replacement heads adds up.
4/5
Design
Cute and attractive and will appeal to 3-7-year-olds.
4.5/5
Features
The lack of a two-minute timer and oscillating movement let the toothbrush down.
4/5
Total
A solid vibrating toothbrush with a cute aesthetic.
4/5
(Image credit: Future / Paul Hatton)Ordo Squishmallows Sonic Kids: Should I buy?Buy it if...You want an entry-level electric toothbrush
The Ordo lacks high-end features such as oscillating movement and a two-minute timer, but it is priced accordingly.
You want a cute toothbrush with replaceable heads
Most character-themed battery toothbrushes have fixed heads and are considered disposable. The Ordo, on the other hand, has replacement heads for greater longevity.
Your child has sensory sensitivities
At 18,000 vibrations per minute, this brush provides a mild, gentle hum that is perfect for children who find the toothbrushing experience overwhelming.
Don't buy if if...You want an oscillating head action
If you want a superior cleaning action, then the vibrating movement of the Ordo can't compare to oscillating alternatives.
You want a toothbrush with a charging stand
The Ordo operates with a single removable AA battery rather than an internal battery with a charging stand.
Your child needs a timer
The toothbrush won't alert your child at 30-second intervals, which means they might find it difficult to know when to move from the bottom teeth to the top teeth.
Also considerColgate Kids Battery Toothbrush
These child-themed battery toothbrushes feature small, vibrating heads and extra-soft bristles designed for kids aged 3 and up. It's worth considering that the heads are non-replaceable, which makes the whole toothbrush redundant when the bristles are past their best.
Ordo Cam Squishmallows Sonic Kids Electric Toothbrush
A more feature-rich toothbrush for children with multiple cleaning modes, 32,000 pulsations per minute, and a two-minute timer. It comes with a charger to recharge the internal battery.
How I testedMy six-year-old daughter used the Ordo Squishmallows Sonic Kids toothbrush for one month. Her normal toothbrush is an Oral-B PRO Junior Electric with an oscillating head, although she has experience of a manual toothbrush as well. Her familiarity of both of these meant she was able to compare the Ordo to both ends of the spectrum of what's available for children.
First reviewed: May 2026
I haven't always been an AirPods fangirl. In fact, in May 2021, when the company unveiled Apple Music Lossless and Hi-Res Lossless for free, as part of your Apple Music subscription, I may have come down quite hard on Apple's musical headgear — and for some time after that. Why? Because it took four more years for the Cupertino giant to work out how to get its Lossless music standard into its own flagship headphones.
Another thing that's taken Apple a very long time? Unveiling a second-generation update to said headphones. It's been five years and three months between iterations, a vast expanse of time in any area of technology, but an epoch in Bluetooth audio and among the best noise-cancelling headphones.
A happy by-product of the fact above is that it makes my delay in filing this review seem minuscule in comparison (I had a spell in hospital, but it did mean I could test the ANC in a key user-case scenario!). However, I mention the timeline mostly as a way to emphasise that based on looks alone, you'd be forgiven for thinking Apple hadn't used that huge stretch wisely. The ear cup design, webbed headband, driver array and yes, even the 'headphone bra' semi-case haven't been tweaked whatsoever for AirPods Max 2.
Did Apple simply not have the R&D budget, or did its engineers double down on their 2020 design as still being the best possible shape, construction, driver size and material for a set of cans? And why, given the glowing star-rating at the top of this review, am I still being so negative?
The answer to all of these questions is this: if you're using an iPhone 15 Pro (aka, the oldest iPhone that is still able to support Apple Intelligence) or later as a source device, AirPods Max 2 are some of the most formidable, featured and fantastic shut-the-world-out headphones I've ever tested — and I've been doing this full-time since 2019. They're doubtless the best noise-cancelling iPhone headphones on the planet.
Design-wise, there's no perceivable difference — it's all under the hoodFutureFutureFutureFutureFutureThat's enough on what Apple hasn't done with AirPods Max 2; let's talk about what has been updated. The big upgrade is the inclusion of Apple's newer H2 chip, over the H1 in the originals. Given that this is the same in-house Apple audio processor that made its debut in the September 2022 AirPods Pro 2 (and also takes the wheel in the AirPods 4, AirPods Pro 3, and original 2023-launch Apple Vision Pro), it might not seem like much of a headline grabber. But in AirPods Max it does a lot of heavy lifting.
The H2 chips — yes, you actually get one in each ear cup — add a plethora of new features, including Adaptive Audio (the Transparency mode can adjust itself to block some unnecessary sounds, and there's an optional slider to tweak just how 'adaptive' you want it to get), Conversation Awareness (so the over-ears can automatically lower the volume of your music and filter external sounds should you start talking to someone, then put everything back again once you stop yapping), plus Loud Sound Reduction and Personalized Volume to help protect your hearing but keep the sonic profile how you like it.
There's also Live Translation, which I enjoyed using here much more than on AirPods Pro 3, because it's so much easier to access via a long press of AirPods Max's on-ear Listening Mode button. The new Voice Isolation software also improves your call quality when it's loud or windy around you — and thanks to some extra processing power afforded by that H2 chip, you get much better voice capture from the headphones' three mics for voice pickup (two are shared with the ANC system, and one is an additional dedicated microphone) in the nine-mic total.
Elsewhere, Head Gestures let you nod to accept a call or check a message, shake your head to dismiss a message or decline a call, or nod to Siri silently. Also, the new Camera Remote feature means you can now take snaps on your iPhone camera using AirPods Max 2's Digital Crown.
And I left the best for last: Apple claims that the active noise cancellation is "up to 1.5x more effective than the previous generation" and when Tim Cook's behemoth states such a thing, I sit up and take notice. The noise-nixing here is next-level — and I mean near-silent, calming, cocooning and enveloping. It's like stillness as a backdrop to your music. If that's what you need, buy these headphones.
Any negatives? Two. The battery life is unchanged at 20 hours (which is easy to beat even much further down the headphone food chain), and there's still no support for wireless hi-res codecs. You can get Lossless-quality audio, but you have to use the bundled USB-C cable (or buy a USB-C to 3.5mm one, which Apple sells separately) introduced to the original AirPods Max via a software update in March 2025.
Does any of that last paragraph matter? For me, given the crispness, clarity, impact, fun, separation and sheer musicality available here, no. And I rarely say that hi-res codecs or stamina don't matter.
(Image credit: Future)Apple AirPods Max 2 review: Price and release dateThere's been a curious trend in Apple's pricing of late. The inaugural AirPods Max arrived in December 2020 with an asking price of $549 / £549 / AU$899, so, with the second-generation update priced at $549 / £499 / AU$999, Apple is keeping the US MSRP the same, giving the UK a price cut and charging The Land Down Under a little more.
The thing is, this is not a one-off. Both the first-generation AirPods Pro and the follow-up AirPods Pro 2 were priced at $249 / £249 / AU$399 when they landed, so when AirPods Pro 3 arrived with a $249 price tag, it came as no surprise to US fans. However, those newest buds were priced a little lower than before in the UK, at £219, and — at AU$429 — a little bit more in Australia. For Apple's flagship earbuds, £30 cheaper in the UK yet AU$30 more expensive in Australia felt a bit harsh.
Here, there's a £50 saving to be had if you live in Blighty, but a AU$100 increase to pay if you reside in Oz. I'm sorry. I could suggest it's down to Australian Goods and Services Taxes (GST), relative incomes, International shipping costs, or perhaps a more bijou consumer base, but all of that would be pure speculation. I just cannot make that make sense to you.
Anyway, what of direct competition at this not-insignificant level? AirPods Max 2's chief rivals are perhaps most pressingly the five-star Bose QuietComfort Ultra Headphones (2nd Gen), which hit shelves at slightly more affordable $449 / £449 / AU$699 price points, or the also five-star Bowers & Wilkins Px8 S2, which cost a fair bit more, at $799 / £629 / AU$1,299. Oh, and let's not forget the excellent Sony WH-1000XM6, which sell for $449 / £399 / AU$699.
But there's no shortage of competition at this level and – given options such as the inexpensive 4.5-star Nothing Headphone (a) with its remote camera function – at a few levels down from it too…
(Image credit: Future)Apple AirPods Max 2 review: SpecsDrivers
Apple-designed dynamic driver with new 'custom high dynamic range amplifier'
Active noise cancellation
Yes
Battery life
Up to 20 hours (with ANC enabled)
5 mins of charging nets 1.5 hours of listening
Weight
386.2g
Connectivity
Bluetooth 5.3 (H2 chip)
Waterproofing
Not rated
(Image credit: Future)Apple AirPods Max 2 review: FeaturesI've touched on a lot of great new features, so it might be worth mentioning an Apple headline grabber you won't get: heart-rate monitoring. It is available in both the flagship AirPods Pro 3 and Beats Powerbeats Pro 2, yet despite the arsenal of sensors nestled in AirPods Max 2 (an optical sensor, position sensor, accelerometer and case-detect sensor in each ear cup, plus a gyroscope in the left cup), there's no PPG infrared light sensor to measure light absorption in your blood. And because of this, Apple isn't funnelling you quite so readily towards its free Fitness app with its over-ears, or offering you a virtual trainer, however you feel about that…
You also don't get Apple's Hearing Test or Hearing Aid suite of features; the only toggles to preserve your hearing health here are Loud Sound Reduction (switch it on and provided you're listening in either Transparency or Adaptive modes, the headphones will actively reduce your exposure to loud environmental sounds) and Personalized Volume, to readily adjust the loudness of your media in response to your surroundings, but they both work well.
Now, back to what you do get, and top of the list for me personally must be Live Translation. Why? Because it can be accessed with a surreptitious long press of the listening mode button (ie. the flush pill-shaped button located on the right ear cup that isn't the digital crown). I found this a much more reliable way to start Live Translation than squeezing both stems of my AirPods Pro 3. Quick accessibility is key with these kinds of life-hack features, and on a recent trip to Girona (the Catalonian city near Barcelona where Season 6 of Game of Thrones was filmed), I found it genuinely useful, rather than a novelty to play with. Now, Girona is a Catalan-speaking city, and Catalan isn't yet one of Apple's supported Live Translation languages, but I heard a lot of Spanish too — and I also have a long-suffering life partner who speaks both languages. You can see snippets of our conversation below.
Apple AppleI've said before that this is an Apple offering you need to spend a bit of time setting up — ideally before your romantic city break — because there's a fair bit of red tape you'll need to cut through. You'll also need an iPhone 15 Pro or later running iOS 26 or later, Apple Intelligence turned on, the Translate app downloaded (and the language modules you want downloaded), plus the latest AirPods Firmware version.
I also customized the iPhone Action button on my iPhone 15 Pro Max to start Live Translation, because in the moment it can be easier to tap your phone rather than your headphones, and it's all about speed of deployment with Live Translation. Once that's done, audible English responses are piped in as your helper answers your questions, with a transcription of the information they're giving you (and your questions translated) also appearing on your iPhone's screen. OK, perhaps your helpful human will find the fact that you're not taking off your headphones to talk to them a little rude, but it works beautifully and with very little lag.
Now to the other new features and claimed upticks in performance, all of which can be found, controlled, toggled and customized with a tap of the AirPods Max bubble near the top of the settings tab, or by swiping down from the top-right of your screen, to get the Control Center. Your listening modes include Off, Transparency (which works and without making music tinny, but there's no slider), Adaptive (which does have a slider, to allow more or less noise into your cans, albeit dynamically and in response to noises the headphones pick up around you) or Noise Cancellation (no slider, but it's excellent).
For me, the right way to go about this in most situations is to deploy both Noise Cancellation and the Conversation Awareness toggle, a little further down in that menu. This means that, by default, you're not being bothered, but when you speak up, music is automatically lowered and external noises are piped in as you need them. It's not that Adaptive Audio is bad, because it's not; I simply found that when using the Adaptive Audio profile I'd keep setting the slider right down to allow for fewer distractions, but if you don't have the luxury of blocking out the world in your working day, Adaptive will serve you well.
If you take just one thing away from this review, let it be that the noise-cancelling power in AirPods Max 2 really is 1.5 times better than before. It's fabulous; almost wickedly good at inhaling the noise from your ears, but without the vacuum effect I often find nauseating in rival cans (the few that offer ANC anywhere near this good, anyway).
Call handling is excellent; callers said my voice was remarkably clear, even on a windy UK seafront in Dorset. Gesture Control is also good provided you're relatively animated with your nods or head shakes, and the Camera Remote feature is a neat way to make photo capture easier on your iPhone. As with Conversation Awareness, it just makes for a simpler life when it comes to wearing headphones.
I've spent enough time on how good the noise cancellation is, right? OK, so let's move on to the joys of head-tracked Spatial Audio. It's not a new feature with this iteration, but it is so beautifully implemented here you'll find yourself whipping them off to check there's no mini speaker under your chin or squirrelled away at the back of the room. Better than the original AirPods Max? Yes. It's likely due to the new amplifier under the hood plus the processing power of the H2 chipset, but it's cleaner all round — and I did listen in direct comparison.
My favorite home cinema setup is now an iPad and the AirPods Max 2 with head-tracked Spatial Audio engaged. If you're not so sure, try watching the opening scene of Alfonso Cuarón’s 2013 movie Gravity (it's a known test these days, but still). See?
When listening to music, you can expect an expansive, meticulously unfurled soundstage with a noise floor so low that bass frequencies rumble, snap and boom in so much space it's almost a crime. Fontaines D.C.'s I Love You is brooding through the intro and able to celebrate the juicy depth of Grian Chatten's vocals as well as I've heard in any wireless headphones. My Chatten playlist continues with The Score. Its textured acoustic guitar intro brushes each of my ears in turn before expanding yet further to let the vocal drop centrally. Add the USB-C cable to listen in Lossless on Apple Music and it's even better.
Timing, too, is exceptional. I dare you to stream Bad Bunny's Tití Me Preguntó and sit still. It's raucous, defiant, joyous and, in these headphones, it's why I love music.
For crisp leading edges of notes and an extra ounce of detail (again, we come to that 'integrated hi-fi versus fun' debate), you'll get just a little more insight and honesty from the Bowers & Wilkins Px8 S2, but those headphones are pricier and for me, AirPods Pro 2's Spatial Audio knocks B&W's True Immersion solution clean out the water, with the latter coming off veiled and almost muffled in direct comparison.
Ask yourself this: do you want your music to feel emotional, zealous and fun — a more V-shaped presentation where upper mids (ie. vocals) and feels through the bass dart betwixt each ear? Or do you want a faithful, neutral stereo performance that leaves nothing out of the mix? Your answer is important because if you pick the first option, you own an iPhone and you can afford these headphones, I know you won't be disappointed.
As I've already mentioned and pictured, AirPods Max 2's appearance and indeed innards (save for a new chip and amplification module) remain largely unchanged. If you hoped Apple would completely overhaul the design, you'll doubtless feel wronged. But I maintain that the headband here is the most comfortable I've ever worn, and the metallic yokes are the most reliable and silent. I wear headphones almost constantly, but I also suffer from migraines, so a headband digging into the crown of my head doesn't help the pain in my noggin one bit. No such issue here, ever, and for me that's priceless. What I'm saying is, I think Apple found the fix here and I wouldn't want them to try again and alter it.
The ear cups are quite wide and extremely long, but they aren't especially deep, unlike the audiophile-grade options I've tried that felt like long lenses strapped across my head. An IP rating would be a plus, as would an actual case rather than the headphone bra Apple has stuck with (see the new Sony 1000X The Collexion for a novel idea that still actually protects your expensive headphones, Apple), but the build quality is resoundingly premium. All the more reason to want to protect it…
My main gripe here concerns the battery life. At 20 hours (albeit with ANC deployed), Apple is being left behind. We recently knocked the Sony 1000X for a lack of stamina, even with 24 hours in ANC mode, but you'll get 30 hours from the B&W Px8 S2 with noise cancellation on. And these options aren't class leaders — Cambridge's Melomania P100 (a fantastic set of cans) will go for 60 hours with ANC on.
And I have one other bugbear. In AirPods Pro 3, I suggested a dedicated iOS app might be necessary now, because of the additional Hearing Health suite (hearing tests, hearing aid functionality and virtual trainer perks), heart-rate monitor, and the fact that on-ear controls on an earbud are more fiddly than they are on an ear cup. Here, I think the in-iPhone solution suffices, but I'd like an audio handoff feature that works with Apple Music.
To be clear, I don't mean a cross-device feature to resume playback on another Apple device when I walk through the door, as pioneered by Bowers & Wilkins between its wireless headphones and wireless speakers (not too many of us still use HomePods or HomePod minis, I imagine), or true multipoint connectivity — if you're using the same Apple ID, your AirPods Max 2 will happily dart between your iPhone, Mac or iPad using its own Automatic Device Switching solution. No, I simply want to be able to seamlessly switch from streaming Apple Music on my iPhone to streaming Apple Music on my MacBook. I want to pause a song on my phone, sit at my MacBook Pro, open the Music app, and continue listening to the same track, or playlist. It's odd that this still isn't happening — but this is a review about AirPods Max 2, not the Apple Music user experience.
Here's the issue: people buy with their eyes first, then their wallets. And in one sense, there's nothing new to see here — buy the newest AirPods Max and few people will be able to tell if you just bought the older, heavily discounted set or the brand new H2-toting pair. My Orange review sample is one of the new Max 2-only colorways, but with so many bright finishes available (and oddly, none of them correspond with Apple's latest MacBook Neo colorways), it's hard to keep tabs on what's new and what's not.
It's unfortunate, because having tested them for over two months now, I can tell you that AirPods Max 2 are much better sonically than the originals. The ANC is as good as Apple claims it is, and they boast a greatly improved user experience to boot. But you'd never be able to tell that by looking at them, and when the model they look just like came out in late 2020, that could present a problem in terms of perceived value.
Excellent sound and ANC; lacklustre stamina
Features 4.5 Sound Quality 5 Design 4.5 Battery Life 3 Noise Cancellation 5 Value 4 Overall 4.5 01.534.56 Group 1 Data ProductFeatures ()Sound Quality ()Design ()Battery Life ()Noise Cancellation ()Value ()Overall () AirPods Max 24.554.53544.5 window.iFrameResizer = { heightCalculationMethod: 'taggedElement' }; (function() { /* Global animation function for slideshow re-use */ window.fvAnimateCharts = function(chartWrapper) { if (!chartWrapper) return; function animateBars(chartElement) { if (!chartElement) return; var bars = chartElement.querySelectorAll('.fv-bar, .fv-stacked-segment'); bars.forEach(function(bar, index) { /* Reset to 0 first to ensure animation triggers */ bar.style.setProperty('width', '0%', 'important'); bar.style.setProperty('transition', 'none', 'important'); var targetWidth = bar.dataset.targetWidth; if (targetWidth === undefined) return; /* Force reflow */ void bar.offsetWidth; var targetMargin = bar.dataset.targetMargin; var baseMargin = bar.dataset.baseMargin; if (baseMargin !== undefined) { bar.style.setProperty('margin-left', baseMargin + '%', 'important'); } setTimeout(function() { var marginTransition = baseMargin !== undefined ? ', margin-left 0.8s ease-out' : ''; bar.style.setProperty('transition', 'opacity 0.2s ease, width 0.8s ease-out' + marginTransition, 'important'); bar.style.setProperty('width', targetWidth + '%', 'important'); if (targetMargin !== undefined && baseMargin !== undefined) { bar.style.setProperty('margin-left', targetMargin + '%', 'important'); } }, index * 50 + 50); /* Reduced initial delay */ }); } function animateLineChart(chartElement) { if (!chartElement) return; var lineSvg = chartElement.querySelector('svg'); if (!lineSvg) return; var paths = lineSvg.querySelectorAll('.riv-line-path'); paths.forEach(function(p, i) { if (typeof p.getTotalLength === 'function') { var len = p.getTotalLength(); p.style.transition = 'none'; p.style.strokeDasharray = len; p.style.strokeDashoffset = len; p.getBoundingClientRect(); setTimeout(function() { p.style.transition = 'stroke-dashoffset 1s ease-out ' + (i * 0.1) + 's, stroke-width 0.2s, opacity 0.2s'; p.style.strokeDashoffset = '0'; }, 100); } }); var dots = lineSvg.querySelectorAll('.riv-dot'); dots.forEach(function(dot, i) { dot.style.opacity = '0'; setTimeout(function() { dot.style.transition = 'opacity 0.3s ease'; dot.style.opacity = '1'; }, 500 + i * 10); }); } /* Execute */ var charts = chartWrapper.querySelectorAll('.fv-chart-item'); charts.forEach(function(chart) { /* If in carousel/dropdown mode, hidden charts are display:none. */ /* We only animate what is visible. */ if (window.getComputedStyle(chart).display === 'none') return; var chartType = chart.dataset.chartType; if (chartType === 'Line') { animateLineChart(chart); } else if (chartType !== 'Pie') { animateBars(chart); } }); }; function initialize(uniqueId, isSlideshow) { var root = document.getElementById(uniqueId); /* In slideshow mode, 'root' will be null because the container has '-slideshow' suffix. */ /* We handle that logic below. */ if (!root && !isSlideshow) return; /* Setup internal interactions (Carousel/Dropdown/LineChart) for a specific chart wrapper */ function setupWrapper(chartWrapper) { if (!chartWrapper) return; /* Responsive mobile view handling */ function checkMobileView() { var width = chartWrapper.getBoundingClientRect().width; var isMobileDevice = window.screen && Math.min(window.screen.width, window.screen.height) <= 599; var isMobile; if (width === 0) { /* Fallback for when width isn't available yet (e.g., hidden tab) */ isMobile = isMobileDevice || window.matchMedia('(max-width: 599px)').matches; } else { /* Mobile if container is small OR if it's a physical mobile device (overriding fixed-width iframes) */ isMobile = isMobileDevice || width < 600; } if (isMobile) { chartWrapper.classList.add('mobile-view'); } else { chartWrapper.classList.remove('mobile-view'); } } /* Initial check */ checkMobileView(); if (typeof ResizeObserver !== 'undefined') { var ro = new ResizeObserver(function() { checkMobileView(); }); ro.observe(chartWrapper); } /* Always add window resize listener as a reliable fallback for DevTools and edge cases */ window.addEventListener('resize', checkMobileView); /* Labels on top handler */ var labelsOnTop = chartWrapper.dataset.barLabelsOnTop === 'true'; if (labelsOnTop) { /* If there are multiple charts and we're not in a carousel/dropdown, we might have mixed types. */ /* But typically, labels-on-top is a global setting. We'll apply it initially, */ /* and showInternalChart will toggle it if needed. */ var charts = chartWrapper.querySelectorAll('.fv-chart-item'); var hasVisibleBarChart = false; charts.forEach(function(c) { if (window.getComputedStyle(c).display !== 'none') { var cType = c.dataset.chartType; if (cType === 'Bar' || cType === 'Stacked Bar' || cType === 'Versus') { hasVisibleBarChart = true; } } }); if (hasVisibleBarChart) { chartWrapper.classList.add('labels-on-top'); } else { chartWrapper.classList.remove('labels-on-top'); } } else { chartWrapper.classList.remove('labels-on-top'); } /* Legend interactions */ chartWrapper.querySelectorAll('.riv-line-legend').forEach(function(legend) { var chartId = legend.dataset.chart; var chart = chartWrapper.querySelector('[id="' + chartId + '"]'); if (!chart) return; var lines = chart.querySelectorAll('.riv-line-path'); var dots = chart.querySelectorAll('.riv-dot'); var legendItems = legend.querySelectorAll('.riv-legend-item'); legendItems.forEach(function(item) { var productName = item.dataset.product; var safeProductName = productName.replace(/"/g, '\"'); var line = chart.querySelector('.riv-line-path[data-product="' + safeProductName + '"]'); var productDots = chart.querySelectorAll('.riv-dot[data-product="' + safeProductName + '"]'); if (line && !line.dataset.origStroke) { line.dataset.origStroke = line.getAttribute('stroke-width') || '2'; } var highlight = function() { if (legend.querySelector('.isolated')) return; lines.forEach(function(l) { l.style.opacity = '0.2'; l.setAttribute('stroke-width', l.dataset.origStroke); }); dots.forEach(function(d) { d.style.opacity = '0.2'; }); legendItems.forEach(function(i) { i.style.opacity = '0.3'; i.style.transition = 'opacity 0.2s'; }); if (line) { line.style.opacity = '1'; line.setAttribute('stroke-width', '4'); } productDots.forEach(function(d) { d.style.opacity = '1'; }); item.style.opacity = '1'; }; var clearHighlight = function() { if (legend.querySelector('.isolated')) return; lines.forEach(function(l) { l.style.opacity = '1'; l.setAttribute('stroke-width', l.dataset.origStroke); }); dots.forEach(function(d) { d.style.opacity = '1'; }); legendItems.forEach(function(i) { i.style.opacity = '1'; }); }; var toggleIsolate = function() { var isIsolated = item.classList.contains('isolated'); legendItems.forEach(function(i) { i.classList.remove('isolated'); }); if (isIsolated) { lines.forEach(function(l) { l.style.opacity = '1'; l.setAttribute('stroke-width', l.dataset.origStroke); }); dots.forEach(function(d) { d.style.opacity = '1'; }); legendItems.forEach(function(i) { i.style.opacity = '1'; }); } else { item.classList.add('isolated'); lines.forEach(function(l) { l.style.opacity = '0.2'; l.setAttribute('stroke-width', l.dataset.origStroke); }); dots.forEach(function(d) { d.style.opacity = '0.2'; }); legendItems.forEach(function(i) { i.style.opacity = '0.3'; i.style.transition = 'opacity 0.2s'; }); if (line) { line.style.opacity = '1'; line.setAttribute('stroke-width', '4'); } productDots.forEach(function(d) { d.style.opacity = '1'; }); item.style.opacity = '1'; } }; item.addEventListener('mouseenter', highlight); item.addEventListener('focus', highlight); item.addEventListener('mouseleave', clearHighlight); item.addEventListener('blur', clearHighlight); item.addEventListener('click', toggleIsolate); if (line) { line.style.cursor = 'pointer'; line.addEventListener('mouseenter', highlight); line.addEventListener('mouseleave', clearHighlight); line.addEventListener('click', toggleIsolate); } }); }); /* Versus Chart Logic */ var versusCharts = chartWrapper.querySelectorAll('.fv-versus-chart'); versusCharts.forEach(function(vc) { var dataJson = vc.getAttribute('data-versus-data'); var leftColor = vc.getAttribute('data-left-color') || '#E53935'; var rightColor = vc.getAttribute('data-right-color') || '#FFB300'; if (!dataJson) return; var versusData = JSON.parse(dataJson); var leftSelect = vc.querySelector('.fv-select-left'); var rightSelect = vc.querySelector('.fv-select-right'); var rows = vc.querySelectorAll('.fv-versus-row'); function updateVersusChart() { var leftProduct = leftSelect.value; var rightProduct = rightSelect.value; leftSelect.style.color = leftColor; leftSelect.style.borderColor = leftColor; rightSelect.style.color = rightColor; rightSelect.style.borderColor = rightColor; rows.forEach(function(row) { var index = parseInt(row.getAttribute('data-index')); var data = versusData[index]; if (!data) return; var leftVal = data.productData[leftProduct] ? data.productData[leftProduct].value : undefined; var rightVal = data.productData[rightProduct] ? data.productData[rightProduct].value : undefined; var leftIsNum = typeof leftVal === 'number'; var rightIsNum = typeof rightVal === 'number'; var leftNum = leftIsNum ? leftVal : 0; var rightNum = rightIsNum ? rightVal : 0; var maxVal = Math.max(leftNum, rightNum, 0.0001); var leftWidth = leftIsNum ? (leftNum / maxVal) * 95 : 0; var rightWidth = rightIsNum ? (rightNum / maxVal) * 85 : 0; var winner = null; var pctDiffStr = null; if (leftIsNum && rightIsNum) { if (leftNum > rightNum) { winner = 'left'; if (rightNum > 0) { var diff = Math.round(((leftNum - rightNum) / rightNum) * 100); pctDiffStr = '+' + diff.toLocaleString() + '%'; } } else if (rightNum > leftNum) { winner = 'right'; if (leftNum > 0) { var diff = Math.round(((rightNum - leftNum) / leftNum) * 100); pctDiffStr = '+' + diff.toLocaleString() + '%'; } } } var leftDisplay = data.productData[leftProduct] && data.productData[leftProduct].displayValue !== undefined ? data.productData[leftProduct].displayValue : (leftIsNum ? leftNum.toLocaleString() : (leftVal !== undefined ? leftVal : '-')); var rightDisplay = data.productData[rightProduct] && data.productData[rightProduct].displayValue !== undefined ? data.productData[rightProduct].displayValue : (rightIsNum ? rightNum.toLocaleString() : (rightVal !== undefined ? rightVal : '-')); var unit = (data.productData[leftProduct] && data.productData[leftProduct].unit) || (data.productData[rightProduct] && data.productData[rightProduct].unit) || ''; var leftTextStr = leftDisplay; var rightTextStr = rightDisplay; var leftBar = row.querySelector('.fv-versus-bar-left'); var rightBar = row.querySelector('.fv-versus-bar-right'); var leftText = row.querySelector('.fv-inside-left'); var rightText = row.querySelector('.fv-inside-right'); var labelText = row.querySelector('.fv-versus-label span'); var leftWrapper = row.querySelector('.fv-versus-bar-left-wrapper'); var rightWrapper = row.querySelector('.fv-versus-bar-right-wrapper'); var existingPctDiffs = row.querySelectorAll('.fv-versus-pct-diff'); existingPctDiffs.forEach(function(el) { el.remove(); }); if (winner === 'left' && pctDiffStr) { var pctSpan = document.createElement('span'); pctSpan.className = 'fv-versus-pct-diff'; pctSpan.style.color = 'rgba(255, 255, 255, 0.9)'; pctSpan.textContent = pctDiffStr; if (leftBar) leftBar.insertBefore(pctSpan, leftBar.firstChild); } else if (winner === 'right' && pctDiffStr) { var pctSpan = document.createElement('span'); pctSpan.className = 'fv-versus-pct-diff'; pctSpan.style.color = 'rgba(255, 255, 255, 0.9)'; pctSpan.textContent = pctDiffStr; if (rightBar) rightBar.appendChild(pctSpan); } if (leftBar) { leftBar.style.backgroundColor = leftColor; leftBar.dataset.targetWidth = leftWidth; leftBar.style.setProperty('--target-width', leftWidth + '%'); leftBar.style.width = leftWidth + '%'; } if (rightBar) { rightBar.style.backgroundColor = rightColor; rightBar.dataset.targetWidth = rightWidth; rightBar.style.setProperty('--target-width', rightWidth + '%'); rightBar.style.width = rightWidth + '%'; } if (leftText) { leftText.innerHTML = leftTextStr; } if (rightText) { rightText.innerHTML = rightTextStr; } if (labelText) { labelText.textContent = data.attribute + (unit ? ' (' + unit + ')' : ''); } }); } if (leftSelect) leftSelect.addEventListener('change', updateVersusChart); if (rightSelect) rightSelect.addEventListener('change', updateVersusChart); }); /* Carousel & Dropdown Logic */ var charts = chartWrapper.querySelectorAll('.fv-chart-item'); var dropdown = chartWrapper.querySelector('.fv-dropdown-title'); var prevBtn = chartWrapper.querySelector('.fv-carousel-nav-btn.prev'); var nextBtn = chartWrapper.querySelector('.fv-carousel-nav-btn.next'); var carouselTitle = chartWrapper.querySelector('.fv-carousel-title-controls .fv-benchmark-title'); var counter = chartWrapper.querySelector('.fv-carousel-counter'); /* Text Elements */ var subheadEl = chartWrapper.querySelector('.fv-chart-subhead'); var captionEl = chartWrapper.querySelector('.rv-chart-caption'); var footerContentEl = chartWrapper.querySelector('.fv-footer-content'); var bottomBarEl = chartWrapper.querySelector('.fv-bottom-bar'); var logoEl = chartWrapper.querySelector('.fv-logo'); if (charts.length > 1 && (dropdown || prevBtn)) { var currentChartIndex = 0; var titles = []; if (dropdown) { titles = Array.from(dropdown.options).map(function(o) { return o.text; }); } else { charts.forEach(function(c) { titles.push(c.getAttribute('data-title') || ''); }); } function showInternalChart(index) { if (index < 0) index = charts.length - 1; if (index >= charts.length) index = 0; currentChartIndex = index; charts.forEach(function(c, i) { c.style.display = i === index ? 'block' : 'none'; if (i === index) { var cType = c.dataset.chartType; if (cType === 'Line') { /* Line chart animations if needed */ } else if (cType !== 'Pie') { window.fvAnimateCharts(chartWrapper); } /* Update labels-on-top based on current chart type */ var labelsOnTop = chartWrapper.dataset.barLabelsOnTop === 'true'; if (labelsOnTop && (cType === 'Bar' || cType === 'Stacked Bar' || cType === 'Versus')) { chartWrapper.classList.add('labels-on-top'); } else { chartWrapper.classList.remove('labels-on-top'); } } }); if (dropdown) dropdown.value = index; if (carouselTitle && titles[index]) carouselTitle.textContent = titles[index]; if (counter) counter.textContent = (index + 1) + ' of ' + charts.length; /* Update Subhead and Caption */ var activeChart = charts[index]; if (activeChart) { var newSubhead = activeChart.getAttribute('data-subhead'); var newCaption = activeChart.getAttribute('data-caption'); var currentChartType = activeChart.getAttribute('data-chart-type'); var hideGlobalCaption = currentChartType === 'Countdown' || currentChartType === 'Image Comparison' || currentChartType === 'Shop the Collection'; if (subheadEl) subheadEl.textContent = newSubhead || ''; if (captionEl) captionEl.textContent = newCaption || ''; if (footerContentEl) { if (newCaption && newCaption.trim().length > 0 && !hideGlobalCaption) { footerContentEl.style.display = 'block'; if (bottomBarEl) bottomBarEl.style.display = 'flex'; } else { footerContentEl.style.display = 'none'; if (bottomBarEl && !logoEl) { bottomBarEl.style.display = 'none'; } } } } } if (dropdown) dropdown.addEventListener('change', function(e) { showInternalChart(parseInt(e.target.value)); }); if (prevBtn) prevBtn.addEventListener('click', function() { showInternalChart(currentChartIndex - 1); }); if (nextBtn) nextBtn.addEventListener('click', function() { showInternalChart(currentChartIndex + 1); }); } /* Image Comparison Logic */ var imageCompareWrappers = chartWrapper.querySelectorAll('.fv-image-compare-wrapper'); imageCompareWrappers.forEach(function(wrapper) { var inner = wrapper.querySelector('.fv-image-compare-inner') || wrapper; var slider = wrapper.querySelector('.fv-image-compare-slider'); var fgImage = wrapper.querySelector('.fv-image-compare-fg'); var bgImage = wrapper.querySelector('.fv-image-compare-bg'); var labelLeft = wrapper.querySelector('.fv-image-compare-label-left'); var labelRight = wrapper.querySelector('.fv-image-compare-label-right'); var isDragging = false; /* Zoom state */ var scale = 1; var panX = 0; var panY = 0; var isPanning = false; var hasPanned = false; var lastClientX = 0; var lastClientY = 0; var initialDistance = null; var lastCenterX = null; var lastCenterY = null; function updateTransform() { if (wrapper.classList.contains('fv-image-compare-fullscreen')) { inner.style.setProperty('transform', 'translate(' + panX + 'px, ' + panY + 'px) scale(' + scale + ')', 'important'); } else { inner.style.removeProperty('transform'); scale = 1; panX = 0; panY = 0; } } function constrainPan() { var rect = wrapper.getBoundingClientRect(); /* Max pan depends on how much the image is scaled beyond the wrapper */ var maxPanX = Math.max(0, (rect.width * scale - rect.width) / 2); var maxPanY = Math.max(0, (rect.height * scale - rect.height) / 2); panX = Math.max(-maxPanX, Math.min(panX, maxPanX)); panY = Math.max(-maxPanY, Math.min(panY, maxPanY)); } wrapper.addEventListener('wheel', function(e) { if (!wrapper.classList.contains('fv-image-compare-fullscreen')) return; e.preventDefault(); var zoomSensitivity = 0.005; var zoomFactor = Math.exp(-e.deltaY * zoomSensitivity); var newScale = Math.max(1, Math.min(scale * zoomFactor, 5)); if (newScale === scale) return; var rect = wrapper.getBoundingClientRect(); var mouseX = e.clientX - rect.left - rect.width / 2; var mouseY = e.clientY - rect.top - rect.height / 2; var ratio = newScale / scale; panX = mouseX - (mouseX - panX) * ratio; panY = mouseY - (mouseY - panY) * ratio; scale = newScale; constrainPan(); updateTransform(); }, { passive: false }); wrapper.addEventListener('mousedown', function(e) { if (!wrapper.classList.contains('fv-image-compare-fullscreen') || scale <= 1) return; if (e.target.closest('.fv-image-compare-slider') || e.target.closest('button')) return; isPanning = true; hasPanned = false; lastClientX = e.clientX; lastClientY = e.clientY; }); window.addEventListener('mousemove', function(e) { if (!isPanning) return; var dx = e.clientX - lastClientX; var dy = e.clientY - lastClientY; if (Math.abs(dx) > 2 || Math.abs(dy) > 2) { hasPanned = true; } lastClientX = e.clientX; lastClientY = e.clientY; panX += dx; panY += dy; constrainPan(); updateTransform(); }); window.addEventListener('mouseup', function() { isPanning = false; }); wrapper.addEventListener('touchstart', function(e) { if (!wrapper.classList.contains('fv-image-compare-fullscreen')) return; if (e.touches.length === 2) { e.preventDefault(); var dx = e.touches[0].clientX - e.touches[1].clientX; var dy = e.touches[0].clientY - e.touches[1].clientY; initialDistance = Math.sqrt(dx * dx + dy * dy); var rect = wrapper.getBoundingClientRect(); lastCenterX = (e.touches[0].clientX + e.touches[1].clientX) / 2 - rect.left - rect.width / 2; lastCenterY = (e.touches[0].clientY + e.touches[1].clientY) / 2 - rect.top - rect.height / 2; hasPanned = true; /* Prevent click after pinch */ } else if (e.touches.length === 1 && scale > 1) { if (e.target.closest('.fv-image-compare-slider') || e.target.closest('button')) return; isPanning = true; hasPanned = false; lastClientX = e.touches[0].clientX; lastClientY = e.touches[0].clientY; } }, { passive: false }); wrapper.addEventListener('touchmove', function(e) { if (!wrapper.classList.contains('fv-image-compare-fullscreen')) return; if (e.touches.length === 2 && initialDistance !== null) { e.preventDefault(); var dx = e.touches[0].clientX - e.touches[1].clientX; var dy = e.touches[0].clientY - e.touches[1].clientY; var distance = Math.sqrt(dx * dx + dy * dy); if (initialDistance > 0) { var zoomFactor = distance / initialDistance; var newScale = Math.max(1, Math.min(scale * zoomFactor, 5)); var rect = wrapper.getBoundingClientRect(); var centerX = (e.touches[0].clientX + e.touches[1].clientX) / 2 - rect.left - rect.width / 2; var centerY = (e.touches[0].clientY + e.touches[1].clientY) / 2 - rect.top - rect.height / 2; var ratio = newScale / scale; panX = centerX - (centerX - panX) * ratio; panY = centerY - (centerY - panY) * ratio; if (lastCenterX !== null && lastCenterY !== null) { panX += (centerX - lastCenterX); panY += (centerY - lastCenterY); } scale = newScale; lastCenterX = centerX; lastCenterY = centerY; constrainPan(); updateTransform(); } initialDistance = distance; } else if (e.touches.length === 1 && isPanning) { e.preventDefault(); var dx = e.touches[0].clientX - lastClientX; var dy = e.touches[0].clientY - lastClientY; if (Math.abs(dx) > 2 || Math.abs(dy) > 2) { hasPanned = true; } lastClientX = e.touches[0].clientX; lastClientY = e.touches[0].clientY; panX += dx; panY += dy; constrainPan(); updateTransform(); } }, { passive: false }); wrapper.addEventListener('touchend', function(e) { if (e.touches.length < 2) { initialDistance = null; } if (e.touches.length === 0) { isPanning = false; } }); function handleMove(clientX) { var rect = inner.getBoundingClientRect(); var x = Math.max(0, Math.min(clientX - rect.left, rect.width)); var percent = Math.max(0, Math.min((x / rect.width) * 100, 100)); if (slider) slider.style.setProperty('left', percent + '%', 'important'); if (fgImage) fgImage.style.setProperty('clip-path', 'polygon(0 0, ' + percent + '% 0, ' + percent + '% 100%, 0 100%)', 'important'); if (labelLeft) { if (percent < 10) { labelLeft.style.setProperty('opacity', '0', 'important'); } else { labelLeft.style.setProperty('opacity', '1', 'important'); } } if (labelRight) { if (percent > 90) { labelRight.style.setProperty('opacity', '0', 'important'); } else { labelRight.style.setProperty('opacity', '1', 'important'); } } } function onMouseMove(e) { if (!isDragging) return; handleMove(e.clientX); } function onTouchMove(e) { if (!isDragging) return; e.preventDefault(); handleMove(e.touches[0].clientX); } function stopDragging() { isDragging = false; window.removeEventListener('mousemove', onMouseMove); window.removeEventListener('mouseup', stopDragging); window.removeEventListener('touchmove', onTouchMove); window.removeEventListener('touchend', stopDragging); } if (slider) { var startDrag = function(clientX) { isDragging = true; handleMove(clientX); window.addEventListener('mousemove', onMouseMove); window.addEventListener('mouseup', stopDragging); }; var startTouchDrag = function(clientX) { isDragging = true; handleMove(clientX); window.addEventListener('touchmove', onTouchMove, { passive: false }); window.addEventListener('touchend', stopDragging); }; slider.addEventListener('mousedown', function(e) { e.preventDefault(); startDrag(e.clientX); }); slider.addEventListener('touchstart', function(e) { e.preventDefault(); startTouchDrag(e.touches[0].clientX); }, { passive: false }); } /* Expand/Close Logic */ var expandBtn = wrapper.querySelector('.fv-image-compare-expand-btn'); var closeBtn = wrapper.querySelector('.fv-image-compare-close-btn'); if (expandBtn) { if (window !== window.parent) { expandBtn.style.display = 'none'; } else { expandBtn.addEventListener('click', function(e) { /* e.preventDefault(); // Removed to allow text selection */ e.stopPropagation(); wrapper.classList.add('fv-image-compare-fullscreen'); document.body.style.overflow = 'hidden'; /* Load high-res images if available */ if (fgImage && fgImage.dataset.highresSrc) { fgImage.src = fgImage.dataset.highresSrc; fgImage.removeAttribute('srcset'); fgImage.removeAttribute('sizes'); } if (bgImage && bgImage.dataset.highresSrc) { bgImage.src = bgImage.dataset.highresSrc; bgImage.removeAttribute('srcset'); bgImage.removeAttribute('sizes'); } }); } } if (closeBtn) { closeBtn.addEventListener('click', function(e) { /* e.preventDefault(); // Removed to allow text selection */ e.stopPropagation(); wrapper.classList.remove('fv-image-compare-fullscreen'); document.body.style.overflow = ''; updateTransform(); }); } /* Close on Escape */ document.addEventListener('keydown', function(e) { if (e.key === 'Escape' && wrapper.classList.contains('fv-image-compare-fullscreen')) { wrapper.classList.remove('fv-image-compare-fullscreen'); document.body.style.overflow = ''; updateTransform(); } }); }); /* Shop The Look Hotspots */ var hotspots = chartWrapper.querySelectorAll('.fv-stl-hotspot-btn'); var allProductsModal = chartWrapper.querySelector('.fv-stl-all-products-modal'); var shopAllBtn = chartWrapper.querySelector('.fv-stl-shop-all-btn'); var allProductsList = chartWrapper.querySelector('.fv-stl-all-products-list'); var stlContainer = chartWrapper.querySelector('.fv-stl-container'); function closeAllModals() { if (allProductsModal) { allProductsModal.classList.remove('is-active'); /* Remove highlights */ var items = allProductsModal.querySelectorAll('.fv-stl-all-products-item'); items.forEach(function(item) { item.classList.remove('is-highlighted'); }); /* Remove min-height after transition */ if (stlContainer) { setTimeout(function() { if (!allProductsModal.classList.contains('is-active')) { stlContainer.style.minHeight = ''; if ('parentIFrame' in window) { window.parentIFrame.size(); } } }, 300); } } hotspots.forEach(function(btn) { btn.setAttribute('aria-expanded', 'false'); }); if ('parentIFrame' in window) { window.parentIFrame.size(); } } hotspots.forEach(function(btn) { btn.addEventListener('click', function(e) { e.stopPropagation(); var hotspotId = btn.getAttribute('data-hotspot-id'); var isExpanded = btn.getAttribute('aria-expanded') === 'true'; closeAllModals(); if (!isExpanded && allProductsModal) { btn.setAttribute('aria-expanded', 'true'); allProductsModal.classList.add('is-active'); /* Ensure container is tall enough */ var container = btn.closest('.fv-stl-container'); if (container && container.offsetHeight < 450) { container.style.minHeight = '450px'; } /* Highlight and scroll to item */ var targetItem = allProductsModal.querySelector('.fv-stl-all-products-item[data-product-id="' + hotspotId + '"]'); if (targetItem) { targetItem.classList.add('is-highlighted'); setTimeout(function() { targetItem.scrollIntoView({ behavior: 'smooth', block: 'center' }); }, 100); } if ('parentIFrame' in window) { window.parentIFrame.size(); } } }); }); /* Shop All button */ if (shopAllBtn && allProductsModal) { shopAllBtn.addEventListener('click', function(e) { e.stopPropagation(); closeAllModals(); allProductsModal.classList.add('is-active'); /* Ensure container is tall enough */ var container = shopAllBtn.closest('.fv-stl-container'); if (container && container.offsetHeight < 450) { container.style.minHeight = '450px'; } if ('parentIFrame' in window) { window.parentIFrame.size(); } }); } /* Close button in all products modal */ if (allProductsModal) { var closeAllBtn = allProductsModal.querySelector('.fv-stl-all-products-close'); if (closeAllBtn) { closeAllBtn.addEventListener('click', function(e) { e.stopPropagation(); closeAllModals(); }); } } /* Close modals when clicking outside */ chartWrapper.addEventListener('click', function(e) { /* Only close if clicking on the wrapper or container, not inside a modal content */ if (!e.target.closest('.fv-stl-all-products-content')) { closeAllModals(); } }); if (allProductsModal) { allProductsModal.addEventListener('click', function(e) { if (!e.target.closest('.fv-stl-all-products-content')) { closeAllModals(); } }); } /* Image Annotation Logic */ var iaNodes = chartWrapper.querySelectorAll('.fv-ia-node-button'); var iaWrapper = chartWrapper.querySelector('.fv-ia-wrapper'); var originalCaption = chartWrapper.querySelector('.fv-original-caption') || captionEl; var dynamicCaption = chartWrapper.querySelector('.fv-ia-dynamic-caption'); var exploreBtn = chartWrapper.querySelector('.fv-ia-explore-btn'); var currentIaIndex = -1; function closeAllIANodes() { iaNodes.forEach(function(btn) { btn.classList.remove('is-active'); }); if (originalCaption) originalCaption.style.display = 'block'; if (dynamicCaption) dynamicCaption.style.display = 'none'; } function resetExploreBtn() { currentIaIndex = -1; if (exploreBtn) { var exploreSpan = exploreBtn.querySelector('span'); if (exploreSpan) exploreSpan.textContent = 'Explore'; } } iaNodes.forEach(function(btn, index) { btn.addEventListener('click', function(e) { e.stopPropagation(); var isActive = btn.classList.contains('is-active'); closeAllIANodes(); if (!isActive) { currentIaIndex = index; if (exploreBtn) { var exploreSpan = exploreBtn.querySelector('span'); if (exploreSpan) exploreSpan.textContent = 'Next'; } btn.classList.add('is-active'); if (dynamicCaption) { var title = btn.getAttribute('data-title') || ''; var desc = btn.getAttribute('data-desc') || ''; dynamicCaption.innerHTML = ''; var strongTag = document.createElement('strong'); strongTag.textContent = title; dynamicCaption.appendChild(strongTag); if (desc) { dynamicCaption.appendChild(document.createTextNode(' - ' + desc)); } if (originalCaption) originalCaption.style.display = 'none'; dynamicCaption.style.display = 'block'; if (footerContentEl) footerContentEl.style.display = 'block'; } } else { resetExploreBtn(); } }); }); if (exploreBtn) { exploreBtn.addEventListener('click', function(e) { e.stopPropagation(); if (iaNodes.length === 0) return; var nextIndex = currentIaIndex + 1; if (nextIndex >= iaNodes.length) { closeAllIANodes(); resetExploreBtn(); } else { currentIaIndex = nextIndex; var targetBtn = iaNodes[currentIaIndex]; if (targetBtn) { if(targetBtn.classList.contains('is-active')) { targetBtn.click(); } targetBtn.click(); } } }); } if (iaWrapper) { iaWrapper.addEventListener('click', function(e) { if (!e.target.closest('.fv-ia-node-button') && !e.target.closest('.fv-ia-explore-btn')) { closeAllIANodes(); resetExploreBtn(); } }); } /* Initial Animation */ window.fvAnimateCharts(chartWrapper); /* Countdown Logic */ var countdownContainer = chartWrapper.querySelector('.fv-countdown-container'); if (countdownContainer) { var targetDateAttr = countdownContainer.getAttribute('data-target-date'); if (targetDateAttr) { var targetDate = new Date(targetDateAttr); var primaryColor = countdownContainer.getAttribute('data-primary-color') || '#f97316'; var subheadColor = countdownContainer.getAttribute('data-subhead-color') || '#ffffff'; var pad = function(n) { return (n < 10 ? '0' : '') + n; }; var updateCountdown = function() { var difference = +targetDate - +new Date(); var d = 0, h = 0, m = 0, s = 0; if (difference > 0) { d = Math.floor(difference / (1000 * 60 * 60 * 24)); h = Math.floor((difference / (1000 * 60 * 60)) % 24); m = Math.floor((difference / 1000 / 60) % 60); s = Math.floor((difference / 1000) % 60); } var daysEl = countdownContainer.querySelector('[data-time="days"]'); var hoursEl = countdownContainer.querySelector('[data-time="hours"]'); var minsEl = countdownContainer.querySelector('[data-time="minutes"]'); var secsEl = countdownContainer.querySelector('[data-time="seconds"]'); if (daysEl) daysEl.textContent = d; if (hoursEl) hoursEl.textContent = pad(h); if (minsEl) minsEl.textContent = pad(m); if (secsEl) secsEl.textContent = pad(s); }; updateCountdown(); setInterval(updateCountdown, 1000); } } } if (false) { var slideshowContainer = document.getElementById(uniqueId + '-slideshow'); if (slideshowContainer) { var slides = slideshowContainer.querySelectorAll('.fv-slide'); slides.forEach(function(slide) { setupWrapper(slide.querySelector('.fv-chart-wrapper')); }); } } else { setupWrapper(root); } } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', function() { initialize('fv-chart-1780067391081-6swb3ztn4', false); }); } else { initialize('fv-chart-1780067391081-6swb3ztn4', false); } })();Attributes
Notes
Rating
Features
AirPods Max 2 are finally full of 2026 tech; you love to see it — just not hearing tests
4.5/5
Sound quality
Excellent ANC and head-tracked Spatial Audio with bags of space in the mix
5/5
Design
There's very little to see here until you get to the H2 chip and new amp — but if it ain't broke…
4.5/5
Value
There is value here, you just can't really see it (because they look just like a set from 2020)
4/5
Buy them if…You want to be held in a bubble of silence
If you want that and (ideally) you own an iPhone, these are the cans for you. Very little penetrates the silence here.
You travel a lot (and you don't speak the language)
Live Translation is well integrated here and for the first time I found it very useful, rather than a fun gimmick to use with my Spanish-speaking other half.
You value head-tracked Spatial Audio
This is especially true if you watch movies on the fly, but even if you just like Apple Music's Spatial Audio offering with head tracking, this is the flagship Gold Standard of the format.
You need proper stamina for long-haul flights
AirPods Max 2's battery life is not great — and by 'not great' I mean that any recent rival of note can beat the quoted battery life by at least four hours (and often by a lot more).
You own an Android phone
It probably goes without saying, but for this money (and for the number of features that melt away if you never bought into Apple's ecosystem), you'll be better served with a Sony, Technics, Bose, Cambridge or Bowers & Wilkins product.
You want LDAC or aptX Adaptive
No dice here, friend. That will come as no surprise to dyed-in-the-wool Apple fans, but if you want hifalutin wireless codecs for higher-resolution audio over Bluetooth, you'll need to look to Bowers & Wilkins or even Sennheiser — which, at the time of writing, has just announced its new Momentum 5 Wireless.
Apple AirPods Max 2
Bose QuietComfort Ultra Headphones (2nd Gen)
Sony WH-1000XM6
Bowers & Wilkins Px8 S2
Drivers
'Apple-designed dynamic driver'
Not stated officially
30mm dynamic
40mm dynamic full-range carbon cone
Active noise cancellation
Yes
Yes
Yes
Yes
Battery life
Up to 20 hours (ANC on); 5 mins of charging = 1.5 hours of listening
30 hours (ANC on)
30 hours (ANC on)
30 hours (ANC on)
Weight
386.2g
250g
254g
310g
Connectivity
Bluetooth 5.3 (H2 chip); USB-C audio
Bluetooth 5.4 with aptX Adaptive, USB-C audio
Bluetooth 5.3, 3.5mm, LDAC
Bluetooth 5.3 with aptX Adaptive and aptX Lossless
Sony WH-1000XM6
If you’re after something a little bit cheaper that performs really well in every department without ever quite dominating it, the Sony WH-1000XM6 are excellent all-rounders with better battery life and LDAC support (ie. good for Sony handsets or Samsung Galaxy S-Series phones).
Read our full Sony WH-1000XM6 review
Bose QuietComfort Ultra Headphones (2nd Gen)
Like the Sony cans above, you get an extra 10 hours of battery life over the Apple option, with ANC deployed. And what a great noise-cancelling performance it is! You also get Bose's Immersive Audio profiles, which we really enjoyed.
Read more in our Bose QuietComfort Ultra Headphones (2nd Gen) review
View Deal
Bowers & Wilkins Px8 S2
Want a truly premium-feeling set of over-ears? These are gorgeous, and the detailed, neutral sound is sensational — although you do pay for that. That being said, the onboard spatial audio solution is easily beaten by AirPods Max 2…
See if they're a better fit for you in our Bowers & Wilkins Px8 S2 review
I used AirPods Max 2 for two months while compiling this review. Why so long? Because I had to have shoulder surgery after accepting them for review, so my testing involved listening to podcasts and music post-op from my hospital bed, with ANC on to distract me from my immediate surroundings, then plenty of streamed movies during my recovery (and to distract me from painful rehab exercises).
I listened at home, on a quick pre-op trip to Girona (which is where AirPods Max 2's Live Translation really came into its own) and on blustery Dorset coastal walks, and let me tell you, they kept me sane while navigating my early recovery away from my desk.
I've been testing audio products full-time since 2019, first as a staff writer at TechRadar's sister publication What Hi-Fi? (locked in our hi-fi testing facility for two years, I was), then as senior writer at TechRadar and, since early 2024, audio editor.
My background as a professional dancer means I'm always interested in moving to good-quality music even with a non-functioning shoulder. I never stop listening for precision, clarity, faithful timing, insight and good old-fashioned fun in recorded audio. And when said shoulder's fully better, I'm going to be back to throwing shapes while testing too. You just wait…