diff --git a/src/components/PrimaryWindow.js b/src/components/PrimaryWindow.js
index 4d6344b3acb3f692e6a0511697751016ebeadb03..30c4d302eb4e9794fc9c9b73e318c02a24e78982 100644
--- a/src/components/PrimaryWindow.js
+++ b/src/components/PrimaryWindow.js
@@ -1,6 +1,7 @@
 import { Component, lazy, Suspense } from 'react';
 import PropTypes from 'prop-types';
 import { styled } from '@mui/material/styles';
+import classNames from 'classnames';
 import WindowSideBar from '../containers/WindowSideBar';
 import CompanionArea from '../containers/CompanionArea';
 import CollectionDialog from '../containers/CollectionDialog';
@@ -16,7 +17,7 @@ GalleryView.displayName = 'GalleryView';
 SelectCollection.displayName = 'SelectCollection';
 WindowViewer.displayName = 'WindowViewer';
 
-const StyledPrimaryWindowContainer = styled('div')(() => ({
+const Root = styled('div', { name: 'PrimaryWindow', slot: 'root' })(() => ({
   display: 'flex',
   flex: 1,
   position: 'relative',
@@ -80,17 +81,18 @@ export class PrimaryWindow extends Component {
    */
   render() {
     const {
-      isCollectionDialogVisible, windowId, children,
+      isCollectionDialogVisible, windowId, children, className,
     } = this.props;
+
     return (
-      <StyledPrimaryWindowContainer data-testid="test-window" className={ns('primary-window')}>
+      <Root data-testid="test-window" className={classNames(ns('primary-window'), className)}>
         <WindowSideBar windowId={windowId} />
         <CompanionArea windowId={windowId} position="left" />
         { isCollectionDialogVisible && <CollectionDialog windowId={windowId} /> }
         <Suspense fallback={<div />}>
           {children || this.renderViewer()}
         </Suspense>
-      </StyledPrimaryWindowContainer>
+      </Root>
     );
   }
 }
@@ -98,6 +100,7 @@ export class PrimaryWindow extends Component {
 PrimaryWindow.propTypes = {
   audioResources: PropTypes.arrayOf(PropTypes.object), // eslint-disable-line react/forbid-prop-types
   children: PropTypes.node,
+  className: PropTypes.string,
   isCollection: PropTypes.bool,
   isCollectionDialogVisible: PropTypes.bool,
   isFetching: PropTypes.bool,
@@ -109,6 +112,7 @@ PrimaryWindow.propTypes = {
 PrimaryWindow.defaultProps = {
   audioResources: [],
   children: undefined,
+  className: undefined,
   isCollection: false,
   isCollectionDialogVisible: false,
   isFetching: false,
diff --git a/src/components/Window.js b/src/components/Window.js
index c2f6b3a5bb0527e3e68e77432bea9290c3c1ce10..2d654afd6937ed777e0e5c408b0efb8373c9fd1e 100644
--- a/src/components/Window.js
+++ b/src/components/Window.js
@@ -1,4 +1,4 @@
-import { Component } from 'react';
+import { Component, useContext } from 'react';
 import PropTypes from 'prop-types';
 import { styled } from '@mui/material/styles';
 import Paper from '@mui/material/Paper';
@@ -12,13 +12,25 @@ import ErrorContent from '../containers/ErrorContent';
 import IIIFAuthentication from '../containers/IIIFAuthentication';
 import { PluginHook } from './PluginHook';
 
+const rowMixin = {
+  display: 'flex',
+  flex: '1',
+  flexDirection: 'row',
+  minHeight: 0,
+};
+
+const columnMixin = {
+  display: 'flex',
+  flex: '1',
+  flexDirection: 'column',
+  minHeight: 0,
+};
+
 const Root = styled(Paper)(({ ownerState, theme }) => ({
+  ...columnMixin,
   backgroundColor: theme.palette.shades?.dark,
   borderRadius: 0,
-  display: 'flex',
-  flexDirection: 'column',
   height: '100%',
-  minHeight: 0,
   overflow: 'hidden',
   width: '100%',
   ...(ownerState?.maximized && {
@@ -29,41 +41,39 @@ const Root = styled(Paper)(({ ownerState, theme }) => ({
   }),
 }));
 
-const StyledMiddle = styled('div')(() => ({
-  display: 'flex',
-  flex: '1',
-  flexDirection: 'row',
-  minHeight: 0,
+const ContentRow = styled('div')(() => ({
+  ...rowMixin,
 }));
 
-const StyledMiddleLeft = styled('div')(() => ({
-  display: 'flex',
-  flex: '1',
-  flexDirection: 'column',
-  minHeight: 0,
+const ContentColumn = styled('div')(() => ({
+  ...columnMixin,
 }));
 
-const StyledPrimaryWindow = styled('div')(() => ({
-  display: 'flex',
-  flex: '1',
+const StyledPrimaryWindow = styled(PrimaryWindow)(() => ({
+  ...rowMixin,
   height: '300px',
-  minHeight: 0,
   position: 'relative',
 }));
 
-const StyledCompanionAreaBottom = styled('div')(() => ({
-  display: 'flex',
+const StyledCompanionAreaBottom = styled(CompanionArea)(() => ({
+  ...rowMixin,
   flex: '0',
   flexBasis: 'auto',
-  minHeight: 0,
 }));
 
 const StyledCompanionAreaRight = styled('div')(() => ({
-  display: 'flex',
+  ...rowMixin,
   flex: '0 1 auto',
-  minHeight: 0,
 }));
 
+/** Window title bar wrapper for drag controls in the mosaic view */
+const DraggableNavBar = ({ children, ...props }) => {
+  const { mosaicWindowActions } = useContext(MosaicWindowContext);
+  return mosaicWindowActions.connectDragSource(
+    <nav {...props}>{children}</nav>,
+  );
+};
+
 /**
  * Represents a Window in the mirador workspace
  * @param {object} window
@@ -81,40 +91,13 @@ export class Window extends Component {
     return { error, hasError: true };
   }
 
-  /**
-   * wrappedTopBar - will conditionally wrap a WindowTopBar for needed
-   * additional functionality based on workspace type
-   */
-  wrappedTopBar() {
-    const {
-      windowId, workspaceType, windowDraggable,
-    } = this.props;
-
-    const topBar = (
-      <div>
-        <WindowTopBar
-          windowId={windowId}
-          windowDraggable={windowDraggable}
-        />
-        <IIIFAuthentication windowId={windowId} />
-      </div>
-    );
-    if (workspaceType === 'mosaic' && windowDraggable) {
-      const { mosaicWindowActions } = this.context;
-      return mosaicWindowActions.connectDragSource(
-        topBar,
-      );
-    }
-    return topBar;
-  }
-
   /**
    * Renders things
    */
   render() {
     const {
       focusWindow, label, isFetching, sideBarOpen,
-      view, windowId, t,
+      view, windowDraggable, windowId, workspaceType, t,
       manifestError,
     } = this.props;
 
@@ -138,27 +121,28 @@ export class Window extends Component {
         className={ns('window')}
         aria-label={t('window', { label })}
       >
-        {this.wrappedTopBar()}
+        <WindowTopBar
+          component={workspaceType === 'mosaic' && windowDraggable ? DraggableNavBar : undefined}
+          windowId={windowId}
+          windowDraggable={windowDraggable}
+        />
+        <IIIFAuthentication windowId={windowId} />
         { manifestError && <ErrorContent error={{ stack: manifestError }} windowId={windowId} /> }
-        <StyledMiddle>
-          <StyledMiddleLeft>
-            <StyledPrimaryWindow>
-              <PrimaryWindow
-                view={view}
-                windowId={windowId}
-                isFetching={isFetching}
-                sideBarOpen={sideBarOpen}
-              />
-            </StyledPrimaryWindow>
-            <StyledCompanionAreaBottom>
-              <CompanionArea windowId={windowId} position="bottom" />
-            </StyledCompanionAreaBottom>
-          </StyledMiddleLeft>
+        <ContentRow>
+          <ContentColumn>
+            <StyledPrimaryWindow
+              view={view}
+              windowId={windowId}
+              isFetching={isFetching}
+              sideBarOpen={sideBarOpen}
+            />
+            <StyledCompanionAreaBottom windowId={windowId} position="bottom" />
+          </ContentColumn>
           <StyledCompanionAreaRight>
             <CompanionArea windowId={windowId} position="right" />
             <CompanionArea windowId={windowId} position="far-right" />
           </StyledCompanionAreaRight>
-        </StyledMiddle>
+        </ContentRow>
         <CompanionArea windowId={windowId} position="far-bottom" />
         <PluginHook {...this.props} />
       </Root>
diff --git a/src/components/WindowTopBar.js b/src/components/WindowTopBar.js
index abc496c2ccc00d24b239dcd978d61303e4ef137d..5e32f8cd0787303091ddba23f3fb1843cf6d40d6 100644
--- a/src/components/WindowTopBar.js
+++ b/src/components/WindowTopBar.js
@@ -45,10 +45,11 @@ export class WindowTopBar extends Component {
       removeWindow, windowId, toggleWindowSideBar, t,
       maximizeWindow, maximized, minimizeWindow, allowClose, allowMaximize,
       focusWindow, allowFullscreen, allowTopMenuButton, allowWindowSideBar,
+      component,
     } = this.props;
 
     return (
-      <Root component="nav" aria-label={t('windowNavigation')} position="relative" color="default" enableColorOnDark>
+      <Root component={component} aria-label={t('windowNavigation')} position="relative" color="default" enableColorOnDark>
         <StyledToolbar
           disableGutters
           onMouseDown={focusWindow}
@@ -106,6 +107,7 @@ WindowTopBar.propTypes = {
   allowMaximize: PropTypes.bool,
   allowTopMenuButton: PropTypes.bool,
   allowWindowSideBar: PropTypes.bool,
+  component: PropTypes.elementType,
   focused: PropTypes.bool, // eslint-disable-line react/no-unused-prop-types
   focusWindow: PropTypes.func,
   maximized: PropTypes.bool,
@@ -124,6 +126,7 @@ WindowTopBar.defaultProps = {
   allowMaximize: true,
   allowTopMenuButton: true,
   allowWindowSideBar: true,
+  component: 'nav',
   focused: false,
   focusWindow: () => {},
   maximized: false,