官网开发中 0803

This commit is contained in:
eafonyang
2026-08-03 19:09:03 +08:00
parent eeccdb079c
commit f37b6451ef
36 changed files with 1906 additions and 78 deletions
+5 -5
View File
@@ -75,8 +75,8 @@ function closeMobile() {
:class="useTransparent ? 'bg-transparent' : 'bg-white/80 backdrop-blur-md border-b border-gray-100 dark:bg-dark-900/80 dark:border-dark-700'"
>
<div class="section-container h-64px flex items-center justify-between">
<!-- Logo -->
<NuxtLink :to="switchLocalePath(locale)" class="flex items-center gap-8px shrink-0" @click="closeMobile">
<!-- Logo点击返回首页 -->
<NuxtLink :to="localePath('/')" class="flex items-center gap-8px shrink-0" @click="closeMobile">
<img v-if="logoUrl" :src="logoUrl" :alt="site?.site_title || 'Luxsin'" class="h-32px w-auto" />
<span
v-else
@@ -99,7 +99,7 @@ function closeMobile() {
>
<NuxtLink
:to="resolveLink(item.link)"
class="text-sm font-medium transition-colors flex items-center gap-4px"
class="text-base font-medium transition-colors flex items-center gap-4px"
:class="lightText ? 'text-white/90 hover:text-white' : 'text-gray-700 hover:text-primary dark:text-gray-200'"
>
{{ siteStore.navLabel(item) }}
@@ -147,7 +147,7 @@ function closeMobile() {
v-else-if="isExternal(item.link)"
:href="item.link"
:target="item.open_new_tab ? '_blank' : undefined"
class="text-sm font-medium transition-colors"
class="text-base font-medium transition-colors"
:class="lightText ? 'text-white/90 hover:text-white' : 'text-gray-700 hover:text-primary dark:text-gray-200'"
>
{{ siteStore.navLabel(item) }}
@@ -158,7 +158,7 @@ function closeMobile() {
v-else
:to="resolveLink(item.link)"
:target="item.open_new_tab ? '_blank' : undefined"
class="text-sm font-medium transition-colors"
class="text-base font-medium transition-colors"
:class="lightText ? 'text-white/90 hover:text-white' : 'text-gray-700 hover:text-primary dark:text-gray-200'"
>
{{ siteStore.navLabel(item) }}
+36
View File
@@ -0,0 +1,36 @@
<script setup lang="ts">
/**
* 内页 Hero 公共区:overline + 标题 + 副标题 + 可选背景图
*
* 非首页导航栏为 glass 风格(深色文字),因此无背景图时使用深色文字,
* 有背景图时叠加半透明遮罩并使用白色文字。
*/
defineProps<{
title: string;
subtitle?: string;
overline?: string;
bgUrl?: string;
}>();
</script>
<template>
<section class="relative overflow-hidden">
<!-- 背景图 + 遮罩 -->
<div v-if="bgUrl" class="absolute inset-0 bg-cover bg-center" :style="{ backgroundImage: `url(${bgUrl})` }" />
<div v-if="bgUrl" class="absolute inset-0 bg-black/45" />
<!-- 内容 -->
<div
class="section-container relative flex flex-col items-center text-center gap-16px py-72px md:py-96px"
:class="bgUrl ? 'text-white' : 'text-gray-900 dark:text-white'"
>
<p v-if="overline" class="text-sm tracking-[0.35em] uppercase opacity-80 font-medium">
{{ overline }}
</p>
<h1 class="text-3xl md:text-5xl font-bold leading-tight">{{ title }}</h1>
<p v-if="subtitle" class="max-w-680px text-base md:text-lg opacity-90 leading-relaxed">
{{ subtitle }}
</p>
</div>
</section>
</template>
@@ -3,7 +3,7 @@ import type { SectionBlock } from '~/types/site';
const props = defineProps<{ section: SectionBlock }>();
const { overline, title, subtitle, config, isEn, isDark } = useSectionContent(props.section);
const { overline, title, subtitle, config, isEn, isDark, overlineStyle, titleStyle, bodyStyle } = useSectionContent(props.section);
const features = computed(() => config.value.features ?? []);
</script>
@@ -12,13 +12,13 @@ const features = computed(() => config.value.features ?? []);
<div class="section-container py-96px">
<!-- 标题区 -->
<div class="text-center max-w-640px mx-auto mb-56px">
<p v-if="overline" class="text-13px font-semibold tracking-widest uppercase" :class="isDark ? 'text-primary-300' : 'text-primary'">
<p v-if="overline" class="text-13px font-semibold tracking-widest uppercase" :class="isDark ? 'text-primary-300' : 'text-primary'" :style="overlineStyle">
{{ overline }}
</p>
<h2 class="mt-12px text-3xl md:text-4xl font-bold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'">
<h2 class="mt-12px text-3xl md:text-4xl font-bold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'" :style="titleStyle">
{{ title }}
</h2>
<p v-if="subtitle" class="mt-16px text-base" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'">
<p v-if="subtitle" class="mt-16px text-base" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'" :style="bodyStyle">
{{ subtitle }}
</p>
</div>
@@ -32,10 +32,10 @@ const features = computed(() => config.value.features ?? []);
:class="isDark ? 'bg-white/5 border border-white/10' : 'bg-white border border-gray-100 shadow-sm hover:shadow-md dark:bg-dark-800 dark:border-dark-700'"
>
<span v-if="feature.icon" class="text-3xl">{{ feature.icon }}</span>
<h3 class="mt-16px text-lg font-semibold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'">
<h3 class="mt-16px text-lg font-semibold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'" :style="titleStyle">
{{ isEn ? feature.title_en : feature.title_zh }}
</h3>
<p class="mt-8px text-sm leading-relaxed" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'">
<p class="mt-8px text-sm leading-relaxed" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'" :style="bodyStyle">
{{ isEn ? feature.desc_en : feature.desc_zh }}
</p>
</div>
@@ -3,21 +3,21 @@ import type { SectionBlock } from '~/types/site';
const props = defineProps<{ section: SectionBlock }>();
const { overline, title, subtitle, content } = useSectionContent(props.section);
const { overline, title, subtitle, content, overlineStyle, titleStyle, bodyStyle } = useSectionContent(props.section);
</script>
<template>
<div class="section-container py-120px flex-col-center text-center max-w-800px">
<p v-if="overline" class="text-13px font-semibold tracking-widest uppercase" :class="section.theme === 'dark' ? 'text-primary-300' : 'text-primary'">
<p v-if="overline" class="text-13px font-semibold tracking-widest uppercase" :class="section.theme === 'dark' ? 'text-primary-300' : 'text-primary'" :style="overlineStyle">
{{ overline }}
</p>
<h2 class="mt-16px text-3xl md:text-5xl font-bold leading-tight" :class="section.theme === 'dark' ? 'text-white' : 'text-gray-900 dark:text-white'">
<h2 class="mt-16px text-3xl md:text-5xl font-bold leading-tight" :class="section.theme === 'dark' ? 'text-white' : 'text-gray-900 dark:text-white'" :style="titleStyle">
{{ title }}
</h2>
<p v-if="subtitle" class="mt-20px text-lg md:text-xl" :class="section.theme === 'dark' ? 'text-gray-300' : 'text-gray-600 dark:text-gray-300'">
<p v-if="subtitle" class="mt-20px text-lg md:text-xl" :class="section.theme === 'dark' ? 'text-gray-300' : 'text-gray-600 dark:text-gray-300'" :style="bodyStyle">
{{ subtitle }}
</p>
<div v-if="content" class="mt-16px text-15px leading-relaxed" :class="section.theme === 'dark' ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'" v-html="content" />
<div v-if="content" class="mt-16px text-15px leading-relaxed" :class="section.theme === 'dark' ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'" :style="bodyStyle" v-html="content" />
<SectionCta :section="section" class="mt-32px justify-center" />
</div>
</template>
@@ -3,7 +3,7 @@ import type { SectionBlock } from '~/types/site';
const props = defineProps<{ section: SectionBlock }>();
const { overline, title, subtitle, config, isEn, isDark } = useSectionContent(props.section);
const { overline, title, subtitle, config, isEn, isDark, overlineStyle, titleStyle, bodyStyle } = useSectionContent(props.section);
const images = computed(() => config.value.images ?? []);
</script>
@@ -12,13 +12,13 @@ const images = computed(() => config.value.images ?? []);
<div class="section-container py-96px">
<!-- 标题区 -->
<div class="text-center max-w-640px mx-auto mb-56px">
<p v-if="overline" class="text-13px font-semibold tracking-widest uppercase" :class="isDark ? 'text-primary-300' : 'text-primary'">
<p v-if="overline" class="text-13px font-semibold tracking-widest uppercase" :class="isDark ? 'text-primary-300' : 'text-primary'" :style="overlineStyle">
{{ overline }}
</p>
<h2 class="mt-12px text-3xl md:text-4xl font-bold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'">
<h2 class="mt-12px text-3xl md:text-4xl font-bold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'" :style="titleStyle">
{{ title }}
</h2>
<p v-if="subtitle" class="mt-16px text-base" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'">
<p v-if="subtitle" class="mt-16px text-base" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'" :style="bodyStyle">
{{ subtitle }}
</p>
</div>
@@ -3,28 +3,57 @@ import type { SectionBlock } from '~/types/site';
const props = defineProps<{ section: SectionBlock }>();
const { overline, title, subtitle, content, mediaUrl, isDark } = useSectionContent(props.section);
const { overline, title, subtitle, content, mediaUrl, isDark, overlineStyle, titleStyle, bodyStyle } = useSectionContent(props.section);
// 九宫格文案位置(config.text_position,默认左中):top/middle/bottom + left/center/right
const textPosition = computed(() => (props.section.config as Record<string, string> | null)?.text_position ?? 'middle_left');
// 垂直对齐(flex-col 主轴):top->start / middle->center / bottom->end
const vAlign = computed(() => ({
top: 'justify-start',
middle: 'justify-center',
bottom: 'justify-end'
} as Record<string, string>)[textPosition.value.split('_')[0] ?? ''] ?? 'justify-center');
// 水平对齐(flex-col 交叉轴):left->start / center->center / right->end
const hAlign = computed(() => ({
left: 'items-start',
center: 'items-center',
right: 'items-end'
} as Record<string, string>)[textPosition.value.split('_')[1] ?? ''] ?? 'items-start');
// 水平内边距:左列贴左、右列贴右、中列居中留白
const hPad = computed(() => ({
left: 'md:pl-128px md:pr-96px',
center: 'md:px-64px',
right: 'md:pl-96px md:pr-128px'
} as Record<string, string>)[textPosition.value.split('_')[1] ?? ''] ?? 'md:px-64px');
</script>
<template>
<div class="section-container aspect-[2/3] md:aspect-auto md:min-h-[min(calc(92vh-64px),54vw)] grid md:grid-cols-2 gap-48px items-center">
<!-- 左侧文案 -->
<div class="flex flex-col gap-20px self-center md:min-h-[680px]">
<p v-if="overline" class="text-13px font-semibold tracking-widest uppercase" :class="isDark ? 'text-primary-300' : 'text-primary'">
{{ overline }}
</p>
<h2 class="text-3xl md:text-5xl font-bold leading-tight" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'">
{{ title }}
</h2>
<p v-if="subtitle" class="text-lg md:text-xl" :class="isDark ? 'text-gray-300' : 'text-gray-600 dark:text-gray-300'">
{{ subtitle }}
</p>
<div v-if="content" class="text-15px leading-relaxed" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'" v-html="content" />
<SectionCta :section="section" class="mt-8px" />
<div class="relative aspect-[2/3] md:aspect-auto md:min-h-[max(680px,min(calc(92vh-64px),54vw))] grid gap-48px px-16px md:px-0">
<!-- 文案移动端文档流桌面端全宽绝对定位 + 九宫格对齐 -->
<div
class="relative z-10 flex flex-col gap-20px py-64px md:py-64px md:absolute md:inset-0"
:class="[vAlign, hAlign, hPad]"
>
<div class="flex flex-col gap-20px max-w-560px">
<p v-if="overline" class="text-13px font-semibold tracking-widest uppercase" :class="isDark ? 'text-primary-300' : 'text-primary'" :style="overlineStyle">
{{ overline }}
</p>
<h2 class="text-3xl md:text-5xl font-bold leading-tight" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'" :style="titleStyle">
{{ title }}
</h2>
<p v-if="subtitle" class="text-lg md:text-xl" :class="isDark ? 'text-gray-300' : 'text-gray-600 dark:text-gray-300'" :style="bodyStyle">
{{ subtitle }}
</p>
<div v-if="content" class="text-15px leading-relaxed" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'" :style="bodyStyle" v-html="content" />
<SectionCta :section="section" class="mt-8px" />
</div>
</div>
<!-- 右侧图片 -->
<div v-if="mediaUrl" class="flex-center">
<!-- 图片移动端文档流桌面端占右侧一半 -->
<div v-if="mediaUrl" class="flex-center md:absolute md:top-0 md:right-0 md:bottom-0 md:w-1/2">
<img :src="mediaUrl" :alt="title" class="w-full max-w-560px rounded-16px object-cover shadow-lg" />
</div>
</div>
@@ -4,7 +4,7 @@ import type { SectionBlock } from '~/types/site';
const props = defineProps<{ section: SectionBlock }>();
// 引言评价:正文 content 作为引用语,subtitle 作为作者/出处
const { content, subtitle, isDark } = useSectionContent(props.section);
const { content, subtitle, isDark, titleStyle, bodyStyle } = useSectionContent(props.section);
</script>
<template>
@@ -13,9 +13,10 @@ const { content, subtitle, isDark } = useSectionContent(props.section);
<blockquote
class="mt-8px text-2xl md:text-3xl font-medium leading-relaxed"
:class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'"
:style="titleStyle"
v-html="content"
/>
<p v-if="subtitle" class="mt-24px text-sm tracking-wide" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'">
<p v-if="subtitle" class="mt-24px text-sm tracking-wide" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'" :style="bodyStyle">
{{ subtitle }}
</p>
</div>
@@ -3,7 +3,7 @@ import type { SectionBlock } from '~/types/site';
const props = defineProps<{ section: SectionBlock }>();
const { overline, title, subtitle, config, isEn, isDark } = useSectionContent(props.section);
const { overline, title, subtitle, config, isEn, isDark, overlineStyle, titleStyle, bodyStyle } = useSectionContent(props.section);
const steps = computed(() => config.value.steps ?? []);
</script>
@@ -12,13 +12,13 @@ const steps = computed(() => config.value.steps ?? []);
<div class="section-container py-96px">
<!-- 标题区 -->
<div class="text-center max-w-640px mx-auto mb-64px">
<p v-if="overline" class="text-13px font-semibold tracking-widest uppercase" :class="isDark ? 'text-primary-300' : 'text-primary'">
<p v-if="overline" class="text-13px font-semibold tracking-widest uppercase" :class="isDark ? 'text-primary-300' : 'text-primary'" :style="overlineStyle">
{{ overline }}
</p>
<h2 class="mt-12px text-3xl md:text-4xl font-bold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'">
<h2 class="mt-12px text-3xl md:text-4xl font-bold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'" :style="titleStyle">
{{ title }}
</h2>
<p v-if="subtitle" class="mt-16px text-base" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'">
<p v-if="subtitle" class="mt-16px text-base" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'" :style="bodyStyle">
{{ subtitle }}
</p>
</div>
@@ -35,10 +35,10 @@ const steps = computed(() => config.value.steps ?? []);
<span class="text-4xl font-bold opacity-20" :class="isDark ? 'text-white' : 'text-gray-900'">
{{ String(idx + 1).padStart(2, '0') }}
</span>
<h3 class="text-xl font-semibold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'">
<h3 class="text-xl font-semibold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'" :style="titleStyle">
{{ isEn ? step.title_en : step.title_zh }}
</h3>
<p class="text-15px leading-relaxed" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'">
<p class="text-15px leading-relaxed" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'" :style="bodyStyle">
{{ isEn ? step.desc_en : step.desc_zh }}
</p>
</div>
@@ -3,7 +3,7 @@ import type { SectionBlock, SpecGroup } from '~/types/site';
const props = defineProps<{ section: SectionBlock }>();
const { overline, title, subtitle, isEn, isDark } = useSectionContent(props.section);
const { overline, title, subtitle, isEn, isDark, overlineStyle, titleStyle, bodyStyle } = useSectionContent(props.section);
const specGroups = computed<SpecGroup[]>(() => props.section.spec_groups ?? []);
@@ -35,13 +35,13 @@ function needToggle(group: SpecGroup): boolean {
<div class="section-container py-96px">
<!-- 标题区 -->
<div class="text-center max-w-640px mx-auto mb-56px">
<p v-if="overline" class="text-13px font-semibold tracking-widest uppercase" :class="isDark ? 'text-primary-300' : 'text-primary'">
<p v-if="overline" class="text-13px font-semibold tracking-widest uppercase" :class="isDark ? 'text-primary-300' : 'text-primary'" :style="overlineStyle">
{{ overline }}
</p>
<h2 class="mt-12px text-3xl md:text-4xl font-bold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'">
<h2 class="mt-12px text-3xl md:text-4xl font-bold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'" :style="titleStyle">
{{ title }}
</h2>
<p v-if="subtitle" class="mt-16px text-base" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'">
<p v-if="subtitle" class="mt-16px text-base" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'" :style="bodyStyle">
{{ subtitle }}
</p>
</div>
@@ -56,7 +56,7 @@ function needToggle(group: SpecGroup): boolean {
>
<!-- 分组标题 -->
<div class="px-32px py-20px border-b" :class="isDark ? 'border-white/10' : 'border-gray-100 dark:border-dark-700'">
<h3 class="text-lg font-semibold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'">
<h3 class="text-lg font-semibold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'" :style="titleStyle">
{{ isEn ? group.title_en : group.title_zh }}
</h3>
</div>
@@ -3,7 +3,7 @@ import type { SectionBlock } from '~/types/site';
const props = defineProps<{ section: SectionBlock }>();
const { overline, title, subtitle, content, mediaUrl, isDark } = useSectionContent(props.section);
const { overline, title, subtitle, content, mediaUrl, isDark, overlineStyle, titleStyle, bodyStyle } = useSectionContent(props.section);
</script>
<template>
@@ -15,16 +15,16 @@ const { overline, title, subtitle, content, mediaUrl, isDark } = useSectionConte
<!-- 文案 -->
<div class="flex flex-col gap-20px order-1 md:order-2">
<p v-if="overline" class="text-13px font-semibold tracking-widest uppercase" :class="isDark ? 'text-primary-300' : 'text-primary'">
<p v-if="overline" class="text-13px font-semibold tracking-widest uppercase" :class="isDark ? 'text-primary-300' : 'text-primary'" :style="overlineStyle">
{{ overline }}
</p>
<h2 class="text-3xl md:text-4xl font-bold leading-tight" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'">
<h2 class="text-3xl md:text-4xl font-bold leading-tight" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'" :style="titleStyle">
{{ title }}
</h2>
<p v-if="subtitle" class="text-lg" :class="isDark ? 'text-gray-300' : 'text-gray-600 dark:text-gray-300'">
<p v-if="subtitle" class="text-lg" :class="isDark ? 'text-gray-300' : 'text-gray-600 dark:text-gray-300'" :style="bodyStyle">
{{ subtitle }}
</p>
<div v-if="content" class="text-15px leading-relaxed" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'" v-html="content" />
<div v-if="content" class="text-15px leading-relaxed" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'" :style="bodyStyle" v-html="content" />
<SectionCta :section="section" class="mt-8px" />
</div>
</div>
@@ -3,7 +3,7 @@ import type { SectionBlock } from '~/types/site';
const props = defineProps<{ section: SectionBlock }>();
const { overline, title, subtitle, config, isEn, isDark } = useSectionContent(props.section);
const { overline, title, subtitle, config, isEn, isDark, overlineStyle, titleStyle, bodyStyle } = useSectionContent(props.section);
const stats = computed(() => config.value.stats ?? []);
</script>
@@ -12,13 +12,13 @@ const stats = computed(() => config.value.stats ?? []);
<div class="section-container py-96px">
<!-- 标题区 -->
<div class="text-center max-w-640px mx-auto mb-64px">
<p v-if="overline" class="text-13px font-semibold tracking-widest uppercase" :class="isDark ? 'text-primary-300' : 'text-primary'">
<p v-if="overline" class="text-13px font-semibold tracking-widest uppercase" :class="isDark ? 'text-primary-300' : 'text-primary'" :style="overlineStyle">
{{ overline }}
</p>
<h2 class="mt-12px text-3xl md:text-4xl font-bold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'">
<h2 class="mt-12px text-3xl md:text-4xl font-bold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'" :style="titleStyle">
{{ title }}
</h2>
<p v-if="subtitle" class="mt-16px text-base" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'">
<p v-if="subtitle" class="mt-16px text-base" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'" :style="bodyStyle">
{{ subtitle }}
</p>
</div>
@@ -26,10 +26,10 @@ const stats = computed(() => config.value.stats ?? []);
<!-- 数据统计 -->
<div class="grid grid-cols-2 lg:grid-cols-4 gap-32px">
<div v-for="(stat, idx) in stats" :key="idx" class="flex-col-center text-center">
<p class="text-4xl md:text-5xl font-bold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'">
<p class="text-4xl md:text-5xl font-bold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'" :style="titleStyle">
{{ stat.value }}<span class="text-2xl md:text-3xl ml-4px opacity-70">{{ stat.unit }}</span>
</p>
<p class="mt-12px text-sm" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'">
<p class="mt-12px text-sm" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'" :style="bodyStyle">
{{ isEn ? stat.label_en : stat.label_zh }}
</p>
</div>
@@ -3,7 +3,7 @@ import type { SectionBlock } from '~/types/site';
const props = defineProps<{ section: SectionBlock }>();
const { overline, title, subtitle, isDark } = useSectionContent(props.section);
const { overline, title, subtitle, isDark, overlineStyle, titleStyle, bodyStyle } = useSectionContent(props.section);
// 判断是否为可嵌入的 iframe 视频(YouTube / Bilibili
const isEmbed = computed(() => /youtube\.com|youtu\.be|bilibili\.com|player\.bilibili\.com/.test(props.section.video_url));
@@ -13,13 +13,13 @@ const isEmbed = computed(() => /youtube\.com|youtu\.be|bilibili\.com|player\.bil
<div class="section-container py-96px">
<!-- 标题区 -->
<div class="text-center max-w-640px mx-auto mb-48px">
<p v-if="overline" class="text-13px font-semibold tracking-widest uppercase" :class="isDark ? 'text-primary-300' : 'text-primary'">
<p v-if="overline" class="text-13px font-semibold tracking-widest uppercase" :class="isDark ? 'text-primary-300' : 'text-primary'" :style="overlineStyle">
{{ overline }}
</p>
<h2 class="mt-12px text-3xl md:text-4xl font-bold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'">
<h2 class="mt-12px text-3xl md:text-4xl font-bold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'" :style="titleStyle">
{{ title }}
</h2>
<p v-if="subtitle" class="mt-16px text-base" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'">
<p v-if="subtitle" class="mt-16px text-base" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'" :style="bodyStyle">
{{ subtitle }}
</p>
</div>