diff --git a/src/addons/block/onlineusers/components/onlineusers/onlineusers.scss b/src/addons/block/onlineusers/components/onlineusers/onlineusers.scss
index c3d4b4c40..c34c11af4 100644
--- a/src/addons/block/onlineusers/components/onlineusers/onlineusers.scss
+++ b/src/addons/block/onlineusers/components/onlineusers/onlineusers.scss
@@ -28,7 +28,7 @@
                 }
 
                 .userpicture {
-                    vertical-align: text-bottom;
+                    border-radius: 50%;
                 }
             }
 
diff --git a/src/addons/block/timeline/components/components.module.ts b/src/addons/block/timeline/components/components.module.ts
index dfd4a5fc4..f54298186 100644
--- a/src/addons/block/timeline/components/components.module.ts
+++ b/src/addons/block/timeline/components/components.module.ts
@@ -15,8 +15,6 @@
 import { NgModule } from '@angular/core';
 
 import { CoreSharedModule } from '@/core/shared.module';
-import { CoreCoursesComponentsModule } from '@features/courses/components/components.module';
-import { CoreCourseComponentsModule } from '@features/course/components/components.module';
 
 import { AddonBlockTimelineComponent } from './timeline/timeline';
 import { AddonBlockTimelineEventsComponent } from './events/events';
