about
Thin
cards
ChecksCompareImageMinimalplainSteps
contact
Address
core
Consent
footer
Slim
hero
Bigcentral
lists
Panel
nav
Slimslim Desktopslim MobileSpringSpring DesktopSpring Mobile
sections
Problem SolutionSimple
text
largeParagraph

Theme Customizer

v1.0

Slim nav

Combines PublicNavSlimDesktop with PublicNavSlimMobile: a minimal desktop header and a slide-in mobile drawer sharing state via v-model and a toggle event. Includes brand logo and link list.

navigationnavbarmobiledesktopcomboui

Get the code!

License Summary

You may use these UI components in your own personal or commercial projects. You may not resell, redistribute, sublicense, or package them as standalone assets or template/library packs.

Full terms: End-User License Agreement

Below you can expand the main implementation file and any supporting components. Use the “Copy” button to grab a snippet straight to your clipboard.

1 Copy raw components

These are the raw components that are required to run this example. Copy-paste them into your project. Most likely you will not change anything in these files, but you can if you want to. These are the components that are used in the main implementation file.

slimDesktop.vue
<script setup>
const emit = defineEmits(["toggleMobile"]);
const props = defineProps({
  logo: {
    type: String,
    default: "Your logo",
  },
  links: {
    type: Array,
    required: true,
    validator: (v) => {
      return v.every((link) => {
        return typeof link.path === "string" && typeof link.name === "string";
      });
    },
  },
});
</script>
<template>
  <nav
    class="flex items-center justify-between w-full font-iq-paragraph leading-iq-paragraph tracking-iq-paragraph text-iq-paragraph-color"
  >
    <!-- Logo / Home Link -->
    <NuxtLink
      to="/"
      class="text-3xl md:text-4xl font-black drop-shadow-lg font-iq-header leading-iq-header tracking-iq-header text-iq-header-color"
    >
      <slot name="logo">{{ logo }}</slot>
    </NuxtLink>

    <!-- Nav Links (desktop) -->
    <div class="hidden md:flex items-center gap-6 ">
      <template v-for="(link, index) in links" :key="index">
        <NuxtLink
          :to="link.path"
          :class="{
            'text-center text-iq-paragraph-color/80 hover:text-iq-paragraph-color px-6 py-3 rounded-full bg-white/10 backdrop-blur-lg ring-1 ring-white/20 hover:bg-white/20 hover:ring-white/40 transition text-sm font-semibold uppercase': link.highlight,
            'text-sm font-semibold uppercase text-iq-paragraph-color/80 hover:text-iq-paragraph-color  transition': !link.highlight
          }"
        >
          {{ link.name }}
        </NuxtLink>

      </template>
    </div>

    <!-- Hamburger (mobile) -->

    <button
      @click="emit('toggleMobile')"
      class="p-2 rounded-lg bg-white/10 hover:bg-white/20 transition md:hidden"
      aria-label="Open menu"
    >
      <!-- Hamburger Icon -->
      <svg
        xmlns="http://www.w3.org/2000/svg"
        class="h-6 w-6 text-white/80"
        fill="none"
        viewBox="0 0 24 24"
        stroke="currentColor"
      >
        <path
          stroke-linecap="round"
          stroke-linejoin="round"
          stroke-width="2"
          d="M4 6h16M4 12h16M4 18h16"
        />
      </svg>
    </button>
  </nav>
</template>

slimMobile.vue
<script setup>
import { ref } from "vue";

defineProps({

  logo: {
    type: String,
  },

  links: {
    type: Array,
    required: true,
    validate: (value) => {
      return value.every((item) => {
        return typeof item.name === "string" && typeof item.path === "string";
      });
    },
  }

});

const isOpen = defineModel()

/**
 * Toggle the mobile menu open/close state
 */
function toggleMenu() {
  isOpen.value = !isOpen.value;
}

defineExpose({
  toggleMenu,
  
});
</script>

