54 lines
1.9 KiB
Vue
54 lines
1.9 KiB
Vue
<script setup>
|
|
defineProps({
|
|
image: { type: String, required: true },
|
|
title: { type: String, required: true },
|
|
description: { type: String, required: true },
|
|
action: {
|
|
type: Object,
|
|
default: () => ({ color: 'success', label: 'Find Out More', route: '#' }),
|
|
},
|
|
})
|
|
|
|
// action.color is a design-system color name: 'success', 'primary', etc.
|
|
const btnClasses = {
|
|
primary: 'bg-gradient-primary shadow-primary text-white',
|
|
secondary: 'bg-gradient-secondary shadow-secondary text-white',
|
|
success: 'bg-gradient-success shadow-success text-white',
|
|
warning: 'bg-gradient-warning shadow-warning text-white',
|
|
danger: 'bg-gradient-danger shadow-danger text-white',
|
|
info: 'bg-gradient-info shadow-info text-white',
|
|
dark: 'bg-gradient-dark shadow-dark text-white',
|
|
light: 'bg-gradient-light shadow-soft-sm text-dark',
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="rounded-2xl bg-white shadow-soft-md overflow-visible">
|
|
<!-- Floating image header — overlaps the card top -->
|
|
<div class="relative -mt-6 mx-4 z-10 overflow-hidden rounded-xl shadow-soft-lg">
|
|
<a :href="action.route" class="block">
|
|
<img
|
|
:src="image"
|
|
:alt="title"
|
|
class="h-48 w-full object-cover transition-transform duration-500 hover:scale-105"
|
|
/>
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Body -->
|
|
<div class="px-6 pb-6 pt-4 text-center">
|
|
<h5 class="font-semibold text-dark">
|
|
<a :href="action.route" class="hover:text-primary transition-colors">{{ title }}</a>
|
|
</h5>
|
|
<p class="mt-2 text-sm text-secondary leading-relaxed">{{ description }}</p>
|
|
<button
|
|
type="button"
|
|
class="mt-4 inline-flex items-center justify-center rounded-lg px-5 py-2 text-sm font-medium transition-all hover:-translate-y-0.5"
|
|
:class="btnClasses[action.color] ?? btnClasses.success"
|
|
>
|
|
{{ action.label }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</template>
|