@@ -28,8 +26,6 @@ import { AddonBlockTimelineEventsComponent } from './events/events';
     ],
     imports: [
         CoreSharedModule,
-        CoreCoursesComponentsModule,
-        CoreCourseComponentsModule,
     ],
     exports: [
         AddonBlockTimelineComponent,
diff --git a/src/addons/block/timeline/components/events/addon-block-timeline-events.html b/src/addons/block/timeline/components/events/addon-block-timeline-events.html
index 0622e2e0b..7907f508c 100644
--- a/src/addons/block/timeline/components/events/addon-block-timeline-events.html
+++ b/src/addons/block/timeline/components/events/addon-block-timeline-events.html
@@ -1,50 +1,61 @@
+<ion-item lines="none" *ngIf="course">
+    <ion-label class="ion-text-wrap">
+        <h3>
+            <span class="sr-only">{{ 'core.courses.aria:coursename' | translate }}</span>
+            <core-format-text [text]="course.fullname" contextLevel="course" [contextInstanceId]="course.id"></core-format-text>
+        </h3>
+    </ion-label>
+</ion-item>
 <ion-item-group *ngFor="let dayEvents of filteredEvents">
-    <ion-item-divider [color]="dayEvents.color">
-        <ion-label><h3>{{ dayEvents.dayTimestamp * 1000 | coreFormatDate:"strftimedayshort" }}</h3></ion-label>
-    </ion-item-divider>
+    <ion-item lines="none">
+        <ion-label>
+            <h4 [class.core-bold]="!course">{{ dayEvents.dayTimestamp * 1000 | coreFormatDate:"strftimedayshort" }}</h4>
+        </ion-label>
+    </ion-item>
     <ng-container *ngFor="let event of dayEvents.events">
-        <ion-item class="ion-text-wrap core-course-module-handler item-media" detail="false" (click)="action($event, event.url)"
-            [attr.aria-label]="event.name" button>
-            <core-mod-icon *ngIf="event.iconUrl" slot="start" [modicon]="event.iconUrl" [componentId]="event.instance"
-                [modname]="event.modulename">
-            </core-mod-icon>
+        <ion-item class="addon-block-timeline-activity" detail="false" (click)="action($event, event.url)" [attr.aria-label]="event.name"
+            button lines="full">
             <ion-label>
-                <p class="item-heading">
-                    <core-format-text [text]="event.name" contextLevel="module" [contextInstanceId]="event.id"
-                        [courseId]="event.course && event.course.id">
-                    </core-format-text>
-                </p>
-                <p *ngIf="showCourse && event.course">
-                    <core-format-text [text]="event.course.fullnamedisplay" contextLevel="course"
-                        [contextInstanceId]="event.course.id">
-                    </core-format-text>
-                </p>
-
-                <ion-button fill="clear" class="ion-hide-md-up ion-text-wrap" (click)="action($event, event.action.url)"
-                    [title]="event.action.name" [disabled]="!event.action.actionable" *ngIf="event.action">
-                    {{event.action.name}}
-                    <ion-badge slot="end" class="ion-margin-start" *ngIf="event.action.showitemcount">{{event.action.itemcount}}
-                    </ion-badge>
-                </ion-button>
+                <ion-row class="ion-justify-content-between ion-align-items-center ion-no-padding">
+                    <ion-col class="addon-block-timeline-activity-main ion-no-padding">
+                        <ion-row class="ion-justify-content-between ion-align-items-center ion-nowrap ion-no-padding">
+                            <ion-col class="addon-block-timeline-activity-time ion-no-padding">
+                                <ion-badge color="light">{{event.timesort * 1000 | coreFormatDate:"strftimetime24" }}</ion-badge>
+                                <core-mod-icon *ngIf="event.iconUrl" [modicon]="event.iconUrl" [componentId]="event.instance"
+                                    [modname]="event.modulename">
+                                </core-mod-icon>
+                            </ion-col>
+                            <ion-col class="addon-block-timeline-activity-name ion-no-padding">
+                                <p class="item-heading">
+                                    <core-format-text [text]="event.activityname || event.name" contextLevel="module"
+                                        [contextInstanceId]="event.id" [courseId]="event.course && event.course.id">
+                                    </core-format-text>
+                                    <ion-badge *ngIf="event.overdue" color="danger">{{ 'addon.block_timeline.overdue' | translate }}
+                                    </ion-badge>
+                                </p>
+                                <p *ngIf="(showCourse && event.course) || event.activitystr">
+                                    <span *ngIf="showCourse && event.course">
+                                        <core-format-text [text]="event.course.fullnamedisplay" contextLevel="course"
+                                            [contextInstanceId]="event.course.id">
+                                        </core-format-text> ยท
+                                    </span>
+                                    <core-format-text [text]="event.activitystr" contextLevel="module" [contextInstanceId]="event.id">
+                                    </core-format-text>
+                                </p>
+                            </ion-col>
+                        </ion-row>
+                    </ion-col>
+                    <ion-col class="addon-block-timeline-activity-action ion-no-padding">
+                        <ion-button fill="clear" (click)="action($event, event.action.url)" [title]="event.action.name"
+                            [disabled]="!event.action.actionable" *ngIf="event.action">
+                            {{event.action.name}}
+                            <ion-badge slot="end" class="ion-margin-start" *ngIf="event.action.showitemcount">
+                                {{event.action.itemcount}}
+                            </ion-badge>
+                        </ion-button>
+                    </ion-col>
+                </ion-row>
             </ion-label>
-
-            <div slot="end" class="events-info">
-                <div>
-                    <ion-badge color="light">{{event.timesort * 1000 | coreFormatDate:"strftimetime24" }}</ion-badge>
-                </div>
-                <ion-button
-                    class="ion-hide-md-down"
-                    fill="clear"
-                    (click)="action($event, event.action.url)"
-                    [title]="event.action.name"
-                    [disabled]="!event.action.actionable" *ngIf="event.action"
-                >
-                    {{event.action.name}}
-                    <ion-badge slot="end" class="ion-margin-start" *ngIf="event.action.showitemcount">
-                        {{event.action.itemcount}}
-                    </ion-badge>
-                </ion-button>
-            </div>
         </ion-item>
     </ng-container>
 </ion-item-group>
@@ -57,6 +68,10 @@
     <ion-spinner *ngIf="loadingMore" [attr.aria-label]="'core.loading' | translate"></ion-spinner>
 </div>
 
-<core-empty-box *ngIf="empty" image="assets/img/icons/activities.svg" [message]="'addon.block_timeline.noevents' | translate"
-    inline="true">
-</core-empty-box>
+<ion-item lines="none" *ngIf="empty && course">
+    <ion-label class="ion-text-wrap">
+        <p>{{'addon.block_timeline.noevents' | translate}}</p>
+    </ion-label>
+</ion-item>
+<core-empty-box *ngIf="empty && !course" image="assets/img/icons/activities.svg" inline="true"
+    [message]="'addon.block_timeline.noevents' | translate"></core-empty-box>
diff --git a/src/addons/block/timeline/components/events/events.scss b/src/addons/block/timeline/components/events/events.scss
index c863dbb2a..8ea49fcb1 100644
--- a/src/addons/block/timeline/components/events/events.scss
+++ b/src/addons/block/timeline/components/events/events.scss
@@ -1,6 +1,41 @@
-.events-info {
-    display: flex;
-    flex-direction: column;
-    text-align: end;
-    padding: 10px 0;
+@import "~theme/globals";
+
+h3 {
+    font-weight: bold;
+    font-size: 18px;
+}
+
+h4 {
+    font-size: 15px;
+}
+
+h4.core-bold {
+    font-weight: bold;
+}
+
+.addon-block-timeline-activity ion-badge {
+    @include margin-horizontal(0.25rem, 0.5rem);
+}
+
+.addon-block-timeline-activity core-mod-icon {
+    --margin-end: 0.5rem;
+}
+
+.addon-block-timeline-activity-time,
+.addon-block-timeline-activity-action {
+    flex-grow: 0;
+}
+
+.addon-block-timeline-activity-main,
+.addon-block-timeline-activity-name {
+    flex-grow: 1;
+    p {
+        overflow: hidden;
+        text-overflow: ellipsis;
+    }
+}
+
+.addon-block-timeline-activity-name {
+    flex-grow: 1;
+    overflow: hidden;
 }
diff --git a/src/addons/block/timeline/components/events/events.ts b/src/addons/block/timeline/components/events/events.ts
index b0db9c8a0..b9047ff2b 100644
--- a/src/addons/block/timeline/components/events/events.ts
+++ b/src/addons/block/timeline/components/events/events.ts
@@ -17,11 +17,11 @@ import { CoreSites } from '@services/sites';
 import { CoreDomUtils } from '@services/utils/dom';
 import { CoreTextUtils } from '@services/utils/text';
 import { CoreTimeUtils } from '@services/utils/time';
-import { CoreUtils } from '@services/utils/utils';
 import { CoreCourse } from '@features/course/services/course';
 import moment from 'moment';
 import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper';
 import { AddonCalendarEvent } from '@addons/calendar/services/calendar';
+import { CoreEnrolledCourseDataWithOptions } from '@features/courses/services/courses-helper';
 
 /**
  * Directive to render a list of events in course overview.
@@ -34,34 +34,37 @@ import { AddonCalendarEvent } from '@addons/calendar/services/calendar';
 export class AddonBlockTimelineEventsComponent implements OnChanges {
 
     @Input() events: AddonBlockTimelineEvent[] = []; // The events to render.
-    @Input() showCourse?: boolean | string; // Whether to show the course name.
+    @Input() course?: CoreEnrolledCourseDataWithOptions; // Whether to show the course name.
     @Input() from = 0; // Number of days from today to offset the events.
     @Input() to?: number; // Number of days from today to limit the events to. If not defined, no limit.
-    @Input() canLoadMore?: boolean; // Whether more events can be loaded.
-    @Output() loadMore: EventEmitter<void>; // Notify that more events should be loaded.
+    @Input() canLoadMore = false; // Whether more events can be loaded.
+    @Output() loadMore = new EventEmitter(); // Notify that more events should be loaded.
 
+    showCourse = false; // Whether to show the course name.
     empty = true;
     loadingMore = false;
     filteredEvents: AddonBlockTimelineEventFilteredEvent[] = [];
 
-    constructor() {
-        this.loadMore = new EventEmitter();
-    }
-
     /**
-     * Detect changes on input properties.
+     * @inheritdoc
      */
     async ngOnChanges(changes: {[name: string]: SimpleChange}): Promise<void> {
-        this.showCourse = CoreUtils.isTrueOrOne(this.showCourse);
+        this.showCourse = !this.course;
 
         if (changes.events || changes.from || changes.to) {
             if (this.events && this.events.length > 0) {
                 const filteredEvents = await this.filterEventsByTime(this.from, this.to);
                 this.empty = !filteredEvents || filteredEvents.length <= 0;
 
+                const now = CoreTimeUtils.timestamp();
+
                 const eventsByDay: Record<number, AddonCalendarEvent[]> = {};
                 filteredEvents.forEach((event) => {
                     const dayTimestamp = CoreTimeUtils.getMidnightForTimestamp(event.timesort);
+
+                    // Already calculated on 4.0 onwards but this will be live.
+                    event.overdue = event.timesort < now;
+
                     if (eventsByDay[dayTimestamp]) {
                         eventsByDay[dayTimestamp].push(event);
                     } else {
@@ -69,15 +72,13 @@ export class AddonBlockTimelineEventsComponent implements OnChanges {
                     }
                 });
 
-                const todaysMidnight = CoreTimeUtils.getMidnightForTimestamp();
-                this.filteredEvents = [];
-                Object.keys(eventsByDay).forEach((key) => {
+                this.filteredEvents =  Object.keys(eventsByDay).map((key) => {
                     const dayTimestamp = parseInt(key);
-                    this.filteredEvents.push({
-                        color: dayTimestamp < todaysMidnight ? 'danger' : 'light',
+
+                    return {
                         dayTimestamp,
                         events: eventsByDay[dayTimestamp],
-                    });
+                    };
                 });
             } else {
                 this.empty = true;
@@ -94,7 +95,7 @@ export class AddonBlockTimelineEventsComponent implements OnChanges {
      */
     protected async filterEventsByTime(start: number, end?: number): Promise<AddonBlockTimelineEvent[]> {
         start = moment().add(start, 'days').startOf('day').unix();
-        end = typeof end != 'undefined' ? moment().add(end, 'days').startOf('day').unix() : end;
+        end = end !== undefined ? moment().add(end, 'days').startOf('day').unix() : end;
 
         return await Promise.all(this.events.filter((event) => {
             if (end) {
@@ -122,12 +123,12 @@ export class AddonBlockTimelineEventsComponent implements OnChanges {
     /**
      * Action clicked.
      *
-     * @param e Click event.
+     * @param event Click event.
      * @param url Url of the action.
      */
-    async action(e: Event, url: string): Promise<void> {
-        e.preventDefault();
-        e.stopPropagation();
+    async action(event: Event, url: string): Promise<void> {
+        event.preventDefault();
+        event.stopPropagation();
 
         // Fix URL format.
         url = CoreTextUtils.decodeHTMLEntities(url);
@@ -137,7 +138,7 @@ export class AddonBlockTimelineEventsComponent implements OnChanges {
         try {
             const treated = await CoreContentLinksHelper.handleLink(url);
             if (!treated) {
-                return CoreSites.getCurrentSite()?.openInBrowserWithAutoLoginIfSameSite(url);
+                return CoreSites.getRequiredCurrentSite().openInBrowserWithAutoLoginIfSameSite(url);
             }
         } finally {
             modal.dismiss();
@@ -154,5 +155,4 @@ type AddonBlockTimelineEvent = AddonCalendarEvent & {
 type AddonBlockTimelineEventFilteredEvent = {
     events: AddonBlockTimelineEvent[];
     dayTimestamp: number;
-    color: string;
 };
diff --git a/src/addons/block/timeline/components/timeline/addon-block-timeline.html b/src/addons/block/timeline/components/timeline/addon-block-timeline.html
index 62105627c..81c32360d 100644
--- a/src/addons/block/timeline/components/timeline/addon-block-timeline.html
+++ b/src/addons/block/timeline/components/timeline/addon-block-timeline.html
@@ -1,5 +1,7 @@
 <ion-item-divider sticky="true">
-    <ion-label><h2>{{ 'addon.block_timeline.pluginname' | translate }}</h2></ion-label>
+    <ion-label>
+        <h2>{{ 'addon.block_timeline.pluginname' | translate }}</h2>
+    </ion-label>
     <core-context-menu slot="end">
         <core-context-menu-item *ngIf="loaded" [priority]="900" [content]="'addon.block_timeline.sortbydates' | translate"
             (action)="switchSort('sortbydates')" [iconAction]="sort == 'sortbydates' ? 'far-dot-circle' : 'far-circle'">
@@ -18,7 +20,7 @@
             <ion-select-option class="ion-text-wrap" value="overdue">
                 {{ 'addon.block_timeline.overdue' | translate }}
             </ion-select-option>
-            <ion-select-option class="ion-text-wrap" disabled value="disabled">
+            <ion-select-option class="ion-text-wrap core-select-option-title" disabled value="disabled">
                 {{ 'addon.block_timeline.duedate' | translate }}
             </ion-select-option>
             <ion-select-option class="ion-text-wrap" value="next7days">
@@ -36,21 +38,14 @@
         </core-combobox>
     </div>
     <core-loading [hideUntil]="timeline.loaded" [hidden]="sort != 'sortbydates'" [fullscreen]="false">
-        <addon-block-timeline-events [events]="timeline.events" showCourse="true" [canLoadMore]="timeline.canLoadMore"
-            (loadMore)="loadMoreTimeline()" [from]="dataFrom" [to]="dataTo"></addon-block-timeline-events>
+        <addon-block-timeline-events [events]="timeline.events" [canLoadMore]="timeline.canLoadMore" (loadMore)="loadMore()"
+            [from]="dataFrom" [to]="dataTo"></addon-block-timeline-events>
     </core-loading>
-    <core-loading [hideUntil]="timelineCourses.loaded" [hidden]="sort != 'sortbycourses'"
-        [fullscreen]="false" class="safe-area-padding">
-        <ion-grid class="ion-no-padding">
-            <ion-row class="ion-no-padding">
-                <ion-col *ngFor="let course of timelineCourses.courses" class="ion-no-padding" size="12" size-md="6">
-                    <core-courses-course-progress [course]="course">
-                        <addon-block-timeline-events [events]="course.events" [canLoadMore]="course.canLoadMore"
-                            (loadMore)="loadMoreCourse(course)" [from]="dataFrom" [to]="dataTo"></addon-block-timeline-events>
-                    </core-courses-course-progress>
-                </ion-col>
-            </ion-row>
-        </ion-grid>
+    <core-loading [hideUntil]="timelineCourses.loaded" [hidden]="sort != 'sortbycourses'" [fullscreen]="false" class="safe-area-page">
+        <ng-container *ngFor="let course of timelineCourses.courses">
+            <addon-block-timeline-events [events]="course.events" [canLoadMore]="course.canLoadMore" (loadMore)="loadMore(course)"
+                [course]="course" [from]="dataFrom" [to]="dataTo"></addon-block-timeline-events>
+        </ng-container>
         <core-empty-box *ngIf="timelineCourses.courses.length == 0" image="assets/img/icons/courses.svg" inline="true"
             [message]="'addon.block_timeline.nocoursesinprogress' | translate"></core-empty-box>
     </core-loading>
diff --git a/src/addons/block/timeline/components/timeline/timeline.ts b/src/addons/block/timeline/components/timeline/timeline.ts
index 29f2e1487..c8ef64b77 100644
--- a/src/addons/block/timeline/components/timeline/timeline.ts
+++ b/src/addons/block/timeline/components/timeline/timeline.ts
@@ -24,6 +24,7 @@ import { CoreCoursesHelper, CoreEnrolledCourseDataWithOptions } from '@features/
 import { CoreSite } from '@classes/site';
 import { CoreCourses } from '@features/courses/services/courses';
 import { CoreCourseOptionsDelegate } from '@features/course/services/course-options-delegate';
+import { CoreNavigator } from '@services/navigator';
 
 /**
  * Component to render a timeline block.
@@ -36,7 +37,7 @@ export class AddonBlockTimelineComponent extends CoreBlockBaseComponent implemen
 
     sort = 'sortbydates';
     filter = 'next30days';
-    currentSite?: CoreSite;
+    currentSite!: CoreSite;
     timeline: {
         events: AddonCalendarEvent[];
         loaded: boolean;
@@ -66,10 +67,18 @@ export class AddonBlockTimelineComponent extends CoreBlockBaseComponent implemen
     }
 
     /**
-     * Component being initialized.
+     * @inheritdoc
      */
     async ngOnInit(): Promise<void> {
-        this.currentSite = CoreSites.getRequiredCurrentSite();
+        try {
+            this.currentSite = CoreSites.getRequiredCurrentSite();
+        } catch (error) {
+            CoreDomUtils.showErrorModal(error);
+
+            CoreNavigator.back();
+
+            return;
+        }
 
         this.filter = await this.currentSite.getLocalSiteConfig('AddonBlockTimelineFilter', this.filter);
         this.switchFilter(this.filter);
@@ -117,28 +126,21 @@ export class AddonBlockTimelineComponent extends CoreBlockBaseComponent implemen
         }
     }
 
-    /**
-     * Load more events.
-     */
-    async loadMoreTimeline(): Promise<void> {
-        try {
-            await this.fetchMyOverviewTimeline(this.timeline.canLoadMore);
-        } catch (error) {
-            CoreDomUtils.showErrorModalDefault(error, this.fetchContentDefaultError);
-        }
-    }
-
     /**
      * Load more events.
      *
-     * @param course Course.
+     * @param course Course. If defined, it will update the course events, timeline otherwise.
      * @return Promise resolved when done.
      */
-    async loadMoreCourse(course: AddonBlockTimelineCourse): Promise<void> {
+    async loadMore(course?: AddonBlockTimelineCourse): Promise<void> {
         try {
-            const courseEvents = await AddonBlockTimeline.getActionEventsByCourse(course.id, course.canLoadMore);
-            course.events = course.events?.concat(courseEvents.events);
-            course.canLoadMore = courseEvents.canLoadMore;
+            if (course) {
+                const courseEvents = await AddonBlockTimeline.getActionEventsByCourse(course.id, course.canLoadMore);
+                course.events = course.events?.concat(courseEvents.events);
+                course.canLoadMore = courseEvents.canLoadMore;
+            } else {
+                await this.fetchMyOverviewTimeline(this.timeline.canLoadMore);
+            }
         } catch (error) {
             CoreDomUtils.showErrorModalDefault(error, this.fetchContentDefaultError);
         }
@@ -188,12 +190,12 @@ export class AddonBlockTimelineComponent extends CoreBlockBaseComponent implemen
      */
     switchFilter(filter: string): void {
         this.filter = filter;
-        this.currentSite?.setLocalSiteConfig('AddonBlockTimelineFilter', this.filter);
+        this.currentSite.setLocalSiteConfig('AddonBlockTimelineFilter', this.filter);
 
         switch (this.filter) {
             case 'overdue':
                 this.dataFrom = -14;
-                this.dataTo = 0;
+                this.dataTo = 1;
                 break;
             case 'next7days':
                 this.dataFrom = 0;
@@ -226,7 +228,7 @@ export class AddonBlockTimelineComponent extends CoreBlockBaseComponent implemen
      */
     switchSort(sort: string): void {
         this.sort = sort;
-        this.currentSite?.setLocalSiteConfig('AddonBlockTimelineSort', this.sort);
+        this.currentSite.setLocalSiteConfig('AddonBlockTimelineSort', this.sort);
 
         if (!this.timeline.loaded && this.sort == 'sortbydates') {
             this.fetchContent();
@@ -237,7 +239,7 @@ export class AddonBlockTimelineComponent extends CoreBlockBaseComponent implemen
 
 }
 
-type AddonBlockTimelineCourse = CoreEnrolledCourseDataWithOptions & {
+export type AddonBlockTimelineCourse = CoreEnrolledCourseDataWithOptions & {
     events?: AddonCalendarEvent[];
     canLoadMore?: number;
 };
diff --git a/src/addons/calendar/services/calendar.ts b/src/addons/calendar/services/calendar.ts
index b4ab29361..f21f71869 100644
--- a/src/addons/calendar/services/calendar.ts
+++ b/src/addons/calendar/services/calendar.ts
@@ -1707,14 +1707,19 @@ export type AddonCalendarEventBase = {
     userid?: number; // Userid.
     repeatid?: number; // Repeatid.
     eventcount?: number; // Eventcount.
+    component?: string; // Component.
     modulename?: string; // Modulename.
+    activityname?: string; // Activityname.
+    activitystr?: string; // Activitystr.
     instance?: number; // Instance.
     eventtype: AddonCalendarEventType; // Eventtype.
     timestart: number; // Timestart.
     timeduration: number; // Timeduration.
     timesort: number; // Timesort.
+    timeusermidnight: number; // Timeusermidnight.
     visible: number; // Visible.
     timemodified: number; // Timemodified.
+    overdue?: boolean; // Overdue.
     icon: {
         key: string; // Key.
         component: string; // Component.
diff --git a/src/core/features/block/components/block/block.scss b/src/core/features/block/components/block/block.scss
index c33c495a9..72e49c32f 100644
--- a/src/core/features/block/components/block/block.scss
+++ b/src/core/features/block/components/block/block.scss
@@ -7,4 +7,8 @@
     ion-item-divider {
         min-height: var(--item-divider-min-height);
     }
+
+    ::ng-deep core-loading {
+        --loading-inline-min-height: 44px;
+    }
 }
diff --git a/src/core/features/courses/components/course-progress/core-courses-course-progress.html b/src/core/features/courses/components/course-progress/core-courses-course-progress.html
index d36b8cb38..7adb8fcc3 100644
--- a/src/core/features/courses/components/course-progress/core-courses-course-progress.html
+++ b/src/core/features/courses/components/course-progress/core-courses-course-progress.html
@@ -1,14 +1,12 @@
 <ion-card [attr.course-color]="course.color ? null : course.colorNumber">
     <div (click)="openCourse()" class="core-course-thumb" [class.core-course-color-img]="course.courseImage"
         [style.background-color]="course.color">
-        <img *ngIf="course.courseImage" [src]="course.courseImage" core-external-content alt=""/>
+        <img *ngIf="course.courseImage" [src]="course.courseImage" core-external-content alt="" />
     </div>
     <ion-item button lines="none" (click)="openCourse()" [attr.aria-label]="course.displayname || course.fullname"
         class="core-course-header" [class.item-disabled]="course.visible == 0"
-        [class.core-course-only-title]="!showAll || progress < 0 && completionUserTracked === false"
-        detail="false">
-        <ion-label
-            class="ion-text-wrap core-course-title"
+        [class.core-course-only-title]="!showAll || progress < 0 && completionUserTracked === false" detail="false">
+        <ion-label class="ion-text-wrap core-course-title"
             [class.core-course-with-buttons]="courseOptionMenuEnabled || (downloadCourseEnabled && showDownload)"
             [class.core-course-with-spinner]="(downloadCourseEnabled && prefetchCourseData.icon == 'spinner') || showSpinner">
             <p *ngIf="course.categoryname || (course.displayname && course.shortname && course.fullname != course.displayname)"
@@ -19,8 +17,7 @@
                 </span>
                 <span *ngIf="course.categoryname && course.displayname && course.shortname && course.fullname != course.displayname"
                     class="core-course-category"> | </span>
-                <span *ngIf="course.displayname && course.shortname && course.fullname != course.displayname"
-                    class="core-course-shortname">
+                <span *ngIf="course.displayname && course.shortname && course.fullname != course.displayname" class="core-course-shortname">
                     <core-format-text [text]="course.shortname" contextLevel="course" [contextInstanceId]="course.id">
                     </core-format-text>
                 </span>
@@ -35,12 +32,8 @@
         </ion-label>
 
         <div class="core-button-spinner" *ngIf="downloadCourseEnabled && !courseOptionMenuEnabled && showDownload" slot="end">
-            <core-download-refresh
-                [status]="prefetchCourseData.status"
-                [enabled]="downloadCourseEnabled"
-                [statusTranslatable]="prefetchCourseData.statusTranslatable"
-                canTrustDownload="false"
-                [loading]="prefetchCourseData.loading"
+            <core-download-refresh [status]="prefetchCourseData.status" [enabled]="downloadCourseEnabled"
+                [statusTranslatable]="prefetchCourseData.statusTranslatable" canTrustDownload="false" [loading]="prefetchCourseData.loading"
                 (action)="prefetchCourse()"></core-download-refresh>
         </div>
 
@@ -50,9 +43,8 @@
                 [attr.aria-label]="'core.loading' | translate"></ion-spinner>
 
             <!-- Downloaded icon. -->
-            <ion-icon *ngIf="downloadCourseEnabled && prefetchCourseData.downloadSucceeded && !showSpinner"
-                class="core-icon-downloaded" name="cloud-done" color="success" role="status"
-                [attr.aria-label]="'core.downloaded' | translate"></ion-icon>
+            <ion-icon *ngIf="downloadCourseEnabled && prefetchCourseData.downloadSucceeded && !showSpinner" class="core-icon-downloaded"
+                name="cloud-done" color="success" role="status" [attr.aria-label]="'core.downloaded' | translate"></ion-icon>
 
             <!-- Options menu. -->
             <ion-button fill="clear" color="dark" (click)="showCourseOptionsMenu($event)" *ngIf="!showSpinner"
@@ -61,11 +53,9 @@
             </ion-button>
         </div>
     </ion-item>
-    <ion-item *ngIf="showAll && progress >= 0 && completionUserTracked !== false" lines="none"
-        class="core-course-progress">
+    <ion-item *ngIf="showAll && progress >= 0 && completionUserTracked !== false" lines="none" class="core-course-progress">
         <ion-label>
             <core-progress-bar [progress]="progress" a11yText="core.courses.aria:courseprogress"></core-progress-bar>
         </ion-label>
     </ion-item>
-    <ng-content></ng-content>
 </ion-card>
diff --git a/src/theme/theme.base.scss b/src/theme/theme.base.scss
index c74dae05a..4605eabae 100644
--- a/src/theme/theme.base.scss
+++ b/src/theme/theme.base.scss
@@ -788,6 +788,13 @@ ion-select::part(icon) {
     opacity: 1;
 }
 
+ion-select-popover ion-item.core-select-option-title {
+    cursor: pointer;
+    ion-radio {
+        display: none;
+    }
+}
+
 ion-searchbar {
     .searchbar-search-icon.ios {
         top: 4px;