The Dynamic Island: How Contextual UI Surfaces the Right Data at the Right Time

Maxime Champoux8 min read

By the Well Engineering Team

In January 2026, we had a dashboard problem. Not the kind where charts are broken or numbers are wrong. The kind where everything works perfectly and nobody looks at it.

Our enrichment engine was pulling data from six providers, filling 23 fields per company record with confidence-scored results. The data was good. The architecture was solid. And our users were ignoring most of it because it lived behind a tab they had to click, on a page they had to navigate to, in a section they had to scroll to find.

Static dashboards assume users will come to the data. That assumption is almost always wrong.

The Concept Paper

The idea started as a two-page document Bastien wrote after watching a user session recording. A customer had clicked the Enrich button, watched the fields populate, then switched to their email to manually type the same company address they'd just enriched. The data was there. They didn't see it.

The concept paper had one thesis: data should appear where the user is working, not where the system stores it. Bastien called it the Dynamic Island, borrowing Apple's term for their iPhone notification surface. The name stuck because the metaphor was precise. Apple's Dynamic Island turns a hardware cutout into a contextual information surface. We wanted to turn dead space in our UI into a contextual data surface.

The paper proposed a floating panel that would appear near the user's cursor when enrichment data was relevant to what they were doing. Editing an invoice? The panel shows the counterparty's verified address and VAT number. Reviewing a transaction? It surfaces the merchant's industry classification and revenue range. The trigger wasn't a click. It was context.

What Didn't Work First

We built three prototypes before shipping anything.

Prototype one was a tooltip. Hover over a company name, get a card with enrichment data. The problem was information density. We had 23 possible fields. A tooltip that shows 23 fields is not a tooltip. It's a modal pretending to be small. Users found it overwhelming, and the hover trigger created a jittery experience when moving the mouse across a list of records.

Prototype two was a sidebar. Click a record, and a right-side panel slides in with all enrichment data. This solved the density problem but reintroduced the navigation problem. Users had to consciously decide to open the sidebar. The usage data confirmed what we suspected: sidebar opens dropped 60% after the first week. Novelty wore off. The extra click was enough friction to kill the habit.

Prototype three was the closest to what shipped. A compact floating panel, anchored to the active record, showing only the fields relevant to the current task. But it had a rendering bug that took us two weeks to solve. The panel would calculate its position based on the record's DOM element, but our virtual scrolling implementation meant the element could be recycled while the panel was still animating. The panel would snap to a different record mid-transition. It looked like a UI possessed by demons.

The Architecture Decision

The core technical challenge was determining "relevant fields" without hardcoding every possible user task. We considered three approaches.

Option A was a rule engine. Map each page and action to a set of relevant enrichment fields. Invoice editing shows address, VAT, and legal name. Transaction review shows industry and revenue. This was simple to implement but brittle. Every new feature would require new rules. Every edge case would require an exception.

Option B was an ML model that predicted which fields a user would need based on their behavior patterns. This was technically interesting and practically absurd for our stage. We had maybe 200 active users. The training data didn't exist, and the inference latency would have added 100ms to every interaction.

Option C was a context schema. Each page component declares which enrichment field categories it consumes. The Dynamic Island reads the schema of the currently focused component and filters its display accordingly. Adding a new component to the app means defining its enrichment context, and the island adapts automatically.

We shipped Option C. It took four days to implement the schema system and two more to migrate existing components. The migration surfaced three places where components were rendering enrichment data in inconsistent formats, which we fixed along the way.

Design System Decisions

The Dynamic Island forced us to confront a design system gap we'd been ignoring. Our shadow tokens were built for static surfaces: cards, modals, dropdowns. The island needed shadows that communicated "floating but anchored." It needed to feel like it belonged to the record it was referencing without looking like a child element of that record.

We introduced two new shadow tokens: shadow-contextual and shadow-contextual-elevated. The first is a subtle, directional shadow that connects the island visually to its anchor point. The second adds depth when the island expands to show more fields. The difference between them is 2px of blur and a slight shift in the Y offset. Tiny details. But they're the kind of details that separate software that feels considered from software that feels assembled.

The color system needed work too. The island inherits the background color of its context. On a white page, it's white with a warm gray border. On our dark-mode transaction view, it shifts to match. This sounds obvious, but our design tokens didn't support contextual inheritance. Each component had hardcoded color references. We refactored to a theme-aware token system during the Feb 2026 redesign, and the island was the forcing function.

The Confidence Layer

Enrichment data has confidence scores. A company name returned at 0.95 confidence is probably correct. An address at 0.62 confidence might be wrong. Our original enrichment display treated all data equally. Green checkmark, field populated, move on.

The Dynamic Island introduced visual confidence tiers. Fields above 0.85 confidence display normally. Fields between 0.50 and 0.85 show with an amber indicator and a subtle dotted underline. Fields below 0.50 don't appear in the island at all; they only show in the full enrichment panel where users can manually verify them.

This was a product decision disguised as a UI decision. By hiding low-confidence data from the contextual surface, we reduced the chance of users copying incorrect information into documents. The data still exists. It's just not surfaced in the fast path.

From Storyboard to Screen

We storyboarded the interaction for our product video before we finalized the implementation. This is backwards from how most teams work, but it forced us to commit to the experience before getting lost in technical constraints.

The storyboard showed five scenes: a user receiving a new client inquiry, clicking Enrich, seeing the island appear with relevant data, dragging a verified address into an invoice, and the island collapsing when the task was complete. Each scene mapped to a specific technical requirement. The drag interaction required us to implement a data transfer protocol between the island and form fields. The collapse behavior required an idle detection system to know when the user had moved on.

Building the storyboard first meant we had a clear definition of done. No scope creep. No "what if we also added" conversations. The video became the spec.

What the Numbers Say

Three weeks after launch, we measured the impact.

Enrichment data usage increased 340%. Not because we had more data. The data was always there. Users were actually seeing it and using it because it appeared in context.

Average time to complete an invoice dropped by 40 seconds. Most of that savings came from the address and VAT auto-population that users were previously doing by hand.

Support tickets about "missing data" dropped to near zero. The data wasn't missing before. It was buried.

The Lesson

The Dynamic Island isn't technically complex. The context schema is a few hundred lines of TypeScript. The rendering logic is standard React portal behavior. The shadow tokens are two CSS variables.

The hard part was recognizing that a dashboard full of correct data can still fail if it doesn't respect how people actually work. The hard part was killing three prototypes before finding the right interaction model. The hard part was letting a product video define the engineering spec instead of the other way around.

Context beats content. Every time.

We think about this now whenever we design a new surface. The question isn't "where does this data live?" The question is "where is the user when they need this data?" They sound similar. They lead to completely different designs.

Maxime Champoux, CEO & co-founder, Well

Maxime Champoux

CEO & co-founder, Well

Maxime is the CEO and co-founder of Well. He built Well to rebuild finance around AI-native data, not spreadsheets.

LinkedIn

Ready to automate your financial workflows?