Files
hunli/vite-tailwindcss/src/components/themes/SectionHeading.vue

376 lines
9.2 KiB
Vue
Raw Normal View History

2026-08-12 13:53:06 +08:00
<template>
<div class="sh" :class="`sh-${kind}`">
<span v-if="indexText" class="sh-index">{{ indexText }}</span>
<span v-if="kicker" class="sh-kicker">{{ kicker }}</span>
<i class="sh-rule sh-rule-top" aria-hidden="true"></i>
<span class="sh-title">{{ title }}</span>
<i class="sh-rule sh-rule-bottom" aria-hidden="true"></i>
<span v-if="note" class="sh-note">{{ note }}</span>
</div>
</template>
<script setup>
/**
* 完整模板(layout 主题)的统一章节头。
* 结构固定,观感按 html[data-theme](magazine/newspaper/pixel/zen)差异化:
* - magazine 左对齐编号大字
* - newspaper 居中栏目头,双细线夹标题
* - pixel 像素方框标题
* - zen 小字 + 细线 + 大留白
* pack 主题不使用本组件(各区块保留原有专属设计)。
*/
import { computed } from 'vue'
const props = defineProps({
title: { type: String, default: '' },
kicker: { type: String, default: '' },
note: { type: String, default: '' },
/** 章节序号(杂志风显示为 01/02…) */
index: { type: Number, default: 0 },
/** 当前主题 key(用于组件内微调,可不传) */
kind: { type: String, default: 'layout' },
})
const indexText = computed(() => (props.index > 0 ? String(props.index).padStart(2, '0') : ''))
</script>
<style scoped>
.sh {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: 6px;
margin-bottom: 22px;
}
.sh-index {
display: none;
font-family: var(--font-display);
font-style: italic;
line-height: 1;
color: rgba(var(--c-primary-rgb), 0.34);
}
.sh-kicker {
font-family: var(--t-font-kicker);
font-size: 11px;
letter-spacing: 0.34em;
text-transform: uppercase;
color: var(--c-muted);
}
.sh-title {
font-family: var(--t-font-title);
font-size: 24px;
letter-spacing: 0.16em;
color: var(--c-ink);
line-height: 1.3;
}
.sh-note {
font-size: 11px;
letter-spacing: 0.12em;
color: var(--c-muted);
max-width: 300px;
line-height: 1.9;
white-space: pre-wrap;
}
.sh-rule {
display: none;
pointer-events: none;
}
/* —— 新中式:宋体 + 端部朱砂方点 + 细黛线 —— */
html[data-theme='guofeng-new'] .sh-kicker {
font-family: var(--font-kai);
letter-spacing: 0.44em;
}
html[data-theme='guofeng-new'] .sh-title {
font-family: var(--font-serif);
font-weight: 600;
letter-spacing: 0.3em;
text-indent: 0.3em;
}
html[data-theme='guofeng-new'] .sh-rule-bottom {
display: block;
width: 8px;
height: 8px;
background: #b5493f;
border-radius: 1px;
margin-top: 2px;
}
/* —— 老中式:楷体横批 + 金线双边 —— */
html[data-theme='guofeng-old'] .sh-kicker {
font-family: var(--font-kai);
letter-spacing: 0.4em;
color: var(--c-line);
}
html[data-theme='guofeng-old'] .sh-title {
font-family: var(--font-kai);
font-weight: 700;
letter-spacing: 0.4em;
text-indent: 0.4em;
color: var(--c-primary);
}
html[data-theme='guofeng-old'] .sh-rule {
display: block;
width: min(220px, 62%);
height: 5px;
border-top: 1px solid rgba(var(--c-line-rgb), 0.85);
border-bottom: 1px solid rgba(var(--c-line-rgb), 0.45);
}
/* —— 杂志封面:左对齐、超大编号、大写大字距 —— */
html[data-theme='magazine'] .sh {
align-items: flex-start;
text-align: left;
padding-left: 2px;
gap: 2px;
}
html[data-theme='magazine'] .sh-index {
display: block;
font-size: 52px;
margin-bottom: 2px;
}
html[data-theme='magazine'] .sh-kicker {
font-size: 10px;
letter-spacing: 0.5em;
color: var(--c-primary);
}
html[data-theme='magazine'] .sh-title {
font-family: var(--font-display);
font-size: 30px;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
}
html[data-theme='magazine'] .sh-rule-top {
display: block;
order: -1;
width: 44px;
height: 3px;
background: var(--c-ink);
margin-bottom: 8px;
}
html[data-theme='magazine'] .sh-note {
text-align: left;
}
/* —— 日报编辑:居中栏目头,双细线夹标题 —— */
html[data-theme='newspaper'] .sh {
gap: 8px;
}
html[data-theme='newspaper'] .sh-kicker {
font-family: var(--font-display);
font-size: 10px;
letter-spacing: 0.44em;
}
html[data-theme='newspaper'] .sh-title {
font-family: var(--font-serif);
font-weight: 700;
font-size: 25px;
letter-spacing: 0.22em;
}
html[data-theme='newspaper'] .sh-rule {
display: block;
width: min(240px, 68%);
height: 3px;
border-top: 1px solid var(--c-ink);
border-bottom: 1px solid var(--c-ink);
}
html[data-theme='newspaper'] .sh-note {
font-family: var(--font-serif);
font-style: italic;
}
/* —— 复古像素:像素方框标题 —— */
html[data-theme='pixel'] .sh-kicker {
font-size: 10px;
letter-spacing: 0.2em;
color: var(--c-line);
}
html[data-theme='pixel'] .sh-title {
font-size: 19px;
letter-spacing: 0.1em;
padding: 8px 16px;
color: var(--c-primary);
border: 3px solid var(--c-primary);
box-shadow: 4px 4px 0 rgba(var(--c-line-rgb), 0.55);
image-rendering: pixelated;
}
html[data-theme='pixel'] .sh-note {
font-size: 10px;
}
/* —— 水墨:楷体 + 墨横 + 朱砂点 —— */
html[data-theme='inkwash'] .sh-kicker {
font-family: var(--font-kai);
letter-spacing: 0.4em;
}
html[data-theme='inkwash'] .sh-title {
font-family: var(--font-kai);
letter-spacing: 0.36em;
text-indent: 0.36em;
}
html[data-theme='inkwash'] .sh-rule-bottom {
display: block;
width: 46px;
height: 3px;
background: linear-gradient(90deg, transparent, var(--c-ink) 30%, var(--c-ink) 70%, transparent);
border-radius: 2px;
}
/* —— 电影:场记板 SCENE —— */
html[data-theme='cinema'] .sh-index {
display: block;
font-family: var(--font-number);
font-style: normal;
font-size: 13px;
letter-spacing: 0.2em;
color: var(--c-on-primary);
background: var(--c-primary);
padding: 3px 10px;
border-radius: 3px;
transform: rotate(-2deg);
}
html[data-theme='cinema'] .sh-index::before {
content: 'SCENE ';
}
html[data-theme='cinema'] .sh-title {
font-family: var(--font-serif);
font-weight: 700;
letter-spacing: 0.2em;
}
html[data-theme='cinema'] .sh-kicker {
font-family: var(--font-cinzel);
}
/* —— 胶片:帧号标记 —— */
html[data-theme='kodak'] .sh-index {
display: block;
font-family: var(--font-number);
font-style: normal;
font-size: 12px;
letter-spacing: 0.16em;
color: #ff9a3c;
text-shadow: 0 0 6px rgba(255, 130, 30, 0.55);
}
html[data-theme='kodak'] .sh-index::before {
content: '▸ ';
}
html[data-theme='kodak'] .sh-index::after {
content: 'A';
}
html[data-theme='kodak'] .sh-title {
font-weight: 700;
letter-spacing: 0.14em;
}
/* —— 文艺:罗马分幕 —— */
html[data-theme='arthouse'] .sh {
gap: 10px;
margin-bottom: 30px;
}
html[data-theme='arthouse'] .sh-kicker {
font-family: var(--font-display);
letter-spacing: 0.56em;
}
html[data-theme='arthouse'] .sh-title {
font-family: var(--font-display);
font-weight: 400;
letter-spacing: 0.3em;
text-indent: 0.3em;
}
html[data-theme='arthouse'] .sh-rule-bottom {
display: block;
width: 1px;
height: 22px;
background: rgba(var(--c-line-rgb), 0.6);
}
/* —— 旅行:邮戳圆章 —— */
html[data-theme='passport'] .sh-index {
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
font-family: var(--font-number);
font-style: normal;
font-size: 13px;
color: var(--c-primary);
border: 2px solid rgba(var(--c-primary-rgb), 0.55);
border-radius: 50%;
transform: rotate(-10deg);
}
html[data-theme='passport'] .sh-kicker {
font-family: var(--font-number);
letter-spacing: 0.34em;
}
html[data-theme='passport'] .sh-title {
letter-spacing: 0.22em;
font-weight: 600;
}
/* —— 手账:标签贴 + 胶带 —— */
html[data-theme='scrapbook'] .sh-title {
font-family: var(--font-longcang);
padding: 6px 20px;
background: var(--c-card);
border: 1px dashed rgba(var(--c-primary-rgb), 0.45);
border-radius: 6px;
transform: rotate(-1.4deg);
box-shadow: 0 6px 16px rgba(69, 58, 48, 0.1);
}
html[data-theme='scrapbook'] .sh-kicker {
font-family: var(--font-liujian);
text-transform: none;
letter-spacing: 0.18em;
}
/* —— Y2K:窗口标题条 —— */
html[data-theme='y2k'] .sh-title {
font-weight: 800;
letter-spacing: 0.1em;
background: linear-gradient(180deg, #7a4ae0 10%, #4a90e0 50%, #e04ad0 100%);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
html[data-theme='y2k'] .sh-kicker {
font-family: var(--font-pixel);
font-size: 10px;
letter-spacing: 0.2em;
color: var(--c-line);
text-transform: none;
}
html[data-theme='y2k'] .sh-rule-bottom {
display: block;
width: 60px;
height: 4px;
border-radius: 2px;
background: repeating-linear-gradient(90deg, #7a4ae0 0 8px, #4adce0 8px 16px);
}
2026-08-12 13:53:06 +08:00
/* —— 极简主义:小字 + 一条细线 + 大留白 —— */
html[data-theme='zen'] .sh {
gap: 12px;
margin-bottom: 34px;
}
html[data-theme='zen'] .sh-kicker {
font-size: 9px;
letter-spacing: 0.6em;
}
html[data-theme='zen'] .sh-title {
font-size: 20px;
font-weight: 300;
letter-spacing: 0.5em;
text-indent: 0.5em;
}
html[data-theme='zen'] .sh-rule-bottom {
display: block;
width: 1px;
height: 26px;
background: rgba(var(--c-line-rgb), 0.6);
}
</style>