Vue SFC Component Composition API not working. Any solutions?

I have made a project using Vue.JS 3 and I am migrating my static HTML website to Vue. I am currently using SFC and the Composition API.

Here is my directory tree of src/

src/
--- assets/
------ fonts/
------ img/
------ base.css
------ logo.svg
------ main.css
--- components/
------ MainComponent.vue
------ NavBar.vue
--- App.vue

I tried using pascal case instead of hyphen case like what others have recommended but the components won’t render. When I open chrome dev tools, all I see is the empty app div. I have made sure that I am regestering my components locally. Here is my source code:

App.vue:

<script setup lang="ts">
import NavBar from './components/NavBar.vue'
import MainContent from './components/MainContent.vue'
</script>

<template>
  <div id="app">
    <NavBar />
    <MainContent />
  </div>
</template>

<style>
@import './assets/base.css';

body {
  color: white;
  font-family: 'Segoe Script';
  background-color: var(--background-primary);
  overflow: scroll;
  overflow-x: hidden;
  margin: 0px;
  padding: 0px;
}

body::-webkit-scrollbar {
  width: 0.25rem;
  background-color: #1e1e24;
}

body::-webkit-scrollbar-track {
  background-color: #1e1e24;
}

body::-webkit-scrollbar-thumb {
  background-color: #6649b8;
}

h1 {
  font-size: 3rem;
}

/* Large Screens */
@media only screen and (min-width: 600px) {
  body {
    zoom: 80%;
  }
}

</style>

MainContent.vue:

<script setup lang="ts">
import KUTE from "kute.js";

const anim = KUTE.fromTo(
  '#blob1',
  {
    path: '#blob1'
  },
  {
    path: '#blob2'
  },
  {
    repeat: 999,
    duration: 3000,
    yoyo: true
  }
)

anim.start()
</script>

<template>
  <main
    class="blurred"
    @mouseover="($event.currentTarget as HTMLElement).classList.add('not-blurred')"
    @mouseleave="($event.currentTarget as HTMLElement).classList.remove('not-blurred')"
  >
    <section class="blue">
      <h1>To Code or Not to Code</h1>
      <p>Front-end UI and UX developer. Python Backend Creator.</p>
      <div class="curve"></div>
    </section>

    <section class="dark2" style="z-index: -1">
      <h1>WIP</h1>
      <p>
        Error ea ut pariatur, ex dolore est incidunt distinctio obcaecati ab, inventore labore
        quisquam facere a. Nostrum quisquam temporibus optio, quibusdam amet, repellendus iste
        doloribus molestiae illum ab voluptatem magnam.
      </p>
    </section>

    <section class="bubble dark2">
      <h1>WIP</h1>
      <p>
        Non, voluptatum illum rem temporibus, repellat explicabo reiciendis est obcaecati cumque,
        debitis ducimus. Repudiandae eveniet qui laboriosam consequuntur, ipsum maiores alias
        consectetur, iure libero esse quibusdam doloribus? Facere, minus maxime.
      </p>
    </section>

    <section class="dark">
      <h1>WIP</h1>
      <p>
        Dolorum tempora et officiis quod recusandae odio quisquam possimus delectus quae nesciunt
        cupiditate iure debitis tempore saepe atque, fugit repellat quasi provident magnam
        asperiores qui aliquam hic quidem enim! Doloremque.
      </p>
    </section>

    <section class="red">
      <h1>WIP</h1>
      <p>
        Sunt assumenda similique sit soluta, ea molestias tempora doloribus ab saepe odio reiciendis
        illum laudantium consequuntur quis possimus hic necessitatibus, provident incidunt, cum
        culpa mollitia alias corporis voluptate. Ullam, saepe.
      </p>
    </section>

    <div class="spacer layer1"></div>

    <section class="dark2" style="z-index: -1">
      <h1>WIP</h1>
      <p>
        Ex quia perferendis voluptatum iure repellendus, reiciendis at maxime, fugit, optio totam
        nesciunt non maiores odio minima libero. Error modi cupiditate dolorem architecto mollitia
        perferendis quas temporibus porro expedita eligendi!
      </p>
    </section>

    <div class="spacer layer2"></div>

    <section class="pink">
      <h1 style="z-index: 1">WIP</h1>
      <p style="z-index: 1">
        Est sed ea nemo, itaque laborum nostrum velit accusamus? Aperiam, nesciunt iste! Iusto
        distinctio quaerat at repellat assumenda, ipsam sit sed expedita! Impedit quasi tempora
        rerum est? Laudantium, perferendis officia!
      </p>
    </section>
    <div class="spacer layer3"></div>

    <section class="dark2">
      <h1>Contact Me</h1>
      <iframe
        src="https://canary.discord.com/widget?id=1132442213272518666&theme=dark"
        width="350"
        height="500"
        allowtransparency="true"
        frameborder="0"
        sandbox="allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts"
      ></iframe>
    </section>
  </main>
