Files
zjjk/frontend/src/components/home/PortalCard.vue

93 lines
1.9 KiB
Vue
Raw Normal View History

2026-03-20 21:47:30 +08:00
<script setup lang="ts">
defineProps<{
eyebrow: string
title: string
description: string
bulletPoints: string[]
actionLabel: string
accent: 'gold' | 'teal'
}>()
defineEmits<{
open: []
}>()
</script>
<template>
<article :class="['portal-card', `portal-card--${accent}`]">
<p class="portal-card__eyebrow">{{ eyebrow }}</p>
<h2 class="portal-card__title">{{ title }}</h2>
<p class="portal-card__description">{{ description }}</p>
<ul class="portal-card__list">
<li v-for="point in bulletPoints" :key="point">{{ point }}</li>
</ul>
<button class="portal-card__action" type="button" @click="$emit('open')">
{{ actionLabel }}
</button>
</article>
</template>
<style scoped>
.portal-card {
display: grid;
gap: 1rem;
min-height: 22rem;
padding: 1.6rem;
border: 1px solid rgba(255, 255, 255, 0.08);
background: rgba(8, 14, 26, 0.82);
backdrop-filter: blur(18px);
}
.portal-card--gold {
background:
radial-gradient(circle at top right, rgba(214, 173, 71, 0.18), transparent 35%),
rgba(8, 14, 26, 0.84);
}
.portal-card--teal {
background:
radial-gradient(circle at top right, rgba(55, 175, 160, 0.2), transparent 35%),
rgba(8, 14, 26, 0.84);
}
.portal-card__eyebrow {
margin: 0;
color: var(--color-accent);
letter-spacing: 0.18em;
text-transform: uppercase;
font-size: 0.72rem;
}
.portal-card__title {
margin: 0;
font-family: var(--font-display);
font-size: clamp(1.8rem, 2.4vw, 2.8rem);
line-height: 1.05;
}
.portal-card__description {
margin: 0;
color: var(--color-text-muted);
line-height: 1.7;
}
.portal-card__list {
margin: 0;
padding-left: 1rem;
color: var(--color-text);
display: grid;
gap: 0.65rem;
}
.portal-card__action {
justify-self: start;
padding: 0.9rem 1.3rem;
border: 1px solid rgba(255, 255, 255, 0.12);
background: rgba(255, 255, 255, 0.04);
color: var(--color-text);
cursor: pointer;
}
</style>