diff --git a/ui/src/components/layout/Layout.tsx b/ui/src/components/layout/Layout.tsx
index cbb81d7..bda920a 100644
--- a/ui/src/components/layout/Layout.tsx
+++ b/ui/src/components/layout/Layout.tsx
@@ -4,7 +4,7 @@ import React from 'react'
 import { Helmet } from 'react-helmet'
 import Header from '../header/Header'
 import { Authorized } from '../routes/AuthorizedRoute'
-import { SidebarProvider } from '../sidebar/Sidebar'
+import { Sidebar, SidebarProvider } from '../sidebar/Sidebar'
 import MainMenu from './MainMenu'
 
 export const ADMIN_QUERY = gql`
@@ -40,7 +40,7 @@ const Layout = ({ children, title, ...otherProps }: LayoutProps) => {
             <div className="h-6"></div>
           </div>
         </div>
-        {/* <Sidebar /> */}
+        <Sidebar />
       </div>
     </SidebarProvider>
   )
diff --git a/ui/src/components/sidebar/MediaSidebar.tsx b/ui/src/components/sidebar/MediaSidebar.tsx
index dedb8f8..c9db381 100644
--- a/ui/src/components/sidebar/MediaSidebar.tsx
+++ b/ui/src/components/sidebar/MediaSidebar.tsx
@@ -25,6 +25,7 @@ import {
 } from './__generated__/sidebarPhoto'
 
 import { sidebarDownloadQuery_media_downloads } from './__generated__/sidebarDownloadQuery'
+import SidebarHeader from './SidebarHeader'
 
 const SIDEBAR_MEDIA_QUERY = gql`
   query sidebarPhoto($id: ID!) {
@@ -87,13 +88,6 @@ const SIDEBAR_MEDIA_QUERY = gql`
   }
 `
 
-const PreviewImageWrapper = styled.div<{ imageAspect: number }>`
-  width: 100%;
-  height: 0;
-  padding-top: ${({ imageAspect }) => Math.min(imageAspect, 0.75) * 100}%;
-  position: relative;
-`
-
 const PreviewImage = styled(ProtectedImage)`
   position: absolute;
   width: 100%;
@@ -134,12 +128,6 @@ const PreviewMedia = ({ media, previewImage }: PreviewMediaProps) => {
   return <div>ERROR: Unknown media type: {media.type}</div>
 }
 
-const Name = styled.div`
-  text-align: center;
-  font-size: 1.2rem;
-  margin: 0.75rem 0 1rem;
-`
-
 const MetadataInfoContainer = styled.div`
   margin-bottom: 1.5rem;
 `
@@ -155,7 +143,7 @@ export const MetadataInfo = ({ media }: MediaInfoProps) => {
   const exifName = exifNameLookup(t)
 
   if (media?.exif) {
-    const mediaExif = (media?.exif as unknown) as {
+    const mediaExif = media?.exif as unknown as {
       [key: string]: string | number | null
     }
 
@@ -212,7 +200,7 @@ export const MetadataInfo = ({ media }: MediaInfoProps) => {
 
   let videoMetadataItems: JSX.Element[] = []
   if (media?.videoMetadata) {
-    const videoMetadata = (media.videoMetadata as unknown) as {
+    const videoMetadata = media.videoMetadata as unknown as {
       [key: string]: string | number | null
     }
 
@@ -371,16 +359,21 @@ const SidebarContent = ({ media, hidePreview }: SidebarContentProps) => {
 
   return (
     <div>
-      {!hidePreview && (
-        <PreviewImageWrapper imageAspect={imageAspect}>
-          <PreviewMedia
-            previewImage={previewImage || undefined}
-            media={media}
-          />
-          <SidebarFacesOverlay media={media} />
-        </PreviewImageWrapper>
-      )}
-      <Name>{media.title}</Name>
+      <SidebarHeader title={media.title ?? 'Loading...'} />
+      <div className="lg:mx-4">
+        {!hidePreview && (
+          <div
+            className="w-full h-0 relative"
+            style={{ paddingTop: `${Math.min(imageAspect, 0.75) * 100}%` }}
+          >
+            <PreviewMedia
+              previewImage={previewImage || undefined}
+              media={media}
+            />
+            <SidebarFacesOverlay media={media} />
+          </div>
+        )}
+      </div>
       <MetadataInfo media={media} />
       <SidebarDownload media={media} />
       <SidebarPhotoShare id={media.id} />
@@ -418,10 +411,8 @@ type MediaSidebarType = {
 }
 
 const MediaSidebar = ({ media, hidePreview }: MediaSidebarType) => {
-  const [loadMedia, { loading, error, data }] = useLazyQuery<
-    sidebarPhoto,
-    sidebarPhotoVariables
-  >(SIDEBAR_MEDIA_QUERY)
+  const [loadMedia, { loading, error, data }] =
+    useLazyQuery<sidebarPhoto, sidebarPhotoVariables>(SIDEBAR_MEDIA_QUERY)
 
   useEffect(() => {
     if (media != null && authToken()) {
diff --git a/ui/src/components/sidebar/Sidebar.tsx b/ui/src/components/sidebar/Sidebar.tsx
index 34b3373..ad1a90b 100644
--- a/ui/src/components/sidebar/Sidebar.tsx
+++ b/ui/src/components/sidebar/Sidebar.tsx
@@ -1,41 +1,4 @@
-import React, { createContext, useContext, useState } from 'react'
-import styled from 'styled-components'
-import { Icon } from 'semantic-ui-react'
-
-const SidebarContainer = styled.div<{ highlighted: boolean }>`
-  width: 28vw;
-  max-width: 500px;
-  min-width: 300px;
-  flex-shrink: 0;
-  overflow-y: scroll;
-  right: 0;
-  margin-top: 60px;
-  background-color: white;
-  padding: 12px;
-  border-left: 1px solid #eee;
-
-  @media (max-width: 700px) {
-    position: absolute;
-    width: 100%;
-    /* full height - header - tabbar */
-    height: calc(100% - 60px - 80px);
-    max-width: min(calc(100vw - 85px), 400px);
-    ${({ highlighted }) => `right: ${highlighted ? 0 : -100}%;`}
-    padding-top: 45px;
-  }
-
-  transition: right 200ms ease-in-out;
-`
-
-const SidebarDismissButton = styled(Icon)`
-  position: absolute;
-  top: 10px;
-  right: 10px;
-
-  @media (min-width: 700px) {
-    display: none;
-  }
-`
+import React, { createContext, useContext, useEffect, useState } from 'react'
 
 export type UpdateSidebarFn = (content: React.ReactNode) => void
 
@@ -78,18 +41,33 @@ export const SidebarProvider = ({ children }: SidebarProviderProps) => {
 }
 
 export const Sidebar = () => {
-  const { updateSidebar, content } = useContext(SidebarContext)
+  const { content } = useContext(SidebarContext)
+
+  useEffect(() => {
+    const body = document.body
+
+    if (content == null) {
+      body.classList.remove('overflow-y-hidden')
+      body.classList.remove('lg:overflow-y-auto')
+    } else {
+      body.classList.add('overflow-y-hidden')
+      body.classList.add('lg:overflow-y-auto')
+    }
+
+    return () => {
+      body.classList.remove('overflow-y-hidden')
+      body.classList.remove('lg:overflow-y-auto')
+    }
+  })
 
   return (
-    <SidebarContainer highlighted={content != null}>
+    <div
+      className={`fixed top-[72px] bg-white bottom-0 w-full overflow-y-scroll transform transition-transform motion-reduce:transition-none ${
+        content == null ? 'translate-x-full' : 'translate-x-0'
+      } lg:w-[420px] lg:right-0 lg:shadow-separator lg:top-0 lg:z-40`}
+    >
       {content}
-      <SidebarDismissButton
-        name="angle double right"
-        size="big"
-        link
-        onClick={() => updateSidebar(null)}
-      />
-      <div style={{ height: 100 }}></div>
-    </SidebarContainer>
+      <div className="h-24"></div>
+    </div>
   )
 }
diff --git a/ui/src/components/sidebar/SidebarHeader.tsx b/ui/src/components/sidebar/SidebarHeader.tsx
new file mode 100644
index 0000000..d0db185
--- /dev/null
+++ b/ui/src/components/sidebar/SidebarHeader.tsx
@@ -0,0 +1,27 @@
+import React, { useContext } from 'react'
+
+import { ReactComponent as CloseIcon } from './icons/closeSidebarIcon.svg'
+import { ReactComponent as PinIcon } from './icons/pinSidebarIcon.svg'
+import { SidebarContext } from './Sidebar'
+
+type SidebarHeaderProps = {
+  title: string
+}
+
+const SidebarHeader = ({ title }: SidebarHeaderProps) => {
+  const { updateSidebar } = useContext(SidebarContext)
+
+  return (
+    <div className="m-2 flex items-center gap-2">
+      <button title="Close sidebar" onClick={() => updateSidebar(null)}>
+        <CloseIcon className="m-2" />
+      </button>
+      <span className="flex-grow -mt-1">{title}</span>
+      <button title="Pin sidebar">
+        <PinIcon className="m-2" />
+      </button>
+    </div>
+  )
+}
+
+export default SidebarHeader
diff --git a/ui/src/components/sidebar/icons/closeSidebarIcon.svg b/ui/src/components/sidebar/icons/closeSidebarIcon.svg
new file mode 100644
index 0000000..1d73015
--- /dev/null
+++ b/ui/src/components/sidebar/icons/closeSidebarIcon.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <path stroke="none" stroke-width="1" fill="none" d="M1,11 L11,1 M11,11 L1,1" stroke="#1F2021" stroke-width="2"></path>
+</svg>
\ No newline at end of file
diff --git a/ui/src/components/sidebar/icons/pinSidebarIcon.svg b/ui/src/components/sidebar/icons/pinSidebarIcon.svg
new file mode 100644
index 0000000..08eab7a
--- /dev/null
+++ b/ui/src/components/sidebar/icons/pinSidebarIcon.svg
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="16px" height="17px" viewBox="0 0 16 17" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g transform="translate(8, 8.5) rotate(-330) translate(-8, -8.5) translate(4, 2)" stroke="#1F2021">
+            <path d="M6.76850191,0.434840963 C6.04896114,1.86467297 5.79279384,3.20120746 6,4.44444444 C6.17989677,5.52382504 6.63266329,6.48919052 7.35829958,7.34054088 C7.50158762,7.50867286 7.48146228,7.76112984 7.31333862,7.90442763 C7.24096223,7.96611661 7.14897427,8 7.053875,8 L0.922873286,8 C0.701919553,8.00007212 0.522801161,7.82095373 0.522801161,7.59999999 C0.522801161,7.50599929 0.555900634,7.41500023 0.616293108,7.34296634 C1.36567981,6.44912577 1.82691544,5.48295181 2,4.44444444 C2.19754347,3.25918364 1.93688287,1.92116674 1.21801821,0.430393743 C1.14595115,0.281147735 1.2086138,0.10177184 1.35789863,0.0297852978 C1.39855358,0.0101811032 1.44310701,8.29112604e-18 1.4882418,0 L6.50055336,0 C6.666219,3.58349532e-05 6.80051754,0.134334371 6.80051754,0.300000012 C6.80051754,0.346829895 6.78955305,0.393009303 6.76850191,0.434840963 Z" stroke-linejoin="round"></path>
+            <line x1="4" y1="8" x2="4" y2="13" stroke-linecap="round"></line>
+        </g>
+    </g>
+</svg>
\ No newline at end of file
diff --git a/ui/src/components/timelineGallery/TimelineGallery.tsx b/ui/src/components/timelineGallery/TimelineGallery.tsx
index 770cd4a..eb7c5ff 100644
--- a/ui/src/components/timelineGallery/TimelineGallery.tsx
+++ b/ui/src/components/timelineGallery/TimelineGallery.tsx
@@ -163,7 +163,7 @@ const TimelineGallery = () => {
   ))
 
   return (
-    <>
+    <div className="overflow-x-hidden">
       <div className="mb-2">
         <FavoritesCheckbox
           onlyFavorites={onlyFavorites}
@@ -183,7 +183,7 @@ const TimelineGallery = () => {
           dispatchMedia={dispatchMedia}
         />
       )}
-    </>
+    </div>
   )
 }
 