</template>

<style scoped>
@import "../assets/base.css";
@import '../assets/main.css';

section {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  min-height: 400px;
  padding: 100px 20vw;
}

.blue {
  background-color: var(--blue);
}

.red {
  background-color: var(--red);
}

.pink {
  background-color: var(--pink);
}

.dark {
  background-color: var(--background-primary);
}

.dark2 {
  background-color: var(--background-secondary);
}

.curve {
  position: absolute;
  height: 225px;
  width: 100%;
  bottom: 0px;
  z-index: 5;
}

.curve::before {
  content: '';
  display: block;
  position: absolute;
  border-radius: 100% 50%;
  width: 55%;
  height: 100%;
  background-color: var(--background-secondary);
  transform: translate(85%, 65%);
  z-index: 20;
}

.curve::after {
  content: '';
  display: block;
  position: absolute;
  border-radius: 100% 50%;
  width: 55%;
  height: 100%;
  background-color: var(--blue);
  transform: translate(-1%, 40%);
  z-index: 20;
}

.bubble {
  z-index: 2;
}

.bubble::after {
  content: '';
  border-top-left-radius: 50% 100%;
  border-top-right-radius: 50% 100%;
  position: absolute;
  bottom: 0px;
  height: 85%;
  width: 100%;
  background-color: var(--background-primary);
  z-index: -2;
}

.svg-wave-opacity-top {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  overflow: hidden;
  line-height: 0;
}

.spacer {
  aspect-ratio: 900/450;
  width: 100%;
  background-size: no-repeat;
  background-position: center;
  background-size: cover;
}

.layer1 {
  background-image: url('../assets/img/layer1.svg');
}

.layer2 {
  background-image: url('../assets/img/layer2.svg');
}

.layer3 {
  background-image: url('../assets/img/layer3.svg');
}

.flip {
  transform: rotate(90deg) scaleX(-1);
}

.blob-motion {
  position: absolute;
  transform: translateY(-20%);
  z-index: 0;
}

.blurred {
  filter: blur(50px);
  transition: all 3s;
}

@media (prefers-reduced-motion) {
  .hidden {
    transition: none;
  }
}

.not-blurred {
  filter: blur(0);
}
</style>

NavBar.vue:

<script setup lang="ts"></script>

<template>
  <nav class="navbar">
    <ul class="navbar-nav">
      <li class="logo">
        <a href="example.com" class="nav-link">
          <span class="link-text fa-primary">To Code or Not to Code</span>
        </a>
      </li>
      <li class="nav-item">
        <a href="example.com" class="nav-link">
          <span class="link-text fa-primary">HTML</span>
        </a>
      </li>
      <li class="nav-item">
        <a href="example.com" class="nav-link">
          <span class="link-text fa-primary">CSS</span>
        </a>
      </li>
      <li class="nav-item">
        <a href="example.com" class="nav-link">
          <span class="link-text fa-primary">JS</span>
        </a>
      </li>
      <li class="nav-item">
        <a href="example.com" class="nav-link">
          <span class="link-text fa-primary">JSON</span>
        </a>
      </li>
      <li class="nav-item">
        <a href="example.com" class="nav-link">
          <span class="link-text fa-primary">XML</span>
        </a>
      </li>
      <li class="nav-item">
        <a href="example.com" class="nav-link">
          <span class="link-text fa-primary">Python</span>
        </a>
      </li>
      <li class="nav-item">
        <a href="example.com" class="nav-link">
          <span class="link-text fa-primary">YouTube</span>
        </a>
      </li>
      <li class="nav-item">
        <a href="example.com" class="nav-link">
          <span class="link-text fa-primary">Discord</span>
        </a>
      </li>
    </ul>
  </nav>
</template>

