Responsive layout that pairs each problem point with its matching solution, separated by an arrow. Uses glass-style cards and a subtle primary-tinted solution panel; no external dependencies.
Prop | Type | Default / Req. | Description | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
title | String | required | The heading displayed above the problem–solution list. | ||||||||||||
items | Array | required | An array of entries, each containing a `problem` object and a `solution` object. | ||||||||||||
|
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.
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.
<script setup>
const props = defineProps({
title: {
type: String,
required: true,
},
items: {
type: Array,
required: true,
validator: (value) => {
return value.every(
(item) =>
item.pain &&
typeof item.pain.title === "string" &&
typeof item.pain.description === "string" &&
item.solution &&
typeof item.solution.title === "string" &&
typeof item.solution.description === "string"
);
},
},
});
</script>
<template>
<section class="font-iq-paragraph leading-iq-paragraph tracking-iq-paragraph text-iq-paragraph-color">
<h3 class="text-center text-4xl md:text-5xl font-bold mb-16 drop-shadow">
{{ title }}
</h3>
<div class="space-y-16">
<div v-for="(item, index) in items" :key="index" class="grid grid-cols-1 md:grid-cols-11">
<!-- Pain Card -->
<div class="col-span-5 iq-card-glass p-6">
<h4 class="text-2xl font-semibold mb-2">{{ item.pain.title }}</h4>
<p class="">
{{ item.pain.description }}
</p>
</div>
<!-- Arrow Icon -->
<div class="col-span-1 items-center justify-center flex">
<svg
class="w-8 h-8 text-white/50 hidden md:block"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5l7 7-7 7"
/>
</svg>
<!-- Arrow pointing down for mobile -->
<svg
class="w-8 h-8 text-white/50 md:hidden"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M5 9l7 7 7-7"
/>
</svg>
</div>
<!-- Solution Card -->
<div class="col-span-5 iq-card-glass p-6 bg-iq-primary/25">
<h4 class="text-2xl font-semibold mb-2">{{ item.solution.title }}</h4>
<p class="">
{{ item.solution.description }}
</p>
</div>
</div>
</div>
</section>
</template>
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.
<script setup>
const painSolutions = [
{
pain: {
title: "Blind Design Workflow",
description:
"Making styling tweaks in code without immediate feedback leads to endless cycles of preview, adjust, and re-preview—wasting time and sapping confidence.",
},
solution: {
title: "Live Theme Editor",
description:
"Tweak colors, spacing, typography and more via sliders and pickers—and see every component update in real time.",
},
},
{
pain: {
title: "Style Drift",
description:
"Without a single source of truth, developers apply manual overrides and patches, causing buttons, cards, and inputs to look inconsistent across the UI.",
},
solution: {
title: "Token-Driven Components",
description:
"Every button, card and form input reads from your design tokens—so your brand stays consistent without manual overrides.",
},
},
{
pain: {
title: "Reinventing the Wheel",
description:
"Teams spend hours building common sections—contact forms, galleries, footers—from scratch, delaying launches and introducing bugs.",
},
solution: {
title: "Pre-Built Sections",
description:
"Ship faster with ready-made contact forms, galleries, footers and navbars—each fully theme-aware and production-ready.",
},
},
{
pain: {
title: "Locked-Down Codebase",
description:
"Complex, intertwined Vue files make it risky to customize or extend components—teams avoid changes for fear of breaking styles elsewhere.",
},
solution: {
title: "Fully Editable Code",
description:
"Components are simple, independent Vue files—dive in if you need, but most tweaks happen through props or design tokens.",
},
},
];
</script>
<template>
<div class="iq-card-glass max-w-7xl mx-auto p-24">
<SectionsProblemSolution title="Main Problems & Our Solutions" :items="painSolutions" />
</div>
</template>
Decide whether you want a global design-system or a one-off inline snippet.
Complete @theme
block – import once and share across every component.
Copy the code below into main.css
file. It is most likely in assets/css/main.css
directory.
:style
binding – paste straight onto any of ours components.
Copy the code below and paste it into the :style
binding of the component.
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!
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.
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.
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.