iOS Booking Flow: Issue Diagnosis + Critical Analysis
Prepared for: Brendan Alborn - abeltasman.com
Investigation by: Dylan Galletly (Technical Director & Lead QA) with Dev Support
Devices: iPhone 11 + iPad Pro remote debugging, Chrome DevTools for general testing
Delivered: 17th November 2025
Testing Sprint: Friday 14th to Monday 17th
iOS Users Impacted (stats from GA) 200,000+ in one year (condensed sample size Oct 2024 - 2025 on the main website).
Intro
The booking system uses a three-layer nested iframe architecture (WordPress → IBIS → Windcave) that creates iOS-specific touch-routing failures. The parent WordPress site dynamically locks scrolling via scrolling="no"so the iframe can resize properly (more on this later). Modals appear inside iframes where they can't properly coordinate with the actual viewport (inner iframe constraint vs user's viewport). We have cross-domain coordination that iOS Safari really struggles with, heavy reliance on scroll chaining across security boundaries (this has both let the issue go unnoticed and simultaneously made the site work in most situations, section on this below), and nested hidden fixed-position overlays with scroll containers.
From what we've seen, the architecture works on desktop / Android because those browsers handle cross-domain scroll coordination differently. On iOS, once touch events enter a nested iframe with modal overlays, they don't seem to escape back to the parent page. Users get trapped mid-booking, can't reach modal buttons, and can't scroll payment forms. The sub-16px input font-size triggers iOS auto-zoom, turns an already clunky UX process (but semi-manageable) into a 'hard refresh' situation while at the final stage of payment.
There are also 7 unthrottled / debounced resize listeners running constantly (Astra theme, jQuery, iframeResizer, custom scripts, multiple analytics trackers), which could potentially be compounding timing issues, but we haven't confirmed this is directly causing drastic problems.
1. The Mission
Our goal was to get to the root of these systemic problems and advise on the urgent next steps. iOS users can get 'trapped' at two critical points in the Abel Tasman booking flow (especially when cart is longer, meaning people have spent more time already setting up a trip), while Android and desktop work ok. This creates 1. An extremely frustrating / unacceptable user experience 2. A reduction in conversion rates on mobile (GA stats back this up).
The core fail points we're looking into in this document:
- Cart removal modals appear off-screen and unreachable
- Windcave payment page locks completely (much worse with auto-zoom or CAPTCHA) once you enter a field, you basically can't move beyond the zoom state.
We used Safari Remote Debugging on iPhone and iPad to deeply understand what's happening, provide some clarity around the iOS quirks and suggest next steps.
2. Architecture Details
The booking architecture consists of: (there's more but these are the important ones for this doc.)
Layer A — WordPress (www.abeltasman.com)
- Astra theme
- IBIS widget (
ibis.js) iframeResizerhost script- Receives height + scroll info from IBIS via
postMessage
Layer B — IBIS Booking System (book.abeltasman.com)
iframeResizerclient script- SweetAlert2 modals
- Own touch handlers
- Windcave payment iframe
Layer C — Windcave Payment Iframe (windcave.com / secure3ds domains)
- Fixed overlays
- Scrollable inner divs
- Additional nested iframes for Google Pay / Visa / CVC helpers
- We're unsure of how this is sized / loaded in / integrates / communicates (if at all) with IBIS
Inter-Environment Comms
What we observed in the browser (JavaScript/frontend communication) NOTE: we were only focused on iFrame / issue step processes
WordPress and IBIS communicate through iframeResizer's postMessage channel:
IBIS → WordPress:
- Height updates (from things like cart length if user has multiple products)
PageInfo(scroll position, viewport dimensions)
WordPress → IBIS:
- Acknowledgements + resizing commands
From what we observed, this postMessage channel appears limited to dimension/scroll coordination:
In our browser monitoring, we didn't see touch events, scroll events, preventDefault (modal popup) signals, DOM structure updates, or modal state changes passing through this channel.
IBIS and Windcave:
We couldn't observe any postMessage communication between IBIS and Windcave during browser monitoring. Windcave appears to operate as an isolated iframe inside IBIS, with no visible JavaScript coordination between the two layers. This could be different, and is currently an assumption, one of the key next steps is to get clarity around IBIS is loading this in and setting up the frame.
3. Why is this specific to iOS Safari?
Important to note: Every iOS browser app (Safari, Chrome, Firefox, Edge) must use Apple's WebKit engine. So the bugs show up on all iOS browsers
First We Need To Understand 'Scroll Chaining' (The Core Mechanism)
Think of scroll chaining like a chain of command. When you swipe / drag your finger, the browser has to figure out: "What should this gesture scroll?"
Typical flow:
- You touch an element (a cart inside the booking process iframe)
- Browser checks: "Can this element scroll?"
- If yes → it scrolls the element
- If no → the gesture "chains to" the next parent this is when
scrolling=noworks perfectly on the iframe, and just scrolls the page (as you'd expect).
- The touch / drag propagates up through each layer until it finds something scrollable
Booking cart itself (can't scroll as the height is set dynamically)
↓ chains to...
Iframe embed (scrolling="no" tells it that it shouldn't internally scroll (by design as Wordpress has allowed the embed to be the perfect height for the content inside.)
↓ chains to...
Parent WordPress page (can scroll) ✓
This is how the current site works on most of the embed pages. Both iOS and Android use this mechanism.
On iOS specifically, there is a responder chain:
The touch event follows a predefined path through the iOS system:
- Initial View → The view under the touch (first responder)
- Superview → If not handled, moves up the view hierarchy
- View Controller → Continues until reaching a view controller
- Window → From view controller to the
UIWindowobject - Application → From window to
UIApplicationobject - App Delegate → Final recipient in the chain
This is why cross-domain iframe boundaries are sooooo problematic on iOS. When the responder chain tries to cross from one domain's iframe (e.g., Windcave) to another domain's iframe (IBIS), then to the parent document (WordPress), it's traversing security boundaries that weren't designed for this flow. If JavaScript interferes anywhere in that chain (like preventDefault() the popup / overlay to remove something from cart), iOS has no recovery mechanism, the responder chain just stops.
The Critical Difference
The difference is what happens when something goes wrong in that chain.
Android/Desktop (loose):
preventDefault()(full screen fixed modal overlay / popup) called inside cross-origin iframe → parent page often scrolls anyway- Fixed-position elements with scroll containers → browser routes around them
- Touch routing failures → browser attempts recovery
- Way more forgiving across security boundaries
iOS Safari (strict):
preventDefault()full screen fixed modal overlay / popup) called inside cross-origin iframe → scroll chain killed.- Fixed-position elements with scroll containers → touch routing gets "confused", stops trying
- Touch routing failures → no fallback, gesture is dead
- Very strict enforcement of scroll chain integrity
Analogy: Android is like a game of whispers where if one person doesn't hear clearly, they just guess and pass the message anyway. iOS just stops the game :-\
The Cross-Origin Challenge
In our setup, we have cross-origin iframes (WordPress on one domain, IBIS on another, Windcave on a third). on iOS this creates security boundaries where JavaScript cannot cross. 'What do you mean? But the iframe does work!',explanation on this soon.
In our three-layer system, scroll chaining must successfully traverse:
- Touch Windcave payment form
- Chain through Windcave iframe's document
- Cross security boundary into IBIS iframe
- Cross another security boundary into WordPress
- Finally scroll the actual page
If ANY step fails on iOS, the user is stuck. The gesture just dies.
On Android/desktop, if step 2 or 3 fails, the browser mostly says "I'll just scroll the page anyway."
What Breaks the Chain
The scroll chaining mechanism works the same on both platforms. What's different is iOS Safari's strict enforcement when that mechanism encounters:
preventDefault() calls inside cross-origin iframes
When SweetAlert2 modals call preventDefault() inside the IBIS iframe, iOS treats this as absolute: "Stop. Do not pass this gesture to anyone." Android often ignores this and scrolls the parent anyway.
Fixed-position overlays with internal scroll containers
Windcave current has multiple fixed div elements with overflow-y: scroll but scrollHeight: 0. iOS may be trying to route touches to them, can't scroll them, and thendoesn't know what to do next. It very likely gets "confused" and stops. Android recognises this pattern and routes the touch to the parent. It's worth noting here that this is our assumption based on isolating the modal issue, this needs further testing and coordination with IBIS on how they are implementing Windcave.
Multiple nested cross-origin security boundaries
Each iframe boundary is a JavaScript isolation layer. iOS enforces these strictly. Android/desktop are more lenient about letting scroll gestures "escape" from nested iframes.
Why This Matters
This isn't so much a 'bug' more: strict security and strict behaviour enforcement.
Unfortunately, that philosophy is incompatible with complex nested cross-origin iframe architectures.
Combined with our three-layer architecture, this can create complete UX traps.
Important: It's Not Just Because of Cross-Domains
For clarity, the cross-domain iframe architecture alone isn't the problem. During most of the booking flow, touch events successfully propagate through cross-domain layers (Wordpress → IBIS → WordPress) and the page scrolls fine.
The architecture does work (mostly).
The failures only occur when something interferes with the scroll mechanism inside those cross-domain iframes. Specifically:
- When
preventDefault()is called on touch events (SweetAlert2 modals) - When fixed-position elements with scroll containers confuse iOS touch routing (Windcave payment page)
It's the combination that creates the trap: cross-domain security boundaries + anything that can disrupt scroll chaining (JavaScript, CSS, or DOM structures).
The video below demonstrates this: you can see touch events firing to the console log on the parent page (footer and menu in this vid), then not being sent back to the parent when inside the cross-domain iframe (but the booking page still scrolls). This proves the architecture itself isn't broken. It only breaks when specific JavaScript or CSS/DOM structures interfere with iOS Safari's strict scroll chain enforcement.
4. Failure Point #1 — SweetAlert2 Cart Modal (remove from cart popup) Locks Scroll
What Happens:
The booking iframe is continually forced to scrolling="no" via ibis.js + iframeResizer.
As long as scroll chaining works, this is fine: the parent page scrolls seamlessly, and the booking iframe feels like part of the main document.
But when the SweetAlert2 modal appears:
- It renders a fixed-position backdrop (the semi black overlay)
- The backdrop uses touch handlers that call
preventDefault()the reason for this is because typically you actually don't want the body of a page to scroll when a modal is up (standard UX). - On iOS, this blocks scroll chaining entirely
- The iframe cannot scroll (due to scrolling also being set to
scrolling="no"by ibis.js (which makes sense typically) - The parent page never sees the touch gesture
- Total lock, can't move
Testing & Validation
We confirmed this mechanism by monkey-patching preventDefault() in the IBIS iframe during testing. With preventDefault() disabled, the iframe remained scrollable even with the modal open.
This proves the scroll lock is directly caused by the internal preventDefault() call, not the modal structure itself.
Why The Modal Buttons End Up Off-Screen
(a compounding issue with the current setup)
iframeResizer expands the iframe to the full content height (in our tests, we saw 1860px to contain all the cart items).
Inside the iframe, window.innerHeight reports the iframe's full height, not the user's actual viewport.
SweetAlert2 centres its modal using this reported height:
top: 50%; /* centres based on iframe height, e.g. 930px down */
Here's the fundamental problem: The modal is constrained to the iframe's environment (and div rules). It literally cannot position itself outside the iframe boundaries (unless we trigger this on Wordpress side - a note on this later). The modal positions itself at the centre of the 1860px internal iframe space, but the user's actual viewport is only 750px.
The modal exists at pixel position 930 within the iframe. The user can only see up to pixel 750. There's no way for the modal to "break out" of the iframe and appear in the visible viewport. It's stuck inside the iframe's system. And because scroll is locked, users can't navigate down to where the modal actually is. It's frustrating me thinking about it.
5. Failure Point #2 — Windcave Payment Page Touch Lock
Observed Behaviour:
Consistent across all tests:
- Windcave payment form (CC input area) = always locked from page load made significantly worse by the
<16pxfont size triggering iOS autozoom - Touch outside iframe (Wordpress edge scroll just outside embed) = parent page scrolls perfectly
- Touch inside Windcave iframe = completely frozen
- Open modal (CVC help, Learn More) = internal modal content scrolls perfectly indicating that touch is actually getting into Windcave iframe / passing through IBIS.
- Main payment form remains locked throughout (nightmare UX with the autozoom for small font sizes)
Structure Analysis Results (via Safari Remote Debugging):
Evidence collected: When inspector ran on IBIS iframe at Windcave payment step, detected:
WINDCAVE NESTED IFRAME: Confirmed (Layer C)
src: [windcave payment domain]
scrolling: no (set by parent)
FIXED-POSITION OVERLAYS: 7 detected in Windcave (inspected via IBIS iframe)
├─ DIV #cvc-popup .overlay
│ size: 0px x 0px | z-index: auto
│ display: none | visibility: hidden (HIDDEN)
│ Contains scrollable child. iOS scroll trap
│
├─ DIV #SrcLearnMorePopup .overlay
│ size: 0px x 0px | z-index: auto
│ display: block | visibility: hidden (HIDDEN)
│
├─ DIV #cvc-popup2 .overlay
│ size: 0px x 0px | z-index: auto
│ display: block | visibility: hidden (HIDDEN)
│ Contains scrollable child. iOS scroll trap.
│
├─ DIV #WSrcDcfContainer .DpsClickToPayDcfPopupOverlay
│ size: 0px x 0px | z-index: auto
│ display: block | visibility: hidden (HIDDEN)
│
├─ DIV #vcop-src-system
│ size: 1px x 1px | z-index: auto
│ display: block | visibility: hidden (VISIBLE)
│
├─ DIV #visa-sdk-loader-wrapper
│ size: 0px x 0px | z-index: 999995
│ display: none | visibility: visible (HIDDEN)
│
└─ DIV (unnamed, 135px x 34px)
size: 135px x 34px | z-index: 999999999
display: block | visibility: visible (VISIBLE)
SCROLL CONTAINERS: 2 detected
├─ DIV .content
│ scrollHeight: 0px | clientHeight: 0px
│ Cannot scroll (safe when hidden)
│
└─ DIV .content
scrollHeight: 0px | clientHeight: 0px
Cannot scroll (safe when hidden)
Cross-origin limitation: Could not inspect inside Windcave iframe due to security isolation. The actual Windcave page structure was a black box (as far as we could see in the short sprint).
Our Working Theory Based On Modal Finding
Applying our modal scroll chain knowledge to the Windcave payment lock issue:
This appears to be the same cross-domain touch-routing failure occurring, it just manifests differently:
Cart modal (SweetAlert2):
- Modal appears →
preventDefault()fires → instant scroll lock when modal visible - Before modal: page works
- After modal: complete lock
Windcave payment:
- Page loads → instant scroll lock from page load
- Main form: always locked
- Modals open: those specific modals scroll, main form still locked
What this suggests:
Both failures seem to stem from iOS Safari's inability to route touches across cross-origin iframe boundaries when fixed-position elements and scroll containers exist at all in the DOM structure. The difference is timing (instant vs triggered) and what becomes scrollable (nothing vs opened modals), but the underlying pattern is similar: touch-routing issues in nested cross-origin iframe architecture.
Why modals work / scroll (internally in it's own modal div) but payment form 'the page' doesn't:
When a modal opens (CVC help, Learn More), iOS Safari can clearly identify an active, visible scrollable container and route touches to it successfully (open the CVV about modal, you can scroll inside it up and down fine — although it's worth noting that WC modals don't have the background scroll lock on, which is another clue we need to dig further into). The main payment form appears to create what we're calling "touch confusion". iOS can't seem to determine the correct scroll target, resulting in no scrolling at all.
Important note: We can't prove the exact mechanism without access to Windcave's iframe code. What we can observe is that the behavioural pattern matches the iOS Safari touch-routing issues we confirmed with the cart modal, and the nested cross-origin architecture creates similar fundamental challenges. It's critical that we get a better understanding of what IBIS is doing with that iframe to 100% diagnose this with confidence.
Summary of What we Observed Inside Windcave:
Windcave renders:
- Multiple fixed-position overlays
- Inner divs with
overflow-y: scroll - Custom flags like
canScroll: false - Hidden overlays initialised with:
scrollHeight = 0- Scroll listeners attached from page load
This pattern is a well-known iOS scroll trap:
- Touch lands inside the inner iframe (Windcave)
- iOS tries to scroll the innermost scrollable container
- A hidden/fixed/scrollable structure confuses the iOS scroll chain
- Touch gesture never escapes the Windcave iframe
- IBIS never receives the touch gesture from the user (stopped at WC)
- WordPress never receives the gesture
- Parent page appears frozen even though it isn't
DOUBLE Cross-Domain (iframe in an iframe) — Ouch.
The scroll chain has to cross:
Windcave div → Windcave document → Windcave iframe element
→ IBIS document → IBIS iframe element → WordPress document
Any interference in this multi-layered stack iOS doesn't 'like' just kills the chain.
Windcave has many hooks capable of doing just that.
6. Why the "Edge Scroll" Works (around the IBIS iframe div).
When you grab the edge of the iframe (effectively still WP page):
Your finger starts outside the Windcave content area, so iOS routes the touch directly into the WordPress parent document. The scroll chain never touches Windcave, and everything scrolls normally.
This suggests that the freeze is most definitely a touch-routing issue inside the nested iframes, rather than an iframe height problem. Which we first tested (we focused on the iframeresizer.js)
7. Other Observations
'Noise' From iframeResizer + Others
Repeated / consistent logs (warnings not errors):
[iFrameResizer][Host page: iframeResizer0] Ignored iframe, already setup.
Multiple initialisations add timing complexity but aren't the root cause.
Seven Unthrottled / Debounced Resize Handlers:
- Astra scripts
- jQuery
iframeResizer- Custom JS
- Multiple analytics trackers
All passive: false.
These could potentially be amplifying layout jitter (this does happen a bit through the booking process, but that's not our focus on this sprint), we can't confirm they're adding to the core scroll lock issue. They're still worth noting as potential compounding factors and performance enhancement for down the road.
Windcave font-size: 14px → iOS auto-zoom
Inputs <16px trigger viewport zooming on iOS.
With scroll trapped, zooming makes the UI unusable.
8. Fixes
Fix 1 — Increase Input Font Size to 16px+ on Mobile (this is very easy / fast to ship)
Proposed solution: On both IBIS and Windcave steps, increase all input font sizes to ≥16px.
Prevents iOS auto-zoom, which makes the 'working' name entry fields overflow (janky UX) and creates barely usable checkout on payment i.e. 'the scroll-trap'.
Fix 2 — Enable Conditional Iframe Scrolling In Astra / Wordpress (ibis.js)
Current state: iframeResizer continuously sets scrolling="no" on the booking iframe every 1000ms via ibis.js.
The issue: While this makes the iframe feel like part of the parent page (parent scrolls, iframe doesn't), it creates a complete dependency on iOS Safari's scroll chaining mechanism. When that chain breaks (modals, preventDefault, etc.), users are trapped.
Potential solution: Make scrolling conditional based on content state.
// In ibis.js - modify iframeResizer initialization
function updateIframeScrolling() {
const iframe = document.querySelector('iframe[src*="book"]');
const hasModal = iframe.contentWindow.document.querySelector('.swal2-container');
const hasWindcave = iframe.contentWindow.document.querySelector('iframe[src*="windcave"]');
// Enable internal scrolling when modals present or on payment step
if (hasModal || hasWindcave) {
iframe.setAttribute('scrolling', 'auto');
} else {
iframe.setAttribute('scrolling', 'no');
}
}
Fix 3 — Validation + More Information + Checks of IBIS Touch Behaviour During Windcave Step
Proposed solution: IBIS should confirm:
- No additional scroll-prevention is applied when the payment iframe loads
- How is the Windcave embed setup? What are the properties?
- No "lock scroll while payment loads" behaviour is triggering
iframeResizercontinues receiving accurate height data (it currently appears correct, be good to verify)
Fix 4 — Implement WordPress-Level Modal Overlay
Proposed solution: The only 'real' fix for the cart modal is a WordPress modal overlay triggered from the iframe. The modal needs to exist in the parent WordPress document, not inside the iframe's coordinate system.
The best and most robust solution is a full-screen takeover fixed message in the WordPress layer, coordinated via postMessage from the IBIS iframe when cart removal is requested.
Fix 5 — Remove Potential Traps Inside Windcave's iOS Interaction Layer
(We realise this will be near impossible to get them to do, but noting anyway. The best solution here for smoother UX is a styled Windcave page that redirects after payment step. This also eliminates the cross-origin problem.)
Proposed solution: Because the iframe is already resizing correctly in the parent, the real fix is:
Ensure touches inside the Windcave iframe do not get trapped and can either scroll internally or successfully chain out.
IBIS + Windcave should audit:
Global touch handlers inside the payment iframe
- Identify if there is any use of
preventDefault()that applies to overlays - Restrict scroll-blocking only to elements that require it
Fixed-position + scrollable-child patterns
- Replace small scrolling regions inside fixed modals with full-height mobile panels
- Remove unnecessary
overflow-y: scrollfrom tiny help modal containers
Hidden overlays initialised with scroll listeners
- Delay initialisation until overlays are actually opened
- Or ensure hidden elements do not bind scroll/touch listeners that interfere with the chain
9. Our Testing and Validation
Attempted Workarounds (all failed)
We tested some popular iOS iframe touch / scroll workarounds from developer communities:
-webkit-overflow-scrolling: touchon iframe container (deprecated, no effect)- Dummy
touchstartlistener on parent window (no effect across cross-origin boundary) - Forcing parent body height to match iframe (no effect on touch routing)
- Combination of all three approaches (still no effect)
These failures help confirm the issue is very likely architectural, not fixable with CSS/JS hacks on the WordPress side. The cross-origin security isolation is preventing parent-level fixes from reaching the actual failure points inside the IBIS and Windcave iframes.
We used:
- iPhone 11 + iPad Pro remote debugging
- Chrome DevTools for general testing
- Custom structure analysis scripts to detect:
- Fixed overlays
- Scrollable elements
preventDefaultusage- Touch-move behaviour
- Nested iframe architecture
- Real-time viewport data
10. Rapid Test Sprint - Potential For Errors
Fast paced, assessments across multiple environments via remote debugging always carry some room for error. We're confident in this analysis given the well-documented iOS behaviour in this area, but more than happy to jump back into testing if missed processes (or evidence of something else) comes in from any of the development teams.
Repeated / Condensed Summary
No need to read beyond here if you've just finished the doc, next part for printing / summary purposes only.
Evidence collected:
Structure Analysis (Windcave step):
Console output from structure inspector running in IBIS iframe:
- WINDCAVE IFRAME: Confirmed detected (nested Layer C)
- FIXED-POSITION OVERLAYS: 7 detected
#cvc-popup(0px × 0px, hidden, contains scrollable child)#SrcLearnMorePopup(0px × 0px, hidden)#cvc-popup2(0px × 0px, hidden, contains scrollable child)#WSrcDcfContainer(0px × 0px, hidden)#vcop-src-system(1px × 1px, technically visible)#visa-sdk-loader-wrapper(0px × 0px, z-index: 999995, hidden)- Unnamed DIV (135px × 34px, visible)
- SCROLL CONTAINERS: 2 detected (both with
scrollHeight: 0pxwhen hidden) - CROSS-ORIGIN LIMITATION: Cannot inspect inside Windcave iframe
Behavioural Tests:
- Windcave payment form: Always locked from page load (consistent across all tests)
- Edge scroll test: Touching outside iframe = parent page scrolls (proves parent IS scrollable)
- Modal scroll test: CVC popup, Learn More overlay = scroll works perfectly (proves modals CAN scroll)
- Main form test: CC input area = never scrollable (proves main form is permanently locked)
- Font-size test: Inputs measured at
14px(confirms auto-zoom trigger on iOS)
Deductions:
Based on confirmed cart modal mechanism (preventDefault() breaking iOS scroll chain in cross-origin iframe) + identical architectural pattern + matching behavioural symptoms, we deduce that Windcave payment lock stems from the same iOS Safari touch-routing failure, manifesting as instant lock rather than triggered lock. Cannot prove exact internal mechanism without Windcave code access.
Validated behaviours:
Cart Modal (SweetAlert2):
- Modal scroll lock when modal opens
- Modal mis-positioning (iframe coordinate system vs user's actual viewport)
preventDefault()mechanism breaks iOS scroll chain- Modal constrained to iframe boundaries, cannot overlay parent page
Windcave Payment:
- Payment form locked from page load (consistent behaviour, not intermittent)
- Edge scroll test: parent scrolls when touching outside iframe
- Modal scroll test: CVC and Learn More popups scroll successfully
- Main form remains locked throughout
- Fixed overlays with scroll containers detected (7 overlays, 2 with scrollable children)
- Windcave nested iframe detected (Layer C)
- Sub-16px font-size on inputs (
14pxtriggers iOS auto-zoom) - Cross-origin isolation prevents inspection of Windcave internals
- Touch-routing failure deduced based on cart modal findings and architectural similarities
The key distinction: Cart modal mechanism is proven and understood. Windcave payment exhibits the same behavioural pattern and setup, but the exact internal cause can't be verified without Windcave embed / code access. Both seem to stem from iOS Safari touch-routing issues in nested cross-origin iframes.
Investigation by: Dylan Galletly (Tech Director / QA) + Dev Support
Devices: iPhone 11 + iPad Pro remote debugging, Chrome DevTools for general testing
Delivered: 17th November 2025
Testing Sprint: Friday 14th to Monday 17th
Users Impacted With Buggy UX: 200,000+ in one year (condensed sample size Oct 2024 - 2025 on the main website).