feat(wrapped-ui): 新增 Win98 主题与桌面化外观

- 主题系统新增 win98(显示名 Windows 98,快捷键扩展到 F1-F4),并区分 retro(pixel/CRT) 与桌面 GUI 主题
- 年度总结页新增 Win98 桌面背景与底部任务栏(背景色/视口高度适配)
- 封面与卡片 slide 形态支持 Win98 窗口外观(title bar/icon/controls)
- 主题切换器补充 Win98 选项并新增 Win98 专属切换器
- 新增 Win98 图标资源(Start + 桌面图标)
This commit is contained in:
2977094657
2026-02-02 00:04:54 +08:00
parent 7ce6abecca
commit 980f15d0a4
19 changed files with 767 additions and 29 deletions

View File

@@ -1,5 +1,5 @@
<template>
<div v-if="variant === 'panel'" class="bg-white rounded-2xl border border-[#EDEDED] overflow-hidden">
<div v-if="variant === 'panel'" class="window bg-white rounded-2xl border border-[#EDEDED] overflow-hidden">
<div class="px-6 py-5 border-b border-[#F3F3F3]">
<div class="flex items-start justify-between gap-4">
<div>
@@ -20,24 +20,56 @@
<!-- Slide 模式单张卡片占据全页面背景由外层年度总结统一控制 -->
<section v-else class="relative h-full w-full overflow-hidden">
<div class="relative h-full max-w-5xl mx-auto px-6 py-10 sm:px-8 sm:py-12 flex flex-col">
<div class="flex items-start justify-between gap-4">
<div>
<h2 class="wrapped-title text-2xl sm:text-3xl text-[#000000e6]">{{ title }}</h2>
<div :class="slideContainerClass">
<!-- Win98把整页内容包进一个窗口 -->
<div v-if="isWin98" class="window w-full flex-1 flex flex-col overflow-hidden">
<div class="title-bar">
<div class="title-bar-text">
<img class="title-bar-icon" src="/assets/images/windows-0.png" alt="" aria-hidden="true" />
<span>{{ title }}</span>
</div>
<div class="title-bar-controls" aria-hidden="true">
<button type="button" aria-label="Minimize" tabindex="-1"></button>
<button type="button" aria-label="Maximize" tabindex="-1"></button>
<button type="button" aria-label="Close" tabindex="-1"></button>
</div>
</div>
<div class="window-body flex-1 flex flex-col min-h-0">
<slot name="narrative">
<p v-if="narrative" class="mt-3 wrapped-body text-sm sm:text-base text-[#7F7F7F] max-w-2xl whitespace-pre-wrap">
<p v-if="narrative" class="wrapped-body text-sm sm:text-base whitespace-pre-wrap">
{{ narrative }}
</p>
</slot>
<div class="mt-4 flex-1 min-h-0 overflow-auto">
<div class="w-full">
<slot />
</div>
</div>
</div>
<slot name="badge" />
</div>
<div class="mt-6 sm:mt-8 flex-1 flex items-center">
<div class="w-full">
<slot />
<!-- 其他主题保持原样 -->
<template v-else>
<div class="flex items-start justify-between gap-4">
<div>
<h2 class="wrapped-title text-2xl sm:text-3xl text-[#000000e6]">{{ title }}</h2>
<slot name="narrative">
<p v-if="narrative" class="mt-3 wrapped-body text-sm sm:text-base text-[#7F7F7F] max-w-2xl whitespace-pre-wrap">
{{ narrative }}
</p>
</slot>
</div>
<slot name="badge" />
</div>
</div>
<div class="mt-6 sm:mt-8 flex-1 flex items-center">
<div class="w-full">
<slot />
</div>
</div>
</template>
</div>
</section>
</template>
@@ -49,6 +81,15 @@ defineProps({
narrative: { type: String, default: '' },
variant: { type: String, default: 'panel' } // 'panel' | 'slide'
})
const { theme } = useWrappedTheme()
const isWin98 = computed(() => theme.value === 'win98')
const slideContainerClass = computed(() => (
isWin98.value
? 'relative h-full max-w-5xl mx-auto px-6 pt-2 pb-4 sm:px-8 sm:pt-3 sm:pb-6 flex flex-col'
: 'relative h-full max-w-5xl mx-auto px-6 py-10 sm:px-8 sm:py-12 flex flex-col'
))
</script>
<style>