diff --git a/contentcuration/contentcuration/frontend/shared/utils/icons.js b/contentcuration/contentcuration/frontend/shared/utils/icons.js
new file mode 100644
index 0000000000..5fbe2f3ff4
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/utils/icons.js
@@ -0,0 +1,30 @@
+import camelCase from 'lodash/camelCase';
+import { ContentKindsNames } from 'shared/leUtils/ContentKinds';
+
+const EMPTY = '_empty';
+const CONTENT_KIND_ICONS = {
+  [ContentKindsNames.TOPIC]: 'topic',
+  [ContentKindsNames.TOPIC + EMPTY]: 'emptyTopic',
+  [ContentKindsNames.VIDEO]: 'video',
+  [ContentKindsNames.AUDIO]: 'audio',
+  [ContentKindsNames.SLIDESHOW]: 'slideshow',
+  [ContentKindsNames.EXERCISE]: 'exercise',
+  [ContentKindsNames.DOCUMENT]: 'document',
+  [ContentKindsNames.HTML5]: 'html5',
+  [ContentKindsNames.ZIM]: 'html5',
+};
+
+export function getContentKindIcon(kind, isEmpty = false) {
+  const icon = (isEmpty ? [kind + EMPTY] : []).concat([kind]).find(k => k in CONTENT_KIND_ICONS);
+  return icon ? CONTENT_KIND_ICONS[icon] : 'error';
+}
+
+export function getLearningActivityIcon(activity) {
+  if (activity.toLowerCase() === 'explore') {
+    return 'interactShaded';
+  } else if (activity === 'multiple') {
+    return 'allActivities';
+  } else {
+    return `${camelCase(activity) + 'Solid'}`;
+  }
+}
diff --git a/contentcuration/contentcuration/frontend/shared/views/channel/ChannelThumbnail.vue b/contentcuration/contentcuration/frontend/shared/views/channel/ChannelThumbnail.vue
index d8a5a07d84..25d4a7fbb3 100644
--- a/contentcuration/contentcuration/frontend/shared/views/channel/ChannelThumbnail.vue
+++ b/contentcuration/contentcuration/frontend/shared/views/channel/ChannelThumbnail.vue
@@ -16,7 +16,7 @@
           >
             <VCard
               ref="thumbnail"
-              class="thumbnail"
+              class="thumbnail-wrapper"
               data-test="loading"
             >
               <VLayout
@@ -355,7 +355,7 @@
     border: 2px solid var(--v-grey-darken2);
   }
 
-  .thumbnail {
+  .thumbnail-wrapper {
     padding: 28% 0;
     /* stylelint-disable-next-line custom-property-pattern */
     border-color: var(--v-greyBorder-base) !important;
diff --git a/contentcuration/contentcuration/frontend/shared/views/files/Thumbnail.vue b/contentcuration/contentcuration/frontend/shared/views/files/Thumbnail.vue
index 98caf3423e..fc57eb8579 100644
--- a/contentcuration/contentcuration/frontend/shared/views/files/Thumbnail.vue
+++ b/contentcuration/contentcuration/frontend/shared/views/files/Thumbnail.vue
@@ -6,11 +6,12 @@
       [kind]: compact,
       'icon-only': compact,
       nothumbnail: !showThumbnail && !compact,
+      'with-caption': showCaption,
     }"
     :style="{ 'max-width': maxWidth }"
   >
     <VLayout
-      v-if="kind && !printing && showKind && !compact"
+      v-if="showCaption"
       tag="figcaption"
       row
       align-center
@@ -21,12 +22,10 @@
         shrink
         class="px-1"
       >
-        <VIconWrapper
-          v-if="!compact"
-          dark
-          small
-          :aria-label="kindTitle"
-          v-text="icon"
+        <KIcon
+          :icon="icon"
+          class="icon-thumbnail"
+          :style="{ fill: '#ffffff' }"
         />
       </VFlex>
       <VFlex shrink>
@@ -46,42 +45,39 @@
       v-else-if="printing"
       class="printable-icon"
     >
-      <VIconWrapper
+      <!-- <VIconWrapper
         :color="$vuetify.theme[kind]"
         capture-as-image
       >
         {{ icon }}
-      </VIconWrapper>
+      </VIconWrapper> -->
+      <KIcon
+        class="icon-thumbnail"
+        :icon="icon"
+      />
     </div>
 
     <!-- Bury icon within SVG so it's more responsive, since font-size scaling is more difficult -->
-    <svg
+    <div
       v-else-if="compact"
-      viewBox="0 0 24 24"
-      :aria-label="kindTitle"
-      class="thumbnail-image"
+      class="kicon-wrapper"
     >
       <KIcon
-        icon="infoOutline"
-        :x="+10"
-        :y="y + 20"
+        :icon="icon"
+        class="icon-thumbnail"
         :style="{ fill: '#ffffff' }"
       />
-    </svg>
-    <svg
+    </div>
+    <div
       v-else
-      viewBox="0 0 40 40"
-      :aria-label="kindTitle"
-      class="nothumbnail-image"
-      :class="$isRTL ? 'rtl-image' : 'ltr-image'"
+      class="kicon-wrapper"
     >
       <KIcon
         icon="image"
-        :x="-3"
-        :y="y - 14"
-        :style="{ fill: '#999999' }"
+        class="icon-thumbnail"
+        :style="{ fill: '#999999', fontSize: '3em' }"
       />
-    </svg>
+    </div>
   </figure>
 
 </template>
@@ -89,8 +85,8 @@
 
 <script>
 
+  import { getContentKindIcon } from 'shared/utils/icons';
   import { constantsTranslationMixin, printingMixin } from 'shared/mixins';
-  import { getContentKindIcon } from 'shared/vuetify/icons';
 
   export default {
     name: 'Thumbnail',
@@ -136,22 +132,15 @@
       },
     },
     computed: {
-      y() {
-        switch (this.kind) {
-          case 'exercise':
-            return 28;
-          case 'topic':
-          case 'audio':
-          default:
-            return 26;
-        }
-      },
       objectFit() {
         return this.kind ? 'cover' : 'contain';
       },
       icon() {
         return getContentKindIcon(this.kind, this.isEmpty);
       },
+      showCaption() {
+        return this.kind && !this.printing && this.showKind && !this.compact;
+      },
       thumbnailSrc() {
         return this.encoding && this.encoding.base64 ? this.encoding.base64 : this.src;
       },
@@ -296,4 +285,23 @@
     }
   }
 
+  .kicon-wrapper {
+    position: absolute;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 100%;
+    height: 100%;
+
+    .icon-thumbnail {
+      top: 0;
+    }
+  }
+
+  .thumbnail.with-caption {
+    .kicon-wrapper {
+      height: calc(100% - #{$caption-height});
+    }
+  }
+
 </style>