diff --git a/src/components/Table.vue b/src/components/Table.vue
index 68d54d42f64efca56717c09a2a0661c83320c31f..83ec35240162db6ff234f48954bac8ec6f42f711 100644
--- a/src/components/Table.vue
+++ b/src/components/Table.vue
@@ -392,4 +392,8 @@ table.episodeTable {
 table.episodeTable tr.selected .eq-animation {
 	display: flex;
 }
+
+.inline {
+	display: inline;
+}
 </style>
diff --git a/src/views/BrowseAll.vue b/src/views/BrowseAll.vue
new file mode 100644
index 0000000000000000000000000000000000000000..3b06a9d45c5e209d5eb874eca255269c0366ad8c
--- /dev/null
+++ b/src/views/BrowseAll.vue
@@ -0,0 +1,164 @@
+<!--
+  - @copyright Copyright (c) 2020 Jonas Heinrich
+  -
+  - @author Jonas Heinrich <onny@project-insanity.org>
+  -
+  - @license GNU AGPL version 3 or any later version
+  -
+  - This program is free software: you can redistribute it and/or modify
+  - it under the terms of the GNU Affero General Public License as
+  - published by the Free Software Foundation, either version 3 of the
+  - License, or (at your option) any later version.
+  -
+  - This program is distributed in the hope that it will be useful,
+  - but WITHOUT ANY WARRANTY; without even the implied warranty of
+  - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  - GNU Affero General Public License for more details.
+  -
+  - You should have received a copy of the GNU Affero General Public License
+  - along with this program. If not, see <http://www.gnu.org/licenses/>.
+  -
+  -->
+<template>
+	<div class="mainContent">
+		<div class="podcastSection">
+			<div class="podcastSectionHeader">
+				<h1>Hot podcasts</h1>
+			</div>
+			<div class="podcastSliderAll">
+				<div
+					v-for="(podcast, idx) in podcasts"
+					:key="idx"
+					class="podcastCard">
+					<router-link :to="{ path: `/browse/show/${podcast.id}`}">
+						<div
+							class="podcastImage"
+							:style="{ backgroundImage: `url(${podcast.smallImageURL})` }" />
+						<span class="title">
+							{{ podcast.title }}
+						</span>
+						<span class="subtitle">
+							{{ podcast.author }}
+						</span>
+					</router-link>
+				</div>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+import { showError } from '@nextcloud/dialogs'
+import axios from '@nextcloud/axios'
+
+export default {
+	name: 'BrowseAll',
+	data: () => ({
+		podcasts: {},
+	}),
+	mounted() {
+		this.queryPodcasts()
+	},
+	methods: {
+
+		async queryPodcasts() {
+
+			const vm = this
+
+			const queryURI = this.$apiUrl + '/feature/podcast/hot'
+			try {
+				delete axios.defaults.headers.requesttoken
+				await axios.get(queryURI)
+					.then(function(response) {
+						vm.podcasts = response.data.data
+					})
+			} catch (error) {
+				showError(t('podcast', 'Could not fetch podcasts from remote API'))
+			}
+
+		},
+
+	},
+}
+</script>
+
+<style lang="scss">
+.mainContent {
+	padding: 30px;
+}
+
+.podcastSection {
+	margin-bottom: 30px;
+}
+
+.podcastSectionHeader {
+	padding: 10px 0px;
+	z-index: 60;
+	position: sticky;
+	top: 50px;
+	background: white;
+	display: flex;
+	align-items: center;
+	margin-bottom: 10px;
+
+	h1 {
+		flex-grow: 1;
+		font-size: 1.6em;
+		margin-bottom: 0px;
+	}
+	a {
+		color: #1976d2;
+		cursor: pointer;
+	}
+}
+
+.podcastSliderAll {
+	width: 100%;
+	display: flex;
+	flex-wrap: wrap;
+}
+
+.podcastCard {
+	width: 170px;
+	height: 220px;
+	margin-right: 15px;
+	flex-shrink: 0;
+	background: rgba(241, 241, 241, 0.6);
+	border-radius: 3px;
+	padding: 15px;
+	transition: all 0.2s ease-in-out;
+
+	* {
+		cursor: pointer;
+	}
+
+	.podcastImage {
+		background-size: cover;
+		background-position: center;
+		box-shadow: 1px 1px 2px rgba(0,0,0,.5);
+		border: 1px solid rgba(0,0,0,.5);
+		border-radius: 5px;
+		width: 140px;
+		height: 140px;
+		margin-bottom: 5px;
+	}
+
+	span {
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+		display: block;
+	}
+	span.title {
+		font-size: 1em;
+	}
+	span.subtitle {
+		font-size: 0.9em;
+		color: #b5b1b1;
+	}
+}
+
+.podcastCard:hover {
+	background: rgb(236, 236, 236);
+}
+</style>
diff --git a/src/views/Episode.vue b/src/views/Episode.vue
index c2857893f2910ae55a0ee3e4a8aef16344ad230f..37211edf17d57f759ce67e235b0ed5b082fbbe7c 100644
--- a/src/views/Episode.vue
+++ b/src/views/Episode.vue
@@ -40,7 +40,7 @@
 						</span>
 						<span>
 							<b>Publication date:</b>
-							<span :title="readableDate(episode.pubdate)">
+							<span class="inline" :title="readableDate(episode.pubdate)">
 								{{ readableTimeAgo(episode.pubdate) }}
 							</span>
 						</span>
diff --git a/src/views/placeholder/Browse.vue b/src/views/placeholder/Browse.vue
new file mode 100644
index 0000000000000000000000000000000000000000..5cf930216e7df13d1aa03659ea83497e3799449f
--- /dev/null
+++ b/src/views/placeholder/Browse.vue
@@ -0,0 +1,154 @@
+<!--
+  - @copyright Copyright (c) 2020 Jonas Heinrich
+  -
+  - @author Jonas Heinrich <onny@project-insanity.org>
+  -
+  - @license GNU AGPL version 3 or any later version
+  -
+  - This program is free software: you can redistribute it and/or modify
+  - it under the terms of the GNU Affero General Public License as
+  - published by the Free Software Foundation, either version 3 of the
+  - License, or (at your option) any later version.
+  -
+  - This program is distributed in the hope that it will be useful,
+  - but WITHOUT ANY WARRANTY; without even the implied warranty of
+  - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  - GNU Affero General Public License for more details.
+  -
+  - You should have received a copy of the GNU Affero General Public License
+  - along with this program. If not, see <http://www.gnu.org/licenses/>.
+  -
+  -->
+
+<template>
+	<div class="mainContent">
+		<div
+			v-for="mainIndex in 3"
+			:key="mainIndex"
+			class="podcastSection">
+			<div class="podcastSectionHeader">
+				<div
+					class="podcastDescriptionSubTitle"
+					style="max-width: 300px; width: 100%; height: 30px;" />
+			</div>
+			<div class="podcastSlider">
+				<div
+					v-for="index in 3"
+					:key="index"
+					class="podcastCard">
+					<div class="podcastImageEmpty" />
+					<div
+						class="episodeDescription"
+						style="width: 120px; margin-top: 10px;" />
+				</div>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+
+export default {
+	name: 'Browse',
+}
+</script>
+
+<style lang="scss">
+
+$base-color: #ddd;
+$shine-color: #e8e8e8;
+$animation-duration: 1.6s;
+$avatar-offset: 52 + 16;
+
+@mixin background-gradient {
+	background-image: linear-gradient(90deg, $base-color 0px, $shine-color 40px, $base-color 80px);
+	background-size: 600px;
+}
+
+.podcastHeaderEmpty {
+	width: 100%;
+	min-height: 300px;
+	display: flex;
+	justify-content: center;
+	padding: 40px 20px;
+	background-color: #f2f2f2;
+}
+
+.podcastImageEmpty {
+	width: 140px;
+	height: 140px;
+	flex-shrink: 0;
+	background-color: #ccc;
+	margin-right: 25px;
+	border-radius: 5px;
+
+	@include background-gradient;
+	animation: shine-avatar $animation-duration infinite linear;
+}
+
+.podcastDescriptionEmpty {
+	max-width: 500px;
+	width: 100%;
+}
+
+.podcastDescriptionTitle {
+	max-width: 500px;
+	width: 100%;
+	height: 35px;
+	border-radius: 5px;
+	margin-bottom: 30px;
+	background-color: #ddd;
+
+	@include background-gradient;
+	animation: shine-lines $animation-duration infinite linear;
+}
+
+.podcastDescriptionSubTitle {
+	height: 20px;
+	border-radius: 5px;
+	margin-bottom: 10px;
+	background-color: #ddd;
+
+	@include background-gradient;
+	animation: shine-lines $animation-duration infinite linear;
+}
+
+.episodeImageEmpty {
+	width: 74px;
+	height: 74px;
+	background-color: #ccc;
+	border-radius: 5px;
+
+	@include background-gradient;
+	animation: shine-avatar $animation-duration infinite linear;
+}
+
+.episodeDescription {
+	height: 20px;
+	border-radius: 5px;
+	margin-bottom: 10px;
+	background-color: #ddd;
+
+	@include background-gradient;
+	animation: shine-lines $animation-duration infinite linear;
+}
+
+@keyframes shine-lines {
+	0% {
+		background-position: -100px;
+	}
+	60%, 100% {
+		background-position: 500px;
+	}
+}
+
+@keyframes shine-avatar {
+	0% {
+		background-position: -100px + $avatar-offset;
+	}
+	40%, 100% {
+		background-position: 140px + $avatar-offset;
+	}
+}
+
+</style>
diff --git a/src/views/placeholder/Episode.vue b/src/views/placeholder/Episode.vue
new file mode 100644
index 0000000000000000000000000000000000000000..395b3b740852f8c5d1ecdfab3500c85ebb6a700e
--- /dev/null
+++ b/src/views/placeholder/Episode.vue
@@ -0,0 +1,183 @@
+<!--
+  - @copyright Copyright (c) 2020 Jonas Heinrich
+  -
+  - @author Jonas Heinrich <onny@project-insanity.org>
+  -
+  - @license GNU AGPL version 3 or any later version
+  -
+  - This program is free software: you can redistribute it and/or modify
+  - it under the terms of the GNU Affero General Public License as
+  - published by the Free Software Foundation, either version 3 of the
+  - License, or (at your option) any later version.
+  -
+  - This program is distributed in the hope that it will be useful,
+  - but WITHOUT ANY WARRANTY; without even the implied warranty of
+  - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  - GNU Affero General Public License for more details.
+  -
+  - You should have received a copy of the GNU Affero General Public License
+  - along with this program. If not, see <http://www.gnu.org/licenses/>.
+  -
+  -->
+
+<template>
+	<div>
+		<div class="podcastHeaderEmpty">
+			<div class="podcastImageEmpty" />
+			<div class="podcastDescriptionEmpty">
+				<div class="podcastDescriptionTitle" />
+				<div
+					class="podcastDescriptionSubTitle"
+					style="max-width: 300px; width: 100%;" />
+				<div
+					class="podcastDescriptionSubTitle"
+					style="max-width: 400px; width: 100%;" />
+				<div
+					class="podcastDescriptionSubTitle"
+					style="max-width: 200px; width: 100%;" />
+			</div>
+		</div>
+		<table class="episodeTable">
+			<thead>
+				<tr>
+					<th class="iconColumn" />
+					<th class="nameColumn">
+						{{ t('podcast', 'Name') }}
+					</th>
+					<th class="actionColumn" />
+					<th class="durationColumn">
+						{{ t('podcast', 'Duration') }}
+					</th>
+					<th class="dateColumn">
+						{{ t('podcast', 'Date') }}
+					</th>
+				</tr>
+			</thead>
+			<tbody>
+				<tr v-for="index in 3" :key="index">
+					<td class="iconColumn">
+						<div class="episodeImageEmpty" />
+					</td>
+					<td class="nameColumn">
+						<div
+							class="episodeDescription"
+							style="width: 500px;" />
+						<div
+							class="episodeDescription"
+							style="width: 400px;" />
+					</td>
+					<td class="actionColumn" />
+					<td class="durationColumn" />
+					<td class="dateColumn" />
+				</tr>
+			</tbody>
+		</table>
+	</div>
+</template>
+
+<script>
+
+export default {
+	name: 'Episode',
+}
+</script>
+
+<style lang="scss">
+
+$base-color: #ddd;
+$shine-color: #e8e8e8;
+$animation-duration: 1.6s;
+$avatar-offset: 52 + 16;
+
+@mixin background-gradient {
+	background-image: linear-gradient(90deg, $base-color 0px, $shine-color 40px, $base-color 80px);
+	background-size: 600px;
+}
+
+.podcastHeaderEmpty {
+	width: 100%;
+	min-height: 300px;
+	display: flex;
+	justify-content: center;
+	padding: 40px 20px;
+	background-color: #f2f2f2;
+}
+
+.podcastImageEmpty {
+	width: 200px;
+	height: 200px;
+	flex-shrink: 0;
+	background-color: #ccc;
+	margin-right: 25px;
+	border-radius: 5px;
+
+	@include background-gradient;
+	animation: shine-avatar $animation-duration infinite linear;
+}
+
+.podcastDescriptionEmpty {
+	max-width: 500px;
+	width: 100%;
+}
+
+.podcastDescriptionTitle {
+	max-width: 500px;
+	width: 100%;
+	height: 35px;
+	border-radius: 5px;
+	margin-bottom: 30px;
+	background-color: #ddd;
+
+	@include background-gradient;
+	animation: shine-lines $animation-duration infinite linear;
+}
+
+.podcastDescriptionSubTitle {
+	height: 20px;
+	border-radius: 5px;
+	margin-bottom: 10px;
+	background-color: #ddd;
+
+	@include background-gradient;
+	animation: shine-lines $animation-duration infinite linear;
+}
+
+.episodeImageEmpty {
+	width: 74px;
+	height: 74px;
+	background-color: #ccc;
+	border-radius: 5px;
+
+	@include background-gradient;
+	animation: shine-avatar $animation-duration infinite linear;
+}
+
+.episodeDescription {
+	height: 20px;
+	border-radius: 5px;
+	margin-bottom: 10px;
+	background-color: #ddd;
+
+	@include background-gradient;
+	animation: shine-lines $animation-duration infinite linear;
+}
+
+@keyframes shine-lines {
+	0% {
+		background-position: -100px;
+	}
+	60%, 100% {
+		background-position: 500px;
+	}
+}
+
+@keyframes shine-avatar {
+	0% {
+		background-position: -100px + $avatar-offset;
+	}
+	40%, 100% {
+		background-position: 140px + $avatar-offset;
+	}
+}
+
+</style>
diff --git a/src/views/placeholder/Show.vue b/src/views/placeholder/Show.vue
new file mode 100644
index 0000000000000000000000000000000000000000..e7cb27d48b71283b4493c502c9d096ad566b630d
--- /dev/null
+++ b/src/views/placeholder/Show.vue
@@ -0,0 +1,183 @@
+<!--
+  - @copyright Copyright (c) 2020 Jonas Heinrich
+  -
+  - @author Jonas Heinrich <onny@project-insanity.org>
+  -
+  - @license GNU AGPL version 3 or any later version
+  -
+  - This program is free software: you can redistribute it and/or modify
+  - it under the terms of the GNU Affero General Public License as
+  - published by the Free Software Foundation, either version 3 of the
+  - License, or (at your option) any later version.
+  -
+  - This program is distributed in the hope that it will be useful,
+  - but WITHOUT ANY WARRANTY; without even the implied warranty of
+  - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  - GNU Affero General Public License for more details.
+  -
+  - You should have received a copy of the GNU Affero General Public License
+  - along with this program. If not, see <http://www.gnu.org/licenses/>.
+  -
+  -->
+
+<template>
+	<div>
+		<div class="podcastHeaderEmpty">
+			<div class="podcastImageEmpty" />
+			<div class="podcastDescriptionEmpty">
+				<div class="podcastDescriptionTitle" />
+				<div
+					class="podcastDescriptionSubTitle"
+					style="max-width: 300px; width: 100%;" />
+				<div
+					class="podcastDescriptionSubTitle"
+					style="max-width: 400px; width: 100%;" />
+				<div
+					class="podcastDescriptionSubTitle"
+					style="max-width: 200px; width: 100%;" />
+			</div>
+		</div>
+		<table class="episodeTable">
+			<thead>
+				<tr>
+					<th class="iconColumn" />
+					<th class="nameColumn">
+						{{ t('podcast', 'Name') }}
+					</th>
+					<th class="actionColumn" />
+					<th class="durationColumn">
+						{{ t('podcast', 'Duration') }}
+					</th>
+					<th class="dateColumn">
+						{{ t('podcast', 'Date') }}
+					</th>
+				</tr>
+			</thead>
+			<tbody>
+				<tr v-for="index in 3" :key="index">
+					<td class="iconColumn">
+						<div class="episodeImageEmpty" />
+					</td>
+					<td class="nameColumn">
+						<div
+							class="episodeDescription"
+							style="width: 500px;" />
+						<div
+							class="episodeDescription"
+							style="width: 400px;" />
+					</td>
+					<td class="actionColumn" />
+					<td class="durationColumn" />
+					<td class="dateColumn" />
+				</tr>
+			</tbody>
+		</table>
+	</div>
+</template>
+
+<script>
+
+export default {
+	name: 'Show',
+}
+</script>
+
+<style lang="scss">
+
+$base-color: #ddd;
+$shine-color: #e8e8e8;
+$animation-duration: 1.6s;
+$avatar-offset: 52 + 16;
+
+@mixin background-gradient {
+	background-image: linear-gradient(90deg, $base-color 0px, $shine-color 40px, $base-color 80px);
+	background-size: 600px;
+}
+
+.podcastHeaderEmpty {
+	width: 100%;
+	min-height: 300px;
+	display: flex;
+	justify-content: center;
+	padding: 40px 20px;
+	background-color: #f2f2f2;
+}
+
+.podcastImageEmpty {
+	width: 200px;
+	height: 200px;
+	flex-shrink: 0;
+	background-color: #ccc;
+	margin-right: 25px;
+	border-radius: 5px;
+
+	@include background-gradient;
+	animation: shine-avatar $animation-duration infinite linear;
+}
+
+.podcastDescriptionEmpty {
+	max-width: 500px;
+	width: 100%;
+}
+
+.podcastDescriptionTitle {
+	max-width: 500px;
+	width: 100%;
+	height: 35px;
+	border-radius: 5px;
+	margin-bottom: 30px;
+	background-color: #ddd;
+
+	@include background-gradient;
+	animation: shine-lines $animation-duration infinite linear;
+}
+
+.podcastDescriptionSubTitle {
+	height: 20px;
+	border-radius: 5px;
+	margin-bottom: 10px;
+	background-color: #ddd;
+
+	@include background-gradient;
+	animation: shine-lines $animation-duration infinite linear;
+}
+
+.episodeImageEmpty {
+	width: 74px;
+	height: 74px;
+	background-color: #ccc;
+	border-radius: 5px;
+
+	@include background-gradient;
+	animation: shine-avatar $animation-duration infinite linear;
+}
+
+.episodeDescription {
+	height: 20px;
+	border-radius: 5px;
+	margin-bottom: 10px;
+	background-color: #ddd;
+
+	@include background-gradient;
+	animation: shine-lines $animation-duration infinite linear;
+}
+
+@keyframes shine-lines {
+	0% {
+		background-position: -100px;
+	}
+	60%, 100% {
+		background-position: 500px;
+	}
+}
+
+@keyframes shine-avatar {
+	0% {
+		background-position: -100px + $avatar-offset;
+	}
+	40%, 100% {
+		background-position: 140px + $avatar-offset;
+	}
+}
+
+</style>