diff --git a/Makefile b/Makefile
index 693ef9b2aaec37942c81b422312ea0b5f0751ac4..c483e0b12516af8ea4d80e3cf72efbf340d9a9a1 100644
--- a/Makefile
+++ b/Makefile
@@ -1,10 +1,19 @@
-.PHONY: build run
+.PHONY: build run run-dev unit e2e clean-docker
 
 build-docker:
 	docker build -t sparesti_frontend .
 
 run-docker:
-	docker run -p 5173:5173 sparesti_frontend
+	docker run --rm --name sparesti_frontend_container -p 5173:5173 sparesti_frontend
+
+clean-docker:
+	-docker stop sparesti_frontend_container
+	-docker rm sparesti_frontend_container
+
+run:
+	make build-docker
+	make clean-docker
+	make run-docker
 
 run-dev:
 	npm run dev
@@ -13,4 +22,4 @@ unit:
 	npm run test:unit
 
 e2e:
-	npm run test:e2e
\ No newline at end of file
+	npm run test:e2e
diff --git a/cypress/e2e/homeView.cy.ts b/cypress/e2e/homeView.cy.ts
index c36a497515644ec32fde9cce49a6e3f78850b3ae..8ddc7675b8e2f8c39782ff114013650c1f9a9138 100644
--- a/cypress/e2e/homeView.cy.ts
+++ b/cypress/e2e/homeView.cy.ts
@@ -14,6 +14,13 @@ describe('Goals and Challenges Page Load', () => {
         ],
       },
     }).as('fetchGoals');
+    // Mock the POST request for renewing the token if it's not implemented in the backend
+    cy.intercept('POST', '/auth/renewToken', {
+      statusCode: 200,
+      body: {
+        accessToken: 'newlyRenewedAccessToken'
+      }
+    }).as('renewToken');
 
     cy.intercept('GET', '/challenges', {
       statusCode: 200,
@@ -24,6 +31,14 @@ describe('Goals and Challenges Page Load', () => {
       },
     }).as('fetchChallenges');
 
+    cy.intercept('GET', '/profile/streak', {
+      statusCode: 200,
+      body: {
+        content: [
+          { streak: 1, startDate: "2026-04-29T12:10:38.308Z" },
+        ],
+      },
+    }).as('fetchChallenges');
     // Visit the component that triggers these requests in `onMounted`
     cy.visit('/hjem');
   });