<style scoped>
@import '../assets/base.css';
@import '../assets/main.css';

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }

  25% {
    transform: rotate(90deg);
  }

  50% {
    transform: rotate(180deg);
  }

  75% {
    transform: rotate(-90deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

@keyframes spin-reverse {
  0% {
    transform: rotate(360deg);
  }

  25% {
    transform: rotate(-90deg);
  }

  50% {
    transform: rotate(-180deg);
  }

  75% {
    transform: rotate(90deg);
  }

  100% {
    transform: rotate(0deg);
  }
}

@-webkit-keyframes spin {
  0% {
    transform: rotate(0deg);
  }

  25% {
    transform: rotate(90deg);
  }

  50% {
    transform: rotate(180deg);
  }

  75% {
    transform: rotate(-90deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

@-webkit-keyframes spin-reverse {
  0% {
    transform: rotate(360deg);
  }

  25% {
    transform: rotate(-90deg);
  }

  50% {
    transform: rotate(-180deg);
  }

  75% {
    transform: rotate(90deg);
  }

  100% {
    transform: rotate(0deg);
  }
}

@-moz-keyframes spin {
  0% {
    transform: rotate(0deg);
  }

  25% {
    transform: rotate(90deg);
  }

  50% {
    transform: rotate(180deg);
  }

  75% {
    transform: rotate(-90deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

@-moz-keyframes spin-reverse {
  0% {
    transform: rotate(360deg);
  }

  25% {
    transform: rotate(-90deg);
  }

  50% {
    transform: rotate(-180deg);
  }

  75% {
    transform: rotate(90deg);
  }

  100% {
    transform: rotate(0deg);
  }
}

@-o-keyframes spin {
  0% {
    transform: rotate(0deg);
  }

  25% {
    transform: rotate(90deg);
  }

  50% {
    transform: rotate(180deg);
  }

  75% {
    transform: rotate(-90deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

@-o-keyframes spin-reverse {
  0% {
    transform: rotate(360deg);
  }

  25% {
    transform: rotate(-90deg);
  }

  50% {
    transform: rotate(-180deg);
  }

  75% {
    transform: rotate(90deg);
  }

  100% {
    transform: rotate(0deg);
  }
}

.navbar {
  position: fixed;
  background-color: var(--background-secondary);
  transition: width 500ms ease;
  z-index: 10;
}

.navbar-nav {
  list-style-type: none;
  padding: 0px;
  margin: 0px;
  display: flex;
  flex-direction: column;
  align-content: center;
  height: 100%;
}

.nav-item {
  width: 100%;
}

.nav-item:nth-last-child(2) {
  margin-top: auto;
}

.nav-link {
  display: flex;
  align-items: center;
  height: 5rem;
  color: var(--text-primary);
  text-decoration: none;
  filter: grayscale(100%) opacity(0.7);
  transition: var(--transition-speed);
}

.link-text {
  display: none;
  margin-left: 1rem;
}

.nav-link svg {
  min-width: 2rem;
  margin: 0 1.5rem;
  filter: grayscale(100%);
}

.fa-primary {
  color: #df49a6;
  fill: #df49a6;
  transition: var(--transition-speed);
}

.logo {
  font-weight: bold;
  text-transform: uppercase;
  margin-bottom: 1rem;
  text-align: center;
  color: var(--text-primary);
  background-color: var(--background-primary);
  letter-spacing: 0.3ch;
  width: 100%;
}

@media only screen and (max-width: 600px) {
  .navbar {
    bottom: 0px;
    width: 100vw;
    height: 5rem;
  }

  .logo {
    display: none;
  }

  .navbar-nav {
    flex-direction: row;
  }

  .nav-link {
    justify-content: center;
  }

  html body .hidden {
    transition: none;
  }

  main {
    margin: 0px;
    padding: 0px;
  }
}

@media only screen and (min-width: 600px) {
  body {
    zoom: 80%;
  }

  .navbar {
    top: 0px;
    width: 5rem;
    height: 100%;
  }

  .navbar:hover {
    width: 16rem;
  }

  .nav-link:hover {
    filter: grayscale(0%) opacity(1);
    background-color: var(--background-primary);
    color: var(--text-primary);
  }

  .logo svg {
    animation: spin-reverse 1s ease-in-out;
    -webkit-animation: spin-reverse 1s ease-in-out;
    -moz-animation: spin-reverse 1s ease-in-out;
    -o-animation: spin-reverse 1s ease-in-out;
  }

  .navbar:hover .logo svg {
    animation: spin 1s ease-in-out;
    -webkit-animation: spin 1s ease-in-out;
    -moz-animation: spin 1s ease-in-out;
    -o-animation: spin 1s ease-in-out;
  }

  .navbar:hover .link-text {
    display: inline;
  }
}
</style>

Expected Result (Old static website):
Working static HTML website

Actual Result (Vue Project):
Actual non-working Vue project

Dev tools of vue project:
Dev tools screenshot of non-working vue project

And console of vue project:
Console of non-working vue project

NOTE: There are SVGs in NavBar.vue and MainContent.vue but Stack Overflow limits my body length so I removed them