diff --git a/README.md b/README.md
index b7f7d9ee02e01f7ee3556072cc6dbed994dcbcd1..9c3807871ebe3b79db4788ce66a9c3a1e23c838b 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@
 $ npm start
 ```
 
-Then navigate to [http://127.0.0.1:4444/__tests__/integration/mirador/](http://127.0.0.1:4444/__tests__/integration/mirador/)
+Then navigate to [http://127.0.0.1:4444/\_\_tests\_\_/integration/mirador/](http://127.0.0.1:4444/\_\_tests\_\_/integration/mirador/)
 
 ### Instantiating Mirador
 
diff --git a/__tests__/src/components/ManifestListItem.test.js b/__tests__/src/components/ManifestListItem.test.js
index 2be1cd2218fd179df06542eefbea5ead915ca256..ee8d8891e4468c6f0d1d817739e90609bd5f1fc2 100644
--- a/__tests__/src/components/ManifestListItem.test.js
+++ b/__tests__/src/components/ManifestListItem.test.js
@@ -1,19 +1,23 @@
 import React from 'react';
 import { shallow } from 'enzyme';
-import { store } from '../../../src/store';
-import ManifestListItem from '../../../src/components/ManifestListItem';
+import { ManifestListItem } from '../../../src/components/ManifestListItem';
 
 describe('ManifestListItem', () => {
   it('renders without an error', () => {
-    const wrapper = shallow(<ManifestListItem manifest="http://example.com" store={store} />).dive();
+    const addWindow = jest.fn();
+    const wrapper = shallow(
+      <ManifestListItem manifest="http://example.com" addWindow={addWindow} />,
+    );
     expect(wrapper.find('li.mirador-manifest-list-item').length).toBe(1);
     expect(wrapper.find('button').length).toBe(1);
     expect(wrapper.find('button').text()).toEqual('http://example.com');
   });
   it('updates and adds window when button clicked', () => {
-    const wrapper = shallow(<ManifestListItem manifest="http://example.com" store={store} />).dive();
-    expect(store.getState().windows.length).toEqual(0);
+    const addWindow = jest.fn();
+    const wrapper = shallow(
+      <ManifestListItem manifest="http://example.com" addWindow={addWindow} />,
+    );
     wrapper.find('button').simulate('click');
-    expect(store.getState().windows.length).toEqual(1);
+    expect(addWindow).toHaveBeenCalledTimes(1);
   });
 });
diff --git a/__tests__/src/components/ViewerNavigation.test.js b/__tests__/src/components/ViewerNavigation.test.js
index 407f5f33f7a0cb950b3b240037ef97ab0ee65f96..5e6408cddb3eb90ae2f10be6163828c1f13cb63b 100644
--- a/__tests__/src/components/ViewerNavigation.test.js
+++ b/__tests__/src/components/ViewerNavigation.test.js
@@ -1,6 +1,5 @@
 import React from 'react';
 import { shallow } from 'enzyme';
-import { store } from '../../../src/store';
 import { ViewerNavigation } from '../../../src/components/ViewerNavigation';
 
 describe('ViewerNavigation', () => {
diff --git a/__tests__/src/components/WindowTopBar.test.js b/__tests__/src/components/WindowTopBar.test.js
index c03aeae9695da95d4bf727b3e77d1ba55ccc543f..0940b2ad113b3c9ca02b1adb8ebdddd4655293d3 100644
--- a/__tests__/src/components/WindowTopBar.test.js
+++ b/__tests__/src/components/WindowTopBar.test.js
@@ -1,28 +1,36 @@
 import React from 'react';
-import { mount } from 'enzyme';
-import { actions, store } from '../../../src/store';
-import WindowTopBar from '../../../src/components/WindowTopBar';
-import fixture from '../../fixtures/24.json';
+import { shallow } from 'enzyme';
+import { WindowTopBar } from '../../../src/components/WindowTopBar';
 
-describe('Window', () => {
-  let wrapper;
-  let window;
+const manifestFixture = {
+  manifestation: {
+    getLabel: () => [{ value: 'Fixture Label' }],
+  },
+};
+
+describe('WindowTopBar', () => {
+  let topBar;
+  let mockRemoveWindow;
   beforeEach(() => {
-    store.dispatch(actions.receiveManifest('foo', fixture));
-    store.dispatch(actions.addWindow({ manifestId: 'foo' }));
-    const manifest = store.getState().manifests.foo;
-    [window] = store.getState().windows;
-    wrapper = mount(
-      <WindowTopBar store={store} manifest={manifest} windowId={window.id} />,
-      // We need to attach this to something created by our JSDOM instance.
-      // Also need to provide context of the store so that connected sub components
-      // can render effectively.
-      { attachTo: document.getElementById('main'), context: { store } },
+    mockRemoveWindow = jest.fn();
+    topBar = shallow(
+      <WindowTopBar
+        manifest={manifestFixture}
+        windowId="foo"
+        removeWindow={mockRemoveWindow}
+      />,
     );
   });
 
   it('renders without an error', () => {
-    expect(wrapper.find('div.mirador-window-top-bar h3').text()).toBe('Test 24 Manifest: Image with IIIF Service - adapted with real image');
-    expect(wrapper.find('button.mirador-window-close'));
+    expect(topBar.find('div.mirador-window-top-bar h3')
+      .text()).toBe('Fixture Label');
+    expect(topBar.find('button.mirador-window-close'));
+  });
+
+  it('calls the removeWindow prop when the close button is clicked', () => {
+    topBar.find('button').simulate('click');
+    expect(mockRemoveWindow).toHaveBeenCalledTimes(1);
+    expect(mockRemoveWindow).toHaveBeenCalledWith('foo');
   });
 });
diff --git a/__tests__/src/components/WorkspaceControlPanel.test.js b/__tests__/src/components/WorkspaceControlPanel.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..6e26b9fde4828d83f007cd3156d9f0bd7b531466
--- /dev/null
+++ b/__tests__/src/components/WorkspaceControlPanel.test.js
@@ -0,0 +1,26 @@
+import React from 'react';
+import { shallow } from 'enzyme';
+import { actions, store } from '../../../src/store';
+import WorkspaceControlPanel from '../../../src/components/WorkspaceControlPanel';
+import fixture from '../../fixtures/2.json';
+
+describe('WorkspaceControlPanel', () => {
+  let wrapper;
+  beforeEach(() => {
+    store.dispatch(actions.receiveManifest('foo', fixture));
+    store.dispatch(actions.receiveManifest('bar', fixture));
+    wrapper = shallow(<WorkspaceControlPanel store={store} />).dive();
+  });
+
+  it('renders without an error', () => {
+    expect(wrapper.find('div.mirador-workspace-control-panel').length).toBe(1);
+  });
+
+  it('renders a list item for each manifest in the state', () => {
+    expect(wrapper.find('ul Connect(ManifestListItem)').length).toBe(2);
+  });
+
+  it('renders a Display component', () => {
+    expect(wrapper.find('Display').length).toBe(1);
+  });
+});
diff --git a/package.json b/package.json
index 4891e9bf1f67580188d14a651fead86973f82558..d312076b2ce5991f1c1513fc2e7e8d144404b464 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
   "description": "",
   "main": "index.js",
   "scripts": {
-    "lint": "node_modules/.bin/eslint ./",
+    "lint": "node_modules/.bin/eslint ./ && node_modules/.bin/sass-lint -v ./src/styles/**/*",
     "server": "node_modules/.bin/http-server",
     "pretest": "npm run server:json",
     "posttest": "node ./scripts/json-server/kill-server.js",
@@ -24,7 +24,7 @@
   "repository": "https://github.com/ProjectMirador/mirador",
   "dependencies": {
     "css-ns": "^1.2.2",
-    "deepmerge": "^3.0.0",
+    "deepmerge": "^3.1.0",
     "manifesto.js": "^3.0.9",
     "node-fetch": "2.1.1",
     "node-sass": "^4.9.2",
@@ -60,7 +60,7 @@
     "eslint-plugin-import": "^2.14.0",
     "eslint-plugin-jest": "^22.1.2",
     "eslint-plugin-jsx-a11y": "^6.1.2",
-    "eslint-plugin-react": "^7.11.1",
+    "eslint-plugin-react": "^7.12.4",
     "http-server": "^0.11.1",
     "jest": "^22.4.4",
     "jest-fetch-mock": "^1.5.0",
@@ -69,6 +69,7 @@
     "puppeteer": "^1.4.0",
     "react-dev-utils": "^6.1.1",
     "redux-mock-store": "^1.5.1",
+    "sass-lint": "^1.12.1",
     "style-loader": "^0.22.1",
     "terser-webpack-plugin": "^1.2.1",
     "webpack": "^4.27.1",
diff --git a/src/components/App.js b/src/components/App.js
index 1c9743ca35587e370f9a13301d37639b229e2d9f..735d989aeebb2ef9e5abbed7dff9827a44c3078e 100644
--- a/src/components/App.js
+++ b/src/components/App.js
@@ -1,10 +1,7 @@
 import React, { Component } from 'react';
 import { connect } from 'react-redux';
-import PropTypes from 'prop-types';
 import { actions } from '../store';
-import Display from './Display';
-import ManifestForm from './ManifestForm';
-import ManifestListItem from './ManifestListItem';
+import WorkspaceControlPanel from './WorkspaceControlPanel';
 import Workspace from './Workspace';
 import ns from '../config/css-ns';
 
@@ -12,85 +9,21 @@ import ns from '../config/css-ns';
  * This is the top level Mirador component.
  * @prop {Object} manifests
  */
-class App extends Component {
-  /**
-   * constructor -
-   */
-  constructor(props) {
-    super(props);
-    this.state = {
-      lastRequested: '',
-    };
-
-    this.setLastRequested = this.setLastRequested.bind(this);
-  }
-
-  /**
-   * setLastRequested - Sets the state lastRequested
-   *
-   * @private
-   */
-  setLastRequested(requested) {
-    this.setState({
-      lastRequested: requested,
-    });
-  }
-
-  /**
-   * computedContent - computes the content to be displayed based on logic
-   *
-   * @return {type}  description
-   * @private
-   */
-  computedContent() {
-    const { manifests } = this.props;
-    const { lastRequested } = this.state;
-    const manifest = manifests[lastRequested];
-    if (manifest) {
-      if (manifest.isFetching) {
-        return '☕';
-      }
-      if (manifest.error) {
-        return manifest.error.message;
-      }
-      return JSON.stringify(manifest.json, 0, 2);
-    }
-    return 'Nothing Selected Yet';
-  }
-
+export class App extends Component {
   /**
    * render
    * @return {String} - HTML markup for the component
    */
   render() {
-    const { manifests } = this.props;
-    const { lastRequested } = this.state;
-    const manifestList = Object.keys(manifests).map(manifest => (
-      <ManifestListItem
-        key={manifest}
-        manifest={manifest}
-      />
-    ));
     return (
       <div className={ns('app')}>
         <Workspace />
-        <div className={ns('control-panel')}>
-          <ManifestForm setLastRequested={this.setLastRequested} />
-          <ul>{manifestList}</ul>
-
-          <Display
-            manifest={manifests[lastRequested]}
-          />
-        </div>
+        <WorkspaceControlPanel />
       </div>
     );
   }
 }
 
-App.propTypes = {
-  manifests: PropTypes.instanceOf(Object).isRequired,
-};
-
 /**
  * mapStateToProps - to hook up connect
  * @memberof App
@@ -107,11 +40,7 @@ const mapStateToProps = state => (
  * @memberof App
  * @private
  */
-const mapDispatchToProps = dispatch => ({
-  fetchManifest: manifestUrl => (
-    dispatch(actions.fetchManifest(manifestUrl))
-  ),
-});
+const mapDispatchToProps = { fetchManifest: actions.fetchManifest };
 
 export default connect(
   mapStateToProps,
diff --git a/src/components/ManifestForm.js b/src/components/ManifestForm.js
index 54f1557e96ec08d11bc9792c6c526d7cdd132d69..380027ee24961c0005ae77553244814de6b7cec5 100644
--- a/src/components/ManifestForm.js
+++ b/src/components/ManifestForm.js
@@ -8,7 +8,7 @@ import { actions } from '../store';
  * @prop {Function} fetchManifest
  * @prop {Function} setLastRequested
  */
-class ManifestForm extends Component {
+export class ManifestForm extends Component {
   /**
    * constructor -
    */
@@ -87,11 +87,7 @@ const mapStateToProps = () => (
  * @memberof ManifestForm
  * @private
  */
-const mapDispatchToProps = dispatch => ({
-  fetchManifest: manifestUrl => (
-    dispatch(actions.fetchManifest(manifestUrl))
-  ),
-});
+const mapDispatchToProps = { fetchManifest: actions.fetchManifest };
 
 export default connect(
   mapStateToProps,
diff --git a/src/components/ManifestListItem.js b/src/components/ManifestListItem.js
index b67886e8d869abb540943b088ef0246b6dcef84e..0c47f9bce9a56d6a0c1ee622c01e416eb91a67fc 100644
--- a/src/components/ManifestListItem.js
+++ b/src/components/ManifestListItem.js
@@ -23,7 +23,7 @@ const handleOpenButtonClick = (event, manifest, addWindow) => {
  * @memberof ManifestListItem
  * @private
  */
-const ManifestListItem = ({ manifest, addWindow }) => (
+export const ManifestListItem = ({ manifest, addWindow }) => (
   <li className={ns('manifest-list-item')}>
     <button type="button" onClick={event => handleOpenButtonClick(event, manifest, addWindow)}>
       {manifest}
@@ -50,11 +50,7 @@ const mapStateToProps = () => (
  * @memberof ManifestListItem
  * @private
  */
-const mapDispatchToProps = dispatch => ({
-  addWindow: options => (
-    dispatch(actions.addWindow(options))
-  ),
-});
+const mapDispatchToProps = { addWindow: actions.addWindow };
 
 export default connect(
   mapStateToProps,
diff --git a/src/components/OpenSeadragonViewer.js b/src/components/OpenSeadragonViewer.js
index a707af25b8572abbb3e997e33b79bb7eb567d1eb..7a528034c84c4a18723e9b6a2d240095d9e72703 100644
--- a/src/components/OpenSeadragonViewer.js
+++ b/src/components/OpenSeadragonViewer.js
@@ -1,4 +1,4 @@
-import React, { Component, Fragment } from 'react';
+import React, { Component } from 'react';
 import PropTypes from 'prop-types';
 import OpenSeadragon from 'openseadragon';
 import miradorWithPlugins from '../lib/miradorWithPlugins';
@@ -8,7 +8,7 @@ import ns from '../config/css-ns';
  * Represents a OpenSeadragonViewer in the mirador workspace. Responsible for mounting
  * and rendering OSD.
  */
-class OpenSeadragonViewer extends Component {
+export class OpenSeadragonViewer extends Component {
   /**
    * @param {Object} props
    */
@@ -70,13 +70,13 @@ class OpenSeadragonViewer extends Component {
   render() {
     const { window } = this.props;
     return (
-      <Fragment>
+      <>
         <div
           className={ns('osd-container')}
           id={`${window.id}-osd`}
           ref={this.ref}
         />
-      </Fragment>
+      </>
     );
   }
 }
diff --git a/src/components/ViewerNavigation.js b/src/components/ViewerNavigation.js
index a84b4895427249039baa88aa8c9a9e1779f18fc9..11b54337639169dfd9baa546bb14233bbd27053b 100644
--- a/src/components/ViewerNavigation.js
+++ b/src/components/ViewerNavigation.js
@@ -85,9 +85,9 @@ ViewerNavigation.propTypes = {
  * @memberof ManifestForm
  * @private
  */
-const mapDispatchToProps = dispatch => ({
-  nextCanvas: windowId => dispatch(actions.nextCanvas(windowId)),
-  previousCanvas: windowId => dispatch(actions.previousCanvas(windowId)),
-});
+const mapDispatchToProps = {
+  nextCanvas: actions.nextCanvas,
+  previousCanvas: actions.previousCanvas,
+};
 
 export default connect(null, mapDispatchToProps)(miradorWithPlugins(ViewerNavigation));
diff --git a/src/components/Window.js b/src/components/Window.js
index c524dded55ffd1792a49a70ad0a9b465b85dada0..7b181c480d455a2202fd217997a24db58f054f59 100644
--- a/src/components/Window.js
+++ b/src/components/Window.js
@@ -3,7 +3,7 @@ import { connect } from 'react-redux';
 import PropTypes from 'prop-types';
 import ns from '../config/css-ns';
 import WindowBackground from './WindowBackground';
-import WindowTopBar from './WindowTopBar';
+import ConnectedWindowTopBar from './WindowTopBar';
 import WindowViewer from './WindowViewer';
 
 /**
@@ -26,7 +26,7 @@ class Window extends Component {
    */
   renderViewer() {
     const { manifest, window } = this.props;
-    if (manifest) {
+    if (manifest && manifest.isFetching === false) {
       return (
         <WindowViewer
           window={window}
@@ -44,7 +44,7 @@ class Window extends Component {
     const { manifest, window } = this.props;
     return (
       <div className={ns('window')} style={this.styleAttributes()}>
-        <WindowTopBar
+        <ConnectedWindowTopBar
           windowId={window.id}
           manifest={manifest}
         />
diff --git a/src/components/WindowTopBar.js b/src/components/WindowTopBar.js
index 19b7e35664508b44497f789a65e4c051f9df3c55..3bab8cd5afab2eda1a35293f16a605c272883b8f 100644
--- a/src/components/WindowTopBar.js
+++ b/src/components/WindowTopBar.js
@@ -2,14 +2,14 @@ import React, { Component } from 'react';
 import { connect } from 'react-redux';
 import PropTypes from 'prop-types';
 import { actions } from '../store';
-import WindowTopBarButtons from './WindowTopBarButtons';
+import ConnectedWindowTopBarButtons from './WindowTopBarButtons';
 import miradorWithPlugins from '../lib/miradorWithPlugins';
 import ns from '../config/css-ns';
 
 /**
  * WindowTopBar
  */
-class WindowTopBar extends Component {
+export class WindowTopBar extends Component {
   /**
    * titleContent
    *
@@ -32,7 +32,7 @@ class WindowTopBar extends Component {
     return (
       <div className={ns('window-top-bar')}>
         <h3>{this.titleContent()}</h3>
-        <WindowTopBarButtons windowId={windowId} />
+        <ConnectedWindowTopBarButtons windowId={windowId} />
         <button type="button" className={ns('window-close')} aria-label="Close Window" onClick={() => removeWindow(windowId)}>&times;</button>
       </div>
     );
@@ -44,11 +44,7 @@ class WindowTopBar extends Component {
  * @memberof ManifestListItem
  * @private
  */
-const mapDispatchToProps = dispatch => ({
-  removeWindow: windowId => (
-    dispatch(actions.removeWindow(windowId))
-  ),
-});
+const mapDispatchToProps = { removeWindow: actions.removeWindow };
 
 WindowTopBar.propTypes = {
   manifest: PropTypes.object, // eslint-disable-line react/forbid-prop-types
diff --git a/src/components/WindowTopBarButtons.js b/src/components/WindowTopBarButtons.js
index 6bcdef6b45cd95ca78df88b7dd221d597ef62b65..b6f056d38e8d15e0fad34a120ed60ba50d7e2e47 100644
--- a/src/components/WindowTopBarButtons.js
+++ b/src/components/WindowTopBarButtons.js
@@ -1,18 +1,17 @@
-import React, { Component, Fragment } from 'react';
+import React, { Component } from 'react';
 import miradorWithPlugins from '../lib/miradorWithPlugins';
+
 /**
  *
  */
-class WindowTopBarButtons extends Component {
+export class WindowTopBarButtons extends Component {
   /**
    * render
    *
    * @return {type}  description
    */
   render() {
-    return (
-      <Fragment />
-    );
+    return (<></>);
   }
 }
 
diff --git a/src/components/WindowViewer.js b/src/components/WindowViewer.js
index 1e157eeca7eb5e6d6fed6ad4d055ccf43dd164e4..4d2ea86fd1a7d28b4119a1b8861a5c8272940e6f 100644
--- a/src/components/WindowViewer.js
+++ b/src/components/WindowViewer.js
@@ -1,9 +1,9 @@
-import React, { Component, Fragment } from 'react';
+import React, { Component } from 'react';
 import PropTypes from 'prop-types';
 import { connect } from 'react-redux';
 import { actions } from '../store';
 import miradorWithPlugins from '../lib/miradorWithPlugins';
-import OpenSeadragonViewer from './OpenSeadragonViewer';
+import ConnectedOSDViewer from './OpenSeadragonViewer';
 import ConnectedViewerNavigation from './ViewerNavigation';
 
 /**
@@ -80,13 +80,13 @@ class WindowViewer extends Component {
   render() {
     const { window } = this.props;
     return (
-      <Fragment>
-        <OpenSeadragonViewer
+      <>
+        <ConnectedOSDViewer
           tileSources={this.tileInfoFetchedFromStore()}
           window={window}
         />
         <ConnectedViewerNavigation window={window} canvases={this.canvases} />
-      </Fragment>
+      </>
     );
   }
 }
@@ -107,9 +107,7 @@ const mapStateToProps = state => (
  * @memberof WindowViewer
  * @private
  */
-const mapDispatchToProps = dispatch => ({
-  fetchInfoResponse: infoId => dispatch(actions.fetchInfoResponse(infoId)),
-});
+const mapDispatchToProps = { fetchInfoResponse: actions.fetchInfoResponse };
 
 WindowViewer.propTypes = {
   infoResponses: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
diff --git a/src/components/WorkspaceControlPanel.js b/src/components/WorkspaceControlPanel.js
new file mode 100644
index 0000000000000000000000000000000000000000..da97568bc9b22a7dd019f4a9b1c7d8ade313cef5
--- /dev/null
+++ b/src/components/WorkspaceControlPanel.js
@@ -0,0 +1,77 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import { connect } from 'react-redux';
+import Display from './Display';
+import ConnectedManifestForm from './ManifestForm';
+import ConnectedManifestListItem from './ManifestListItem';
+import ns from '../config/css-ns';
+
+/**
+ * Provides the panel responsible for controlling the entire workspace
+ */
+class WorkspaceControlPanel extends Component {
+  /**
+   * constructor -
+   */
+  constructor(props) {
+    super(props);
+    this.state = {
+      lastRequested: '',
+    };
+
+    this.setLastRequested = this.setLastRequested.bind(this);
+  }
+
+  /**
+   * setLastRequested - Sets the state lastRequested
+   *
+   * @private
+   */
+  setLastRequested(requested) {
+    this.setState({
+      lastRequested: requested,
+    });
+  }
+
+  /**
+   * render
+   * @return {String} - HTML markup for the component
+   */
+  render() {
+    const { manifests } = this.props;
+    const { lastRequested } = this.state;
+    const manifestList = Object.keys(manifests).map(manifest => (
+      <ConnectedManifestListItem
+        key={manifest}
+        manifest={manifest}
+      />
+    ));
+    return (
+      <div className={ns('workspace-control-panel')}>
+        <ConnectedManifestForm setLastRequested={this.setLastRequested} />
+        <ul>{manifestList}</ul>
+
+        <Display
+          manifest={manifests[lastRequested]}
+        />
+      </div>
+    );
+  }
+}
+
+WorkspaceControlPanel.propTypes = {
+  manifests: PropTypes.instanceOf(Object).isRequired,
+};
+
+/**
+ * mapStateToProps - to hook up connect
+ * @memberof WorkspaceControlPanel
+ * @private
+ */
+const mapStateToProps = state => (
+  {
+    manifests: state.manifests,
+  }
+);
+
+export default connect(mapStateToProps)(WorkspaceControlPanel);
diff --git a/src/init.js b/src/init.js
index 0744dd999cdd5cec9a1d09bd57e63deea5b6a06d..fb42874b70d44249213c6f12f176b883305e5cd2 100644
--- a/src/init.js
+++ b/src/init.js
@@ -2,7 +2,7 @@ import React from 'react';
 import ReactDOM from 'react-dom';
 import { Provider } from 'react-redux';
 import deepmerge from 'deepmerge';
-import App from './components/App';
+import ConnectedApp from './components/App';
 import createRootReducer from './reducers/index';
 import { store, actions } from './store';
 import settings from './config/settings';
@@ -57,7 +57,7 @@ export default function (config) {
 
   ReactDOM.render(
     <Provider store={store}>
-      <App config={config} />
+      <ConnectedApp config={config} />
     </Provider>,
     document.getElementById(config.id),
   );
diff --git a/src/lib/miradorWithPlugins.js b/src/lib/miradorWithPlugins.js
index 16a9619ffcb0ae5986ee3193ab56553bfd4a17b1..8bb3a22618b52ce70a6e2a678c20ec054e6e71da 100644
--- a/src/lib/miradorWithPlugins.js
+++ b/src/lib/miradorWithPlugins.js
@@ -1,4 +1,4 @@
-import React, { Component, Fragment } from 'react';
+import React, { Component } from 'react';
 import PropTypes from 'prop-types';
 import { connect } from 'react-redux';
 import componentPlugins from './componentPlugins';
@@ -34,7 +34,7 @@ export default function miradorWithPlugins(WrappedComponent) {
       const { config } = this.props;
       const { plugins } = config;
       return (
-        <Fragment>
+        <>
           <WrappedComponent {...this.props} ref={(parent) => { this.pluginParent = parent; }} />
           { /* TODO: Refactor .name here in some way so we dont need to rely on it */}
           {componentPlugins(WrappedComponent.name, plugins)
@@ -43,7 +43,7 @@ export default function miradorWithPlugins(WrappedComponent) {
               { key: component.name, ...this.props, pluginParent: this.getPluginParent },
             ))
           }
-        </Fragment>
+        </>
       );
     }
   }
diff --git a/src/styles/index.scss b/src/styles/index.scss
index f37eb5dc2f4a4d823401ae7b2cf93931f407bbd7..5f05992a46c70a908ad9f6a2f79b0079b54d9754 100644
--- a/src/styles/index.scss
+++ b/src/styles/index.scss
@@ -1,42 +1,44 @@
+@import 'variables';
+
 body {
-  background: white;
+  background: $white;
   height: 100%;
 }
 
 .mirador {
-  &-control-panel {
-    position: absolute;
+  &-workspace-control-panel {
+    border-right: 2px solid $black;
+    bottom: 0;
     box-sizing: border-box;
+    left: 0;
+    margin: 0;
     padding: 15px;
-    margin:0px;
-    left:0;
-    top:0;
-    bottom:0;
+    position: absolute;
+    top: 0;
     width: 300px;
-    border-right: 2px solid black;
   }
 
   &-workspace {
-    position: absolute;
+    bottom: 0;
     box-sizing: border-box;
+    left: 0;
     margin: 0;
-    padding-left: 300px;
-    top:0;
-    right:0;
-    bottom:0;
-    left:0;
     overflow: scroll;
+    padding-left: 300px;
+    position: absolute;
+    right: 0;
+    top: 0;
   }
 
   &-window {
-    border: 1px solid black;
+    border: 1px solid $black;
     overflow: hidden;
     position: relative;
   }
 
   &-window-top-bar {
-    background: linear-gradient(to bottom, rgba(0, 0, 0, .65) 0%, rgba(0, 0, 0, 0) 100%);
-    color: white;
+    background: linear-gradient(to bottom, $window-top-bar-gradient-top 0%, $window-top-bar-gradient-bottom 100%);
+    color: $white;
     position: absolute;
     z-index: 10;
 
@@ -46,7 +48,7 @@ body {
   }
 
   &-osd-container {
-    background: gray;
+    background: $gray;
     bottom: 0;
     height: 100%;
     position: absolute;
diff --git a/src/styles/variables.scss b/src/styles/variables.scss
new file mode 100644
index 0000000000000000000000000000000000000000..a680a465819ad2d6bbfe498d8a8cb137837ba11f
--- /dev/null
+++ b/src/styles/variables.scss
@@ -0,0 +1,5 @@
+$black: #000;
+$gray: #808080;
+$white: #fff;
+$window-top-bar-gradient-top: rgba(0, 0, 0, .65);
+$window-top-bar-gradient-bottom: rgba(0, 0, 0, 0);