<template>
  <nav class="fixed top-0 left-0 w-full z-50 font-iq-paragraph leading-iq-paragraph tracking-iq-paragraph text-iq-paragraph-color">
    <!-- Backdrop -->
    <transition name="fade">
      <div
        v-if="isOpen"
        class="fixed inset-0 bg-black/50 backdrop-blur-sm"
        @click="toggleMenu"
      />
    </transition>

    <!-- Menu panel -->
    <transition name="slide">
      <aside
        v-if="isOpen"
        class="fixed top-0 left-0 h-full w-64 py-12 bg-white/10 backdrop-blur-lg ring-1 ring-white/20 rounded-r-iq-roundness shadow-xl flex flex-col"
      >
        <div class="flex flex-row items-center justify-between px-6">
          <!-- Name -->
          <NuxtLink
            to="/"
            class="text-2xl font-bold text-white tracking-tight"
            @click="toggleMenu"
          >
            <slot name="logo">{{ logo }}</slot>
          </NuxtLink>

          <button class="self-end p-2" @click="toggleMenu" aria-label="Close menu">
            <!-- X Icon -->
            <svg
              xmlns="http://www.w3.org/2000/svg"
              class="h-6 w-6 text-white/80"
              fill="none"
              viewBox="0 0 24 24"
              stroke="currentColor"
            >
              <path
                stroke-linecap="round"
                stroke-linejoin="round"
                stroke-width="2"
                d="M6 18L18 6M6 6l12 12"
              />
            </svg>
          </button>
        </div>

        <ul class="mt-6 space-y-2">
          <li v-for="item in links" :key="item.path">
            <NuxtLink
              :to="item.path"
              class="block px-6 py-3 bg-white/5 text-lg font-medium text-white active:bg-white/15 transition duration-150"
              active-class="bg-white/15"
              @click="toggleMenu"
            >
              {{ item.name }}
            </NuxtLink>
          </li>
        </ul>

        <div class="mt-auto border-t border-white/20 pt-4 px-6">
          <slot name="footer">
            <a
              href="#"
              class="block text-sm text-white/70 hover:text-white/90 transition"
            >
              © 2025 My Company
            </a>
          </slot>
        </div>
      </aside>
    </transition>
  </nav>
</template>

<style scoped>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.2s ease;
}
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

.slide-enter-active {
  transition: transform 0.3s ease;
}
.slide-enter-from {
  transform: translateX(-100%);
}
.slide-leave-active {
  transition: transform 0.2s ease;
}
.slide-leave-to {
  transform: translateX(-100%);
}
</style>

2 Copy main implementation file

This is the main Vue file that uses the component. Copy-paste this into your project. In this code feel free to change anything you like, such as the component name, props, or class. This is the place where you control the main component.

slim.vue
<script setup>
const links = [
  { name: "Get started", path: "/get-started" },
  { name: "Learn more", path: "/learn-more" },
  { name: "Components", path: "/components" },
  { name: "Some page", path: "/" },
  { name: "Contact", path: "/" },
];


const isOpen = ref(true);
</script>

<template>
  <div>
       <!-- Header -->
    <NavSlimDesktop
    class="max-w-7xl mx-auto px-6 py-8"
     :links="links" @toggleMobile="isOpen = !isOpen"
     logo="Flex Ui Lib"
      />

    <NavSlimMobile
      :links="links"
      logo="Flex Ui Lib"
      v-model="isOpen"
      class="md:hidden text-2xl p-2 rounded hover:bg-white/10 transition"
      aria-label="Toggle navigation"
    />
  </div>
</template>

3 Apply your styles

Decide whether you want a global design-system  or a one-off inline snippet.

Full design system

Complete @theme block – import once and share across every component.

Use when:

  • You want to use multiple components across your site, and you want them to match your design system.
  • You want to change the design of all components at once.

How to use:

Copy the code below into main.css file. It is most likely in assets/css/main.css directory.

Single component

:style binding – paste straight onto any of ours components.

Use when:

  • You want to use a single component without affecting the rest of your design system.
  • You already use multiple components but you want this one to have a different style.

How to use:

Copy the code below and paste it into the :style binding of the component.

4 Manual Actions

I wish I could automate every little thing—but for now you’ll need to handle these final steps by hand. Apologies for the extra work!

Paste your chosen iq-card-* style

Now that you’ve picked a card preset, copy its CSS into your @layer components block in main.css. This ensures every `iq-card` wrapper will look just right.

Copy or customize iq-cta

iq-cta is the main call to action button class. It’s used in many places across the components. But for now it is only a single class that you can customize. You can copy the code below and paste it into your @layer components block in main.css. In future you will be able to fully customize it from our UI and choose from many presets.

3. Audit forms & inputs if you used any

I didn't have time to figure out consistency. Although there are no actions required, be mindful that the forms might not be entirely consistent with the design system. A quick once-over will keep everything looking sharp.