diff --git a/.vscode/settings.json b/.vscode/settings.json
index a2863bc..476b51e 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,3 +1,3 @@
 {
-  "cSpell.words": ["resumarkdown", "spacebar"]
+  "cSpell.words": ["resumarkdown", "spacebar", "testid"]
 }
diff --git a/src/lib/components/content.svelte b/src/lib/components/content.svelte
index 50a2d64..9c46146 100644
--- a/src/lib/components/content.svelte
+++ b/src/lib/components/content.svelte
@@ -3,6 +3,8 @@
 
   export let pane: Pane;
 
+  export let testid: string | undefined = undefined;
+
   // don't show pane if we're not the current pane
   let hidden: boolean;
   $: hidden = pane !== $navStore;
@@ -12,7 +14,9 @@
   $: preview = pane === 'preview';
 </script>
 
-<div id={`pane-${pane}`} role="tabpanel" class:hidden class:preview><slot /></div>
+<div id={`pane-${pane}`} data-testid={testid} role="tabpanel" class:hidden class:preview>
+  <slot />
+</div>
 
 <style lang="less">
   div {
diff --git a/src/lib/components/nav-item.svelte b/src/lib/components/nav-item.svelte
index d4017e4..61965a8 100644
--- a/src/lib/components/nav-item.svelte
+++ b/src/lib/components/nav-item.svelte
@@ -6,6 +6,10 @@
   let selected: boolean;
   $: selected = destination === $pane;
 
+  // we need to hide the "preview" tab on desktop
+  let hiddenOnDesktop: boolean;
+  $: hiddenOnDesktop = destination === 'preview';
+
   function handleKey({ key }: KeyboardEvent) {
     if (key === ' ' || key === 'Enter' || key === 'Spacebar') {
       navigate();
@@ -22,6 +26,7 @@
   aria-selected={selected}
   role="tab"
   tabindex="0"
+  class:hiddenOnDesktop
   class:selected
   on:click={navigate}
   on:keyup={handleKey}
@@ -39,6 +44,10 @@
 
     @media screen and (min-width: @sizes[lg]) {
       flex-grow: 1;
+
+      &.hiddenOnDesktop {
+        display: none;
+      }
     }
 
     &.selected {
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 4e20d35..318da54 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -22,13 +22,13 @@
     </NavTree>
   </header>
   <main>
-    <Content pane="content">
+    <Content pane="content" testid="content-pane">
       <CodeInput bind:code={markdown} />
     </Content>
-    <Content pane="style">
+    <Content pane="style" testid="style-pane">
       <CodeInput bind:code={stylesheet} />
     </Content>
-    <Content pane="preview">
+    <Content pane="preview" testid="preview-pane">
       <dl>
         <dt>markdown:</dt>
         <dd>{markdown !== '' ? markdown : '???'}</dd>
diff --git a/tests/desktop.test.ts b/tests/desktop.test.ts
index d13abb0..fdc0a5c 100644
--- a/tests/desktop.test.ts
+++ b/tests/desktop.test.ts
@@ -14,3 +14,8 @@ test('desktop page has two-column layout', async ({ page }) => {
   await page.goto('/');
   await expect(page.locator('#pane-preview')).toBeVisible();
 });
+
+test('desktop page has no "preview" nav item', async ({ page }) => {
+  await page.goto('/');
+  await expect(page.getByRole('tab').filter({ hasText: 'preview' })).toBeHidden();
+});
diff --git a/tests/general.test.ts b/tests/general.test.ts
index b05fcee..bf617d6 100644
--- a/tests/general.test.ts
+++ b/tests/general.test.ts
@@ -9,14 +9,9 @@ test('page has headline', async ({ page }) => {
 
 test('nav items work', async ({ page }) => {
   await page.goto('/');
-  let lastPane = '#pane-preview';
-  for (const pane of ['content', 'style', 'preview']) {
-    const currentPaneId = `pane-${pane}`;
-    await page.locator(`nav li[aria-controls="${currentPaneId}"]`).click();
-    await expect(page.locator(`#${currentPaneId}`)).toBeVisible();
-    if (lastPane !== '#pane-preview') {
-      await expect(page.locator(lastPane)).toBeHidden();
-    }
-    lastPane = `#${currentPaneId}`;
+
+  for (const tab of await page.getByRole('tab').all()) {
+    await tab.click();
+    await expect(page.getByTestId(`${await tab.textContent()}-pane`)).toBeVisible();
   }
 });
diff --git a/tests/mobile.test.ts b/tests/mobile.test.ts
index ba4a128..03d5cee 100644
--- a/tests/mobile.test.ts
+++ b/tests/mobile.test.ts
@@ -24,3 +24,9 @@ test('mobile page has single-column layout', async ({ page }) => {
   await page.goto('/');
   await expect(page.locator('#pane-preview')).toBeHidden();
 });
+
+test('mobile page has preview nav item', async ({ page }) => {
+  await page.goto('/');
+  await page.getByText('show navigation').click();
+  await expect(page.getByRole('tab').filter({ hasText: 'preview' })).toBeVisible();
+});