@@ -31,6 +46,13 @@ describe('Goals and Challenges Page Load', () => {
   it('loads and displays goals and challenges after onMounted', () => {
     // Wait for API calls made during `onMounted` to complete
     cy.wait(['@fetchGoals', '@fetchChallenges']);
+    // Mock the POST request for renewing the token if it's not implemented in the backend
+    cy.intercept('POST', '/auth/renewToken', {
+      statusCode: 200,
+      body: {
+        accessToken: 'newlyRenewedAccessToken'
+      }
+    }).as('renewToken');
 
     // Check console logs for any errors or warnings that might indicate issues
     cy.window().then((win) => {
diff --git a/package-lock.json b/package-lock.json
index 962f0ccbb36ff69aa08fc85c6ff4ba24d66f855f..cdbcb6f750f1327fdc33e3e3d5fc21a2a8970dbd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,6 +13,7 @@
         "pinia": "^2.1.7",
         "vue": "^3.4.21",
         "vue-router": "^4.3.1",
+        "vue3-flip-countdown": "^0.1.6",
         "vuedraggable": "^4.1.0"
       },
       "devDependencies": {
@@ -7252,6 +7253,14 @@
         "typescript": "*"
       }
     },
+    "node_modules/vue3-flip-countdown": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/vue3-flip-countdown/-/vue3-flip-countdown-0.1.6.tgz",
+      "integrity": "sha512-RRz+iZ7Zvr1U9mrZRya7I5815jboDyRJz9vzgILq8ZCc2fQ6SxZPYwOr3pD5oWCDBprAEsPF9x4fsTtEitSmXw==",
+      "dependencies": {
+        "vue": "^3.0.0"
+      }
+    },
     "node_modules/vuedraggable": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-4.1.0.tgz",
diff --git a/package.json b/package.json
index be13c2a5d3e4a0451de2749309b751fd1a3e17b4..3d1c8853a603f9b7c4fb8d0e0f161bdd8d57c335 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
     "pinia": "^2.1.7",
     "vue": "^3.4.21",
     "vue-router": "^4.3.1",
+    "vue3-flip-countdown": "^0.1.6",
     "vuedraggable": "^4.1.0"
   },
   "devDependencies": {
diff --git a/src/assets/archerSpare.gif b/src/assets/archerSpare.gif
new file mode 100644
index 0000000000000000000000000000000000000000..ef0e3fa6fd0fcdd700e0e8cb233c4195b90b1355
Binary files /dev/null and b/src/assets/archerSpare.gif differ
diff --git a/src/assets/backgroundSavingsPath.png b/src/assets/backgroundSavingsPath.png
new file mode 100644
index 0000000000000000000000000000000000000000..43cfde5161f862f862f14f8612077b10bbcfb4e2
Binary files /dev/null and b/src/assets/backgroundSavingsPath.png differ
diff --git a/src/assets/boatSpare.gif b/src/assets/boatSpare.gif
new file mode 100644
index 0000000000000000000000000000000000000000..f0aaaa991168e07de3f56e5b129ae082094499f3
Binary files /dev/null and b/src/assets/boatSpare.gif differ
diff --git a/src/assets/borderImage.png b/src/assets/borderImage.png
new file mode 100644
index 0000000000000000000000000000000000000000..1c0ac6cdc5e2ef366679ecd0fb85f51c73ccc65f
Binary files /dev/null and b/src/assets/borderImage.png differ
diff --git a/src/assets/farmerSpare.gif b/src/assets/farmerSpare.gif
new file mode 100644
index 0000000000000000000000000000000000000000..0f471d607f720952491c22b815486d4b58425b76
Binary files /dev/null and b/src/assets/farmerSpare.gif differ
diff --git a/src/assets/finishLine.png b/src/assets/finishLine.png
index f30b5a30213062013638f6e275673d65d0640777..9394bd3c85fed058ab7862e207667d0c9df00ff7 100644
Binary files a/src/assets/finishLine.png and b/src/assets/finishLine.png differ
diff --git a/src/assets/flower.png b/src/assets/flower.png
new file mode 100644
index 0000000000000000000000000000000000000000..c7481c94d5c7f137f0bfaad68fbf20b4d9396f9c
Binary files /dev/null and b/src/assets/flower.png differ
diff --git a/src/assets/infoIcon.png b/src/assets/infoIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..1aef35a260e16d428c804b38c584651fe42a1487
Binary files /dev/null and b/src/assets/infoIcon.png differ
diff --git a/src/assets/pengesekkStreak.png b/src/assets/pengesekkStreak.png
new file mode 100644
index 0000000000000000000000000000000000000000..54565d0fd1ad2795edeaab7eeb614e538d618dc2
Binary files /dev/null and b/src/assets/pengesekkStreak.png differ
diff --git a/src/assets/savingsPathBg.png b/src/assets/savingsPathBg.png
new file mode 100644
index 0000000000000000000000000000000000000000..fb1994e981fffba4df9736cd50ccd71d00e70340
Binary files /dev/null and b/src/assets/savingsPathBg.png differ
diff --git a/src/components/ButtonDIsplayStreak.vue b/src/components/ButtonDIsplayStreak.vue
deleted file mode 100644
index e5043e4fb746882e19dac98ed5cb8c42de707c1e..0000000000000000000000000000000000000000
--- a/src/components/ButtonDIsplayStreak.vue
+++ /dev/null
@@ -1,76 +0,0 @@
-<template>
-    <div class="flex flex-col items-center">
-        <Span class="text-sm text-bold">STREAK</Span>
-        <button @click="toggleStreakCard" class="bg-transparent">
-            <img src="@/assets/streak.png" alt="streak" class="mx-auto w-12 h-12" />
-        </button>
-
-        <div
-            v-if="displayStreakCard"
-            class="w-96 h-64 duration-500 group overflow-hidden absolute top-32 rounded bg-white-800 text-neutral-50 p-4 flex flex-col justify-evenly"
-        >
-            <div
-                class="absolute blur opacity-40 duration-500 group-hover:blur-none w-72 h-72 rounded-full group-hover:translate-x-12 group-hover:translate-y-12 bg-green-100 right-1 -bottom-24"
-            ></div>
-            <div
-                class="absolute blur opacity-40 duration-500 group-hover:blur-none w-12 h-12 rounded-full group-hover:translate-x-12 group-hover:translate-y-2 bg-green-300 right-12 bottom-12"
-            ></div>
-            <div
-                class="absolute blur opacity-40 duration-500 group-hover:blur-none w-36 h-36 rounded-full group-hover:translate-x-12 group-hover:-translate-y-12 bg-green-500 right-1 -top-12"
-            ></div>
-            <div
-                class="absolute blur opacity-40 duration-500 group-hover:blur-none w-24 h-24 bg-green-400 rounded-full group-hover:-translate-x-12"
-            ></div>
-            <div class="z-10 flex flex-col justify-evenly w-full h-full px-4">
-                <span class="text-2xl font-bold text-black"
-                    >{{ currentStreak }}{{ currentStreak === 1 ? ' dag' : ' dager' }} streak</span
-                >
-                <p class="text-black text-1xl font-bold">
-                    {{
-                        currentStreak > 0
-                            ? 'Bra jobba du har spart i ' + currentStreak + ' dager!'
-                            : 'Du har ikke gjort noe i dag. Gjør noe nå for å starte en streak!'
-                    }}
-                </p>
-                <!-- Row component with horizontal padding and auto margins for centering -->
-                <div
-                    class="flex flex-row justify-content-between items-center h-20 w-full mx-auto bg-black-400 gap-4"
-                >
-                    <div class="flex flex-1 overflow-x-auto">
-                        <div v-for="index in 6" :key="index" class="min-w-max mx-auto">
-                            <div class="flex flex-col items-center">
-                                <span class="text-black"
-                                    >Dag {{ currentStreak - ((currentStreak % 7) - index) }}</span
-                                >
-                                <!-- Conditional rendering for streak images -->
-                                <img
-                                    v-if="index - 1 < currentStreak % 7"
-                                    src="@/assets/streak.png"
-                                    alt="challenge completed"
-                                    class="max-h-8 max-w-8"
-                                />
-                                <img
-                                    v-else
-                                    src="@/assets/streak.png"
-                                    alt="challenge not completed"
-                                    class="max-h-8 max-w-8 grayscale"
-                                />
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-    </div>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue'
-
-const displayStreakCard = ref(false)
-const currentStreak = ref(20)
-
-function toggleStreakCard() {
-    displayStreakCard.value = !displayStreakCard.value
-}
-</script>
diff --git a/src/components/ButtonDisplayStreak.vue b/src/components/ButtonDisplayStreak.vue
new file mode 100644
index 0000000000000000000000000000000000000000..50ff4e445c0db7b234538d27824d34a65954824c
--- /dev/null
+++ b/src/components/ButtonDisplayStreak.vue
@@ -0,0 +1,134 @@
+<template>
+    <div class="flex flex-col items-center absolute">
+        <span class="text-sm text-bold">STREAK</span>
+        <button
+            @mouseover="display"
+            @mouseleave="hide"
+            class="cursor-pointer bg-transparent hover:bg-transparent hover:scale-150"
+        >
+            <img
+                src="@/assets/pengesekkStreak.png"
+                alt="streak"
+                class="mx-auto w-6 h-6 md:w-12 md:h-12"
+            />
+        </button>
+
+        <div
+            v-if="displayStreakCard"
+            class="w-[30vh] h-[20vh] md:w-auto md:h-auto group z-50 bg-opacity-50 overflow-hidden absolute left-0 top-14 md:top-20 flex flex-col justify-evenly text-wrap"
+        >
+            <div
+                class="flex flex-col justify-evenly w-full h-full py-2 px-4 md:py-0 bg-white rounded-2xl border-4 border-green-300"
+            >
+                <span class="text-xs md:text-2xl font-bold text-black"
+                    >{{ currentStreak
+                    }}{{
+                        currentStreak === 1 ? ' utfodring fullført' : ' utfodringer fullført'
+                    }}
+                    streak</span
+                >
+                <p class="text-black text-xs md:text-1xl md:font-bold">
+                    {{
+                        currentStreak! > 0
+                            ? 'Bra jobba du har fullført ' + currentStreak + ' utfordringer på rad!'
+                            : 'Du har ikke fullført en utfordring det siste. Fullfør en nå for å starte en streak!'
+                    }}
+                </p>
+                <Countdown
+                    v-if="screenSize > 768 && currentStreak! > 0"
+                    class="flex flex-row"
+                    countdownSize="1rem"
+                    labelSize=".5rem"
+                    mainColor="white"
+                    secondFlipColor="white"
+                    mainFlipBackgroundColor="#30ab0e"
+                    secondFlipBackgroundColor="#9af781"
+                    :labels="{ days: 'dager', hours: 'timer', minutes: 'min', seconds: 'sek' }"
+                    :deadlineISO="deadline"
+                ></Countdown>
+                <!-- Row component with horizontal padding and auto margins for centering -->
+                <div
+                    class="flex flex-row items-center mx-auto h-20 w-4/5 md:w-full bg-black-400 gap-4"
+                >
+                    <div class="flex flex-1 overflow-x-auto">
+                        <div v-for="index in 6" :key="index" class="min-w-max mx-auto">
+                            <div class="flex flex-col justify-around items-center">
+                                <span class="text-black text-xs md:text-1xl font-bold">{{
+                                    currentStreak! - ((currentStreak! % 7) - index)
+                                }}</span>
+                                <!-- Conditional rendering for streak images -->
+                                <img
+                                    v-if="index - 1 < currentStreak! % 7"
+                                    src="@/assets/pengesekkStreak.png"
+                                    alt="challenge completed"
+                                    class="max-h-6 max-w-6 md:max-h-10 md:max-w-10"
+                                />
+                                <img
+                                    v-else
+                                    src="@/assets/pengesekkStreak.png"
+                                    alt="challenge not completed"
+                                    class="max-h-6 max-w-6 md:max-h-10 md:max-w-10 grayscale"
+                                />
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup lang="ts">
+import { onMounted, onUnmounted, ref, watch } from 'vue'
+import { useUserStore } from '@/stores/userStore'
+// @ts-ignore
+import { Countdown } from 'vue3-flip-countdown'
+
+const userStore = useUserStore()
+const currentStreak = ref<number>()
+const streakStart = ref<string>()
+const deadline = ref<string>()
+onMounted(async () => {
+    await userStore.getUserStreak()
+    if (userStore.streak) {
+        currentStreak.value = userStore.streak?.streak
+        streakStart.value = userStore.streak?.streakStart
+        deadline.value = userStore.streak?.streakStart
+    }
+    console.log('Streak:', currentStreak.value)
+    if (typeof window !== 'undefined') {
+        window.addEventListener('resize', handleWindowSizeChange)
+    }
+    handleWindowSizeChange()
+})
+
+const screenSize = ref<number>(window.innerWidth)
+
+onUnmounted(() => {
+    window.removeEventListener('resize', handleWindowSizeChange)
+})
+const handleWindowSizeChange = () => {
+    screenSize.value = window.innerWidth
+}
+
+watch(
+    () => currentStreak.value,
+    (newStreak, oldStreak) => {
+        if (newStreak !== oldStreak) {
+            currentStreak.value = newStreak
+            console.log('Updated Steak:', currentStreak)
+        }
+    },
+    { immediate: true }
+)
+
+const displayStreakCard = ref(false)
+
+const display = () => {
+    displayStreakCard.value = true
+}
+
+const hide = () => {
+    displayStreakCard.value = false
+}
+</script>
diff --git a/src/components/DisplayInfoForChallengeOrGoal.vue b/src/components/DisplayInfoForChallengeOrGoal.vue
new file mode 100644
index 0000000000000000000000000000000000000000..b20221e248f67478e41e6df76fd9e8459645cc7d
--- /dev/null
+++ b/src/components/DisplayInfoForChallengeOrGoal.vue
@@ -0,0 +1,87 @@
+<template>
+    <button @click="display" class="bg-transparent relative p-0 hover:bg-transparent">
+        <img src="@/assets/infoIcon.png" alt="i" class="max-h-4 max-w-4 ml-1" />
+    </button>
+    <div
+        v-if="displayInfoCard"
+        class="w-[40vh] h-[20vh]md:w-60 md:h-40 group z-50 bg-opacity-50 overflow-hidden absolute mt-8 md:mt-4 md:mr-0 flex flex-col justify-evenly text-wrap"
+    >
+        <div
+            class="flex flex-col justify-around w-3/4 md:w-full h-[80%] py-2 px-4 md:py-0 bg-white rounded-2xl border-4 border-green-300 overflow-auto"
+        >
+            <p class="text-base md:text-lg text-wrap text-bold">{{ title.toUpperCase() }}</p>
+            <p class="text-xs md:text-sm text-wrap mb-2">Beskrivelse: {{ description }}</p>
+            <p v-if="completion !== 100" class="text-xs md:text-sm text-nowrap text-green-800">
+                Utløper om:
+            </p>
+            <Countdown
+                v-if="completion !== 100 && screenSize > 763"
+                class="flex flex-row"
+                countdownSize="1.3rem"
+                labelSize=".8rem"
+                mainColor="white"
+                secondFlipColor="white"
+                mainFlipBackgroundColor="#30ab0e"
+                secondFlipBackgroundColor="#9af781"
+                :labels="{ days: 'dager', hours: 'timer', minutes: 'min', seconds: 'sek' }"
+                :deadlineISO="deadline"
+            ></Countdown>
+            <Countdown
+                v-else-if="completion !== 100 && screenSize <= 763"
+                class="flex flex-row"
+                countdownSize="1.0rem"
+                labelSize=".6rem"
+                mainColor="white"
+                secondFlipColor="white"
+                mainFlipBackgroundColor="#30ab0e"
+                secondFlipBackgroundColor="#9af781"
+                :labels="{ days: 'dager', hours: 'timer', minutes: 'min', seconds: 'sek' }"
+                :deadlineISO="deadline"
+            ></Countdown>
+            <p class="text-nowrap text-xs md:text.sm" v-else>
+                Utfordring fullført.<br />
+                Totalt spart: {{ amountSaved }}kr
+            </p>
+        </div>
+    </div>
+</template>
+
+<script setup lang="ts">
+import type { Challenge } from '@/types/challenge'
+import type { Goal } from '@/types/goal'
+import { onUnmounted, ref } from 'vue'
+// @ts-ignore
+import { Countdown } from 'vue3-flip-countdown'
+
+interface Props {
+    challenge: Challenge | null | undefined
+    goal: Goal | null | undefined
+    isChallenge: boolean
+}
+const props = defineProps<Props>()
+
+const description = ref<string>(
+    props.isChallenge ? props.challenge!.description : props.goal!.description
+)
+const title = ref<string>(props.isChallenge ? props.challenge!.title : props.goal!.title)
+const amountSaved = ref<number>(props.isChallenge ? props.challenge!.saved : props.goal!.saved)
+const completion = ref<number>(
+    props.isChallenge ? props.challenge?.completion ?? 0 : props.goal?.completion ?? 0
+)
+const deadline = ref<string>(props.isChallenge ? props.challenge!.due : props.goal!.due)
+
+const displayInfoCard = ref(false)
+
+const display = () => {
+    displayInfoCard.value = !displayInfoCard.value
+}
+
+const screenSize = ref<number>(window.innerWidth)
+
+onUnmounted(() => {
+    window.removeEventListener('resize', handleWindowSizeChange)
+})
+const handleWindowSizeChange = () => {
+    screenSize.value = window.innerWidth
+}
+</script>
diff --git a/src/components/ImgGifTemplate.vue b/src/components/ImgGifTemplate.vue
new file mode 100644
index 0000000000000000000000000000000000000000..46fecc79efe8cca7f8427a1a1e851e0c0ca15b79
--- /dev/null
+++ b/src/components/ImgGifTemplate.vue
@@ -0,0 +1,20 @@
+<template>
+    <div class="hover:scale-125">
+        <img
+            v-if="index % 6 === modValue"
+            :src="url"
+            alt="could not load"
+            class="h-32 w-32 border-2 rounded-lg border-stale-400 shadow-md shadow-black"
+        />
+    </div>
+</template>
+
+<script setup lang="ts">
+interface Props {
+    url: string
+    index: number
+    modValue: number
+}
+
+defineProps<Props>()
+</script>
diff --git a/src/components/NavBarComponent.vue b/src/components/NavBarComponent.vue
index f73a9e94cf8f39d898f8641c099b9ccc91f0506c..d801c739ea7ab26801c7215d1fee8fe05070c038 100644
--- a/src/components/NavBarComponent.vue
+++ b/src/components/NavBarComponent.vue
@@ -10,8 +10,7 @@
             </router-link>
 
             <div class="flex flex-row justify-center">
-                <img alt="streak" class="w-8 h-8" src="@/assets/streakFlame.png" />
-                <p class="font-bold">Streak</p>
+                <ButtonDisplayStreak></ButtonDisplayStreak>
             </div>
         </div>
         <div v-if="!isHamburger" class="flex flex-row gap-10">
@@ -68,6 +67,7 @@ import { RouterLink } from 'vue-router'
 import { onMounted, ref } from 'vue'
 import { useUserStore } from '@/stores/userStore'
 import ModalComponent from '@/components/ModalComponent.vue'
+import ButtonDisplayStreak from '@/components/ButtonDisplayStreak.vue'
 
 const userStore = useUserStore()
 
@@ -95,7 +95,9 @@ const updateWindowWidth = () => {
 }
 
 onMounted(() => {
-    window.addEventListener('resize', updateWindowWidth)
+    if (typeof window !== 'undefined') {
+        window.addEventListener('resize', updateWindowWidth)
+    }
     updateWindowWidth()
 })
 
diff --git a/src/components/SavingsPath.vue b/src/components/SavingsPath.vue
index b71a11bb1b657160eea30453ff91600acded5f0f..5e82a770cc22e2a37bab3fa8752ce7a4b0e858b1 100644
--- a/src/components/SavingsPath.vue
+++ b/src/components/SavingsPath.vue
@@ -1,6 +1,6 @@
 <template>
     <div
-        class="flex flex-col basis-2/3 max-h-full mx-auto max-w-5/6 md:basis-3/4 md:pr-20 md:max-mr-20"
+        class="flex flex-col basis-2/3 max-h-full mx-auto md:ml-20 md:mr-2 max-w-5/6 md:basis-3/4 md:max-pr-20 md:pr-10 md:max-mr-20"
     >
         <div class="flex justify-center align-center">
             <span
@@ -9,18 +9,28 @@
                 Din Sparesti
             </span>
         </div>
+        <button
+            class="h-auto w-auto absolute flex text-center self-end mr-10 md:mr-20 text-wrap shadow-sm shadow-black sm:top-50 sm:text-xs sm:mr-20 lg:mr-32 top-60 z-50 p-2 text-xs md:text-sm"
+            @click="scrollToFirstUncompleted"
+            v-show="!isAtFirstUncompleted"
+        >
+            Ufullførte utfordringer<br />↓
+        </button>
         <div class="h-1 w-4/6 mx-auto my-2 opacity-10"></div>
         <div
             ref="containerRef"
-            class="container relative mx-auto pt-6 w-4/5 md:w-3/5 no-scrollbar h-full max-h-[60vh] md:max-h-[60v] overflow-y-auto border-2 border-slate-300 rounded-lg bg-white shadow-lg"
+            class="container relative pt-6 w-4/5 bg-cover bg-[center] md:[background-position: center;] mx-auto md:w-4/5 no-scrollbar h-full max-h-[60vh] md:max-h-[60vh] md:min-w-2/5 overflow-y-auto border-2 border-transparent rounded-xl bg-white shadow-lg shadow-slate-400"
+            style="background-image: url('src/assets/backgroundSavingsPath.png')"
         >
             <div>
                 <img src="@/assets/start.png" alt="Spare" class="md:w-1/6 md:h-auto h-20" />
             </div>
+
             <div
                 v-for="(challenge, index) in challenges"
-                :key="challenge.title"
+                :key="challenge.id"
                 class="flex flex-col items-center"
+                :ref="(el) => assignRef(el, challenge, index)"
             >
                 <!-- Challenge Row -->
                 <div
@@ -31,31 +41,44 @@
                     class="flex flex-row w-4/5 gap-8"
                 >
                     <div class="right-auto just">
-                        <img
-                            v-if="index === 3"
-                            src="@/assets/sleepingSpare.gif"
-                            alt="could not load"
-                            class="w-32 h-32 border-2 rounded-lg border-stale-400"
-                        />
-                        <img
-                            v-else-if="index === 1"
-                            src="@/assets/golfSpare.gif"
-                            alt="could not load"
-                            class="w-32 h-32 border-2 rounded-lg border-stale-400"
-                        />
+                        <img-gif-template
+                            :index="index"
+                            :mod-value="1"
+                            url="src/assets/golfSpare.gif"
+                        ></img-gif-template>
+                        <img-gif-template
+                            :index="index"
+                            :mod-value="3"
+                            url="src/assets/sleepingSpare.gif"
+                        ></img-gif-template>
+                        <img-gif-template
+                            :index="index"
+                            :mod-value="5"
+                            url="src/assets/archerSpare.gif"
+                        ></img-gif-template>
                     </div>
                     <!-- Challenge Icon and Details -->
                     <div class="flex">
                         <!-- Challenge Icon -->
-                        <div class="flex flex-col items-center">
-                            <p class="text-center" data-cy="challenge-title">
-                                {{ challenge.title }}
-                            </p>
+                        <div class="flex flex-col items-center gap-4">
+                            <div class="flex flex-row flex-nowrap">
+                                <p
+                                    class="text-center text-wrap text-xs md:text-lg"
+                                    data-cy="challenge-title"
+                                >
+                                    {{ challenge.title }}
+                                </p>
+                                <display-info-for-challenge-or-goal
+                                    :goal="goal"
+                                    :challenge="challenge"
+                                    :is-challenge="true"
+                                ></display-info-for-challenge-or-goal>
+                            </div>
                             <img
                                 @click="editChallenge(challenge)"
                                 :data-cy="'challenge-icon-' + challenge.id"
                                 :src="getChallengeIcon(challenge)"
-                                class="max-w-20 max-h-20 cursor-pointer"
+                                class="max-w-20 max-h-20 cursor-pointer hover:scale-125"
                                 :alt="challenge.title"
                             />
                             <!-- Progress Bar, if the challenge is not complete -->
@@ -65,7 +88,7 @@
                                 "
                                 class="flex-grow w-full mt-2"
                             >
-                                <div class="flex flex-row">
+                                <div class="flex flex-row ml-5 md:ml-10 justify-center">
                                     <div class="flex flex-col">
                                         <div
                                             class="bg-gray-200 rounded-full h-2.5 dark:bg-gray-700"
@@ -80,7 +103,7 @@
                                                 }"
                                             ></div>
                                         </div>
-                                        <div class="text-center">
+                                        <div class="text-center text-xs md:text-base">
                                             {{ challenge.saved }}kr / {{ challenge.target }}kr
                                         </div>
                                     </div>
@@ -95,12 +118,14 @@
                                     </button>
                                 </div>
                             </div>
-                            <span v-else class="text-center">Ferdig: {{ challenge.saved }}</span>
+                            <span v-else class="text-center text-xs md:text-base"
+                                >Ferdig: {{ challenge.saved }}</span
+                            >
                         </div>
                         <!-- Check Icon -->
                         <div
                             v-if="challenge.completion !== undefined && challenge.completion >= 100"
-                            class="max-w-10 max-h-10"
+                            class="md:max-w-10 min-w-4 max-w-6 max-h-6 w-full h-auto md:max-h-10 min-h-4"
                         >
                             <img src="@/assets/completed.png" alt="" />️
                         </div>
@@ -109,18 +134,21 @@
                         </div>
                     </div>
                     <div class="">
-                        <img
-                            v-if="index === 0"
-                            src="@/assets/cowboySpare.gif"
-                            alt="could not load"
-                            class="h-32 w-32 border-2 rounded-lg border-stale-400"
-                        />
-                        <img
-                            v-else-if="index === 2"
-                            src="@/assets/hotAirBalloonSpare.gif"
-                            class="h-32 w-32 border-stale-400 border-2 rounded-lg"
-                            alt="could not load"
-                        />
+                        <img-gif-template
+                            :index="index"
+                            :mod-value="0"
+                            url="src/assets/cowboySpare.gif"
+                        ></img-gif-template>
+                        <img-gif-template
+                            :index="index"
+                            :mod-value="2"
+                            url="src/assets/hotAirBalloonSpare.gif"
+                        ></img-gif-template>
+                        <img-gif-template
+                            :index="index"
+                            :mod-value="4"
+                            url="src/assets/farmerSpare.gif"
+                        ></img-gif-template>
                     </div>
                 </div>
                 <!-- Piggy Steps, centered -->
@@ -155,9 +183,17 @@
         </div>
         <!-- Goal -->
         <div v-if="goal" class="flex flex-row justify-around m-t-2 pt-6 w-full mx-auto">
-            <div class="flex flex-col items-start cursor-pointer" @click="editGoal(goal)">
-                <img :src="getGoalIcon(goal)" class="w-12 h-12 mx-auto" :alt="goal.title" />
-                <div class="text-lg font-bold" data-cy="goal-title">{{ goal.title }}</div>
+            <div class="grid grid-rows-2 grid-flow-col gap 4">
+                <div class="row-span-3 cursor-pointer" @click="editGoal(goal)">
+                    <img :src="getGoalIcon(goal)" class="w-12 h-12 mx-auto" :alt="goal.title" />
+                    <div class="text-lg font-bold" data-cy="goal-title">{{ goal.title }}</div>
+                </div>
+                <display-info-for-challenge-or-goal
+                    class="col-span-2"
+                    :goal="goal"
+                    :challenge="null"
+                    :is-challenge="false"
+                ></display-info-for-challenge-or-goal>
             </div>
             <div class="flex flex-col items-end">
                 <div @click="goToEditGoal" class="cursor-pointer">
@@ -182,7 +218,16 @@
 </template>
 
 <script setup lang="ts">
-import { nextTick, onMounted, type Ref, ref, watch } from 'vue'
+import {
+    type ComponentPublicInstance,
+    nextTick,
+    onMounted,
+    onUnmounted,
+    reactive,
+    type Ref,
+    ref,
+    watch
+} from 'vue'
 import anime from 'animejs'
 import type { Challenge } from '@/types/challenge'
 import type { Goal } from '@/types/goal'
@@ -190,6 +235,8 @@ import confetti from 'canvas-confetti'
 import { useRouter } from 'vue-router'
 import { useGoalStore } from '@/stores/goalStore'
 import { useChallengeStore } from '@/stores/challengeStore'
+import DisplayInfoForChallengeOrGoal from '@/components/DisplayInfoForChallengeOrGoal.vue'
+import ImgGifTemplate from '@/components/ImgGifTemplate.vue'
 
 const router = useRouter()
 const goalStore = useGoalStore()
@@ -204,6 +251,110 @@ const props = defineProps<Props>()
 const challenges = ref<Challenge[]>(props.challenges)
 const goal = ref<Goal | null | undefined>(props.goal)
 
+onMounted(async () => {
+    await goalStore.getUserGoals()
+    window.addEventListener('resize', handleWindowSizeChange)
+    handleWindowSizeChange()
+    sortChallenges()
+})
+
+const sortChallenges = () => {
+    challenges.value.sort((a, b) => {
+        // First, sort by completion status: non-completed (less than 100) before completed (100)
+        if (a.completion !== 100 && b.completion === 100) {
+            return 1 // 'a' is not completed and 'b' is completed, 'a' should come first
+        } else if (a.completion === 100 && b.completion !== 100) {
+            return -1 // 'a' is completed and 'b' is not, 'b' should come first
+        } else {
+            // Explicitly convert dates to numbers for subtraction
+            const dateA = new Date(a.due).getTime()
+            const dateB = new Date(b.due).getTime()
+            return dateA - dateB
+        }
+    })
+}
+
+const screenSize = ref<number>(window.innerWidth)
+
+onUnmounted(() => {
+    window.removeEventListener('resize', handleWindowSizeChange)
+})
+const handleWindowSizeChange = () => {
+    screenSize.value = window.innerWidth
+}
+
+interface ElementRefs {
+    [key: string]: HTMLElement | undefined
+}
+
+const elementRefs = reactive<ElementRefs>({})
+
+const isAtFirstUncompleted = ref(false) // This state tracks visibility of the button
+const firstUncompletedRef: Ref<HTMLElement | undefined> = ref()
+
+function scrollToFirstUncompleted() {
+    let found = false
+    for (let i = 0; i < challenges.value.length; i++) {
+        if (challenges.value[i].completion! < 100) {
+            const refKey = `uncompleted-${i}`
+            if (elementRefs[refKey]) {
+                elementRefs[refKey]!.scrollIntoView({ behavior: 'smooth', block: 'start' })
+                firstUncompletedRef.value = elementRefs[refKey] // Store the reference
+                found = true
+                isAtFirstUncompleted.value = true
+                break
+            }
+        }
+    }
+    if (!found) {
+        isAtFirstUncompleted.value = false
+    }
+}
+
+onMounted(() => {
+    const container = containerRef.value
+    if (container) {
+        container.addEventListener('scroll', () => {
+            if (!firstUncompletedRef.value) return
+            const containerRect = container.getBoundingClientRect()
+            const firstUncompletedRect = firstUncompletedRef.value.getBoundingClientRect()
+            isAtFirstUncompleted.value = !(
+                firstUncompletedRect.top > containerRect.bottom ||
+                firstUncompletedRect.bottom < containerRect.top
+            )
+        })
+    }
+    scrollToFirstUncompleted()
+})
+
+onUnmounted(() => {
+    const container = containerRef.value
+    if (container) {
+        container.removeEventListener('scroll', () => {
+            // Clean up the scroll listener
+        })
+    }
+})
+
+const assignRef = (
+    el: Element | ComponentPublicInstance | null,
+    challenge: Challenge,
+    index: number
+) => {
+    const refKey = `uncompleted-${index}`
+    if (el instanceof HTMLElement) {
+        // Ensure that el is an HTMLElement
+        if (challenge.completion! < 100) {
+            elementRefs[refKey] = el
+        }
+    } else {
+        // Cleanup if the element is unmounted or not an HTMLElement
+        if (elementRefs[refKey]) {
+            delete elementRefs[refKey]
+        }
+    }
+}
+
 // Utilizing watch to specifically monitor for changes in the props
 watch(
     () => props.goal,
@@ -221,6 +372,7 @@ watch(
     (newChallenges, oldChallenges) => {
         if (newChallenges !== oldChallenges) {
             challenges.value = newChallenges
+            sortChallenges()
             console.log('Updated challenges:', challenges.value)
         }
     },
@@ -243,15 +395,13 @@ const addSpareUtfordring = () => {
 
 // Increment saved amount
 const incrementSaved = async (challenge: Challenge) => {
-    // Set a default increment amount per purchase
-    challenge.perPurchase = 20
-
     // Safely increment the saved amount, ensuring it exists
     challenge.saved += challenge.perPurchase
 
     // Check if the saved amount meets or exceeds the target
     if (challenge.saved >= challenge.target) {
         challenge.completion = 100
+        await challengeStore.completeUserChallenge(challenge)
     }
 
     console.log('Incrementing saved amount for:', challenge)
diff --git a/src/components/__tests__/NavBarTest.spec.ts b/src/components/__tests__/NavBarTest.spec.ts
index fe7a36b37ea2d6cf0624bc4474562fdb13f5d585..909005bc2b57920c924452770fbbf5cccdb74683 100644
--- a/src/components/__tests__/NavBarTest.spec.ts
+++ b/src/components/__tests__/NavBarTest.spec.ts
@@ -3,8 +3,29 @@ import NavBar from '@/components/NavBarComponent.vue'
 import router from '@/router'
 import { createPinia, setActivePinia } from 'pinia'
 import { beforeEach, describe, expect, it, vi } from 'vitest'
+import { nextTick } from 'vue'
 
 vi.stubGlobal('scrollTo', vi.fn())
+// Mocking Axios correctly using `importOriginal`
+const mocks = vi.hoisted(() => ({
+    get: vi.fn(),
+    post: vi.fn()
+}))
+
+vi.mock('axios', async (importActual) => {
+    const actual = await importActual<typeof import('axios')>()
+
+    return {
+        default: {
+            ...actual.default,
+            create: vi.fn(() => ({
+                ...actual.default.create(),
+                get: mocks.get,
+                post: mocks.post
+            }))
+        }
+    }
+})
 
 describe('NavBar Routing', () => {
     let wrapper: VueWrapper<any>
@@ -21,6 +42,7 @@ describe('NavBar Routing', () => {
 
         await router.push({ name: 'start' })
         await router.isReady()
+        await nextTick()
     })
 
     it('renders without errors', () => {
diff --git a/src/components/__tests__/savingsPathTest.spec.ts b/src/components/__tests__/savingsPathTest.spec.ts
index dea8650e2ad5d6ced6b43bfd45ce7bc012319875..40739f5a4e0a9b042239fadd17c40fe3ae9c6a61 100644
--- a/src/components/__tests__/savingsPathTest.spec.ts
+++ b/src/components/__tests__/savingsPathTest.spec.ts
@@ -11,12 +11,32 @@ vi.mock('canvas-confetti', () => ({
         clear: vi.fn()
     }))
 }))
+const mocks = vi.hoisted(() => ({
+    get: vi.fn(),
+    post: vi.fn()
+}))
+
+vi.mock('axios', async (importActual) => {
+    const actual = await importActual<typeof import('axios')>()
+
+    return {
+        default: {
+            ...actual.default,
+            create: vi.fn(() => ({
+                ...actual.default.create(),
+                get: mocks.get,
+                post: mocks.post
+            }))
+        }
+    }
+})
 
 describe('SavingsPath Component', () => {
     let wrapper: any
     const pinia = createPinia()
 
     beforeEach(() => {
+        window.HTMLElement.prototype.scrollIntoView = function () {}
         setActivePinia(pinia)
         wrapper = mount(SavingsPath, {
             global: {
@@ -94,6 +114,7 @@ describe('SavingsPath Component', () => {
                 ]
             })
             await wrapper.vm.$nextTick()
+            await wrapper.vm.$nextTick()
 
             progressBar = wrapper.find('.bg-green-600')
             expect(progressBar.element.style.width).toBe('90%')
diff --git a/src/stores/challengeStore.ts b/src/stores/challengeStore.ts
index 8e4529c5cd004d75a741cd132bc35fa7d7e80310..a8417aa62bf51495a6a06b401145b0fe06f34a06 100644
--- a/src/stores/challengeStore.ts
+++ b/src/stores/challengeStore.ts
@@ -41,10 +41,31 @@ export const useChallengeStore = defineStore('challenge', () => {
             console.error('Error updating challenge:', error)
         }
     }
+    const completeUserChallenge = async (challenge: Challenge) => {
+        try {
+            const response = await authInterceptor.put(
+                `/challenges/${challenge.id}/complete`,
+                challenge
+            )
+            if (response.data) {
+                // Update local challenge state to reflect changes
+                const index = challenges.value.findIndex((c) => c.id === challenge.id)
+                if (index !== -1) {
+                    challenges.value[index] = { ...challenges.value[index], ...response.data }
+                    console.log('Updated Challenge:', response.data)
+                }
+            } else {
+                console.error('No challenge content found in response data')
+            }
+        } catch (error) {
+            console.error('Error updating challenge:', error)
+        }
+    }
 
     return {
         challenges,
         getUserChallenges,
-        editUserChallenge
+        editUserChallenge,
+        completeUserChallenge
     }
 })
diff --git a/src/stores/userStore.ts b/src/stores/userStore.ts
index a40bd558854b047a2e60b747563c1bad88bb6566..dd6bc42fa024c1e2b2b61876ec92694c561a82dd 100644
--- a/src/stores/userStore.ts
+++ b/src/stores/userStore.ts
@@ -4,9 +4,10 @@ import type { User } from '@/types/user'
 import router from '@/router'
 import type { AxiosError } from 'axios'
 import axios from 'axios'
+import authInterceptor from '@/services/authInterceptor'
+import type { Streak } from '@/types/streak'
 import type { CredentialRequestOptions } from '@/types/CredentialRequestOptions'
 import { base64urlToUint8array, initialCheckStatus, uint8arrayToBase64url } from '@/util'
-import authInterceptor from '@/services/authInterceptor'
 import type { CredentialCreationOptions } from '@/types/CredentialCreationOptions'
 
 export const useUserStore = defineStore('user', () => {
@@ -19,6 +20,7 @@ export const useUserStore = defineStore('user', () => {
 
     const user = ref<User>(defaultUser)
     const errorMessage = ref<string>('')
+    const streak = ref<Streak>()
 
     const register = async (
         firstname: string,
@@ -84,6 +86,21 @@ export const useUserStore = defineStore('user', () => {
         user.value = defaultUser
         router.push({ name: 'login' })
     }
+    const getUserStreak = async () => {
+        try {
+            const response = await authInterceptor('/profile/streak')
+            if (response.data) {
+                streak.value = response.data
+                console.log('Fetched Challenges:', streak.value)
+            } else {
+                streak.value = undefined
+                console.error('No challenge content found:', response.data)
+            }
+        } catch (error) {
+            console.error('Error fetching challenges:', error)
+            streak.value = undefined // Ensure challenges is always an array
+        }
+    }
 
     const bioRegister = async () => {
         try {
@@ -237,6 +254,8 @@ export const useUserStore = defineStore('user', () => {
         logout,
         bioLogin,
         bioRegister,
-        errorMessage
+        errorMessage,
+        getUserStreak,
+        streak
     }
 })
diff --git a/src/types/streak.ts b/src/types/streak.ts
new file mode 100644
index 0000000000000000000000000000000000000000..61dafae24c954c7ca99a3596ca43a659f1ef122c
--- /dev/null
+++ b/src/types/streak.ts
@@ -0,0 +1,4 @@
+export interface Streak {
+    streakStart?: string
+    streak?: number
+}