The first version of the Deck plugin in Composer, showing multiple documents open side by side as planks in a horizontally scrollable layout.

Multitasking without tabs

We kept running into the same problem building Composer: as the app grew, we’d find ourselves needing two or three things open at once. A document and its comments. A spreadsheet and a chat thread. Any web app gets this for free from the browser, of course, but loading Composer from scratch in each tab was heavy, and the tabs themselves hid all context about what was open where.

I took a page from my design playbook at AMBOSS and built Deck, a layout plugin for Composer which arranges open objects horizontally as planks. This is the story of how that layout came together over two years of incremental work.

Where are you looking?

Before I could build the Deck itself, I needed to answer a question that tabs don’t have to answer: if multiple things are visible at once, which one does the user consider “current”? The conventional model of a single selected item doesn’t work when you can see three documents side by side. I introduced an attention context that tracks which surfaces the user is actively engaged with, and propagates that information to the navigation tree, to presence indicators, and to any component that cares about where the user is focused.

The attention and relatedness system in action. Clicking into a plank updates attention indicators across the sidebar navigation and the attention glyphs in plank headings.

The attention glyph, a small indicator on each plank’s heading, turned out to be a versatile little affordance. It showed where you were, where your collaborators were, and eventually it doubled as a button for closing open items. A related concept, relatedness, indicated when two planks were connected, such as a document and its comments thread, so that attending to one implicitly related to the other.

A generic frame

With the attention infrastructure in place, I integrated Deck into Composer as an experimental alternative layout enabled with an environment variable. The first version was deliberately minimal: planks in a horizontal scroll, each rendering whatever plugin content was associated with it. Opening something from the navigation tree added a plank; closing one removed it.

This simplicity was the whole point. The Deck couldn’t know whether a plank contained a Markdown document, a spreadsheet, a kanban board, or a chat thread. The plank was just a frame, and each plugin was responsible for filling it. This meant new content types got Deck support for free, which was important since the plugin ecosystem was growing at the same time.

Pixel pushing

Resizing came early. A fixed-width column works for documents but wastes space for narrow chat threads and cramps wide spreadsheets. I added drag-to-resize handles between planks so each surface could be sized to fit its content.

Getting the layout right for every content type in every position was frankly a long slog. Stack, Markdown, Table, and Sheet all had different assumptions about how they filled space, and each needed to work in planks, in sections (stacked vertically within a plank), in solo mode, and in the complementary sidebar. A significant chunk of the work across many PRs was reconciling these assumptions into a consistent set of container behaviors that just worked.

Layout refinements that made Stack, Markdown, Table, and Sheet work correctly in planks, sections, solo, and complementary positions.

One outcome of this phase was StackItemContent, a container that other developers on the team had been asking for. Plugins often wanted a toolbar, a header, and a content area with consistent spacing; StackItemContent provided standardized slots for these, with plank resizing and solo mode working correctly regardless of what was inside.

The Stack-next refactor, introducing StackItemContent as a consistent container for plugin content within planks.

Companion planks

Not everything that opens alongside a document deserves a full plank. Comments, chat with the assistant, message previews — these are companions to a primary surface, not independent work items. I built companion planks as narrow, attached panes that open beside a main plank and are managed through the same navigation graph as everything else.

Companion planks, where secondary content like comments or chat opens alongside the main plank.

When a plank could have multiple companions, they needed to share the same narrow space, so I refactored companions to use the navigation graph for their ontology and render as tabs. This worked out nicely for the email integration as well, where the message list, message preview, and contact details all live as companions.

Focus when you want it

Deck is a multitasking layout, but sometimes you want to focus on one thing. Solo mode collapses the Deck to a single plank, and fullscreen extends that to the entire viewport, hiding the sidebars and everything else. I implemented fullscreen as an additional degree of solo, so the transition from multi-plank to single-plank to fullscreen felt like a smooth continuum rather than a mode switch.

Fullscreen mode, where a single plank fills the viewport. Chrome appears on hover when the cursor approaches the top edge.

Later I added plank encapsulation, a setting that renders each plank as a visually distinct card with borders and rounded corners. Some users prefer the visual separation; others prefer the minimal flush layout where planks blend into one continuous surface. Since the plank was always just a generic frame, this was a styling concern rather than an architectural one.

Plank encapsulation, rendering planks as distinct bordered cards.

Down to the phone

On a desktop with a wide viewport, the Deck can show several planks. On a tablet, it narrows to one or two. On a phone, the whole metaphor changes: you get a single surface at a time with a dedicated home screen and space-level navigation. I implemented a MobileLayoutPlugin with mobile-native designs for the same content, using the same attention and navigation systems but with touch-appropriate gestures and layouts.

The mobile layout, where the Deck adapts to a single-surface view with space-level navigation.

The design held up because the Deck never committed to a specific number of planks. The plank is a generic frame; the attention system doesn’t care how many are visible; the navigation graph works the same way whether it’s managing five columns or one. All the work that went into making each content type behave in each position paid off when the same components needed to work at phone scale too.