Card.vue 1.68 KB
<script setup>
/**
 * Card —— 通用内容容器(Bento 风格表面)。与业务无关,内容经 slot 注入。
 */

defineProps({
  /** 是否带内边距。 */
  padded: { type: Boolean, default: true },
  /** 交互态:hover 抬升 + 指针手势(用于可点击卡片)。 */
  interactive: { type: Boolean, default: false },
})
</script>

<template>
  <div
    class="drama-card"
    :class="{ 'is-padded': padded, 'is-interactive': interactive }"
  >
    <header
      v-if="$slots.header"
      class="drama-card__header"
    >
      <slot name="header" />
    </header>
    <div class="drama-card__body">
      <slot />
    </div>
    <footer
      v-if="$slots.footer"
      class="drama-card__footer"
    >
      <slot name="footer" />
    </footer>
  </div>
</template>

<style scoped>
.drama-card {
  background-color: var(--drama-color-surface);
  color: var(--drama-color-text);
  border: 1px solid var(--drama-color-border);
  border-radius: var(--drama-radius-lg);
  box-shadow: var(--drama-shadow-sm);
  overflow: hidden;
}

.drama-card.is-padded .drama-card__body {
  padding: var(--drama-space-xl);
}

.drama-card.is-interactive {
  cursor: pointer;
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}

.drama-card.is-interactive:hover {
  box-shadow: var(--drama-shadow-md);
  transform: translateY(-2px);
}

.drama-card__header {
  padding: var(--drama-space-lg) var(--drama-space-xl);
  border-bottom: 1px solid var(--drama-color-border);
  font-family: var(--drama-font-family-heading);
  font-weight: var(--drama-font-weight-bold);
}

.drama-card__footer {
  padding: var(--drama-space-lg) var(--drama-space-xl);
  border-top: 1px solid var(--drama-color-border);
}
</style>