Merge commit '49190feab6268d64bbb16e332f53d2a66f387d14' as 'Website'
This commit is contained in:
248
Website/docs/.vitepress/config.ts
Normal file
248
Website/docs/.vitepress/config.ts
Normal file
@@ -0,0 +1,248 @@
|
||||
import { defineConfig } from 'vitepress'
|
||||
import { groupIconMdPlugin, groupIconVitePlugin } from 'vitepress-plugin-group-icons'
|
||||
import {
|
||||
GitChangelog,
|
||||
GitChangelogMarkdownSection,
|
||||
} from '@nolebase/vitepress-plugin-git-changelog/vite'
|
||||
|
||||
import footnote from 'markdown-it-footnote'
|
||||
import mark from 'markdown-it-mark'
|
||||
import sub from 'markdown-it-sub'
|
||||
import taskLists from 'markdown-it-task-lists'
|
||||
|
||||
export default defineConfig({
|
||||
title: 'SukiSU-Ultra',
|
||||
description: 'Next-Generation Android root solution.',
|
||||
|
||||
lastUpdated: true,
|
||||
cleanUrls: true,
|
||||
metaChunk: true,
|
||||
|
||||
// Global performance optimizations
|
||||
cacheDir: './.vitepress/cache',
|
||||
ignoreDeadLinks: false,
|
||||
|
||||
// Enhanced markdown with performance focus
|
||||
markdown: {
|
||||
math: true,
|
||||
config(md) {
|
||||
md.use(groupIconMdPlugin)
|
||||
md.use(footnote)
|
||||
md.use(mark)
|
||||
md.use(sub)
|
||||
md.use(taskLists)
|
||||
},
|
||||
linkify: true,
|
||||
typographer: true,
|
||||
lineNumbers: true,
|
||||
image: {
|
||||
lazyLoading: true,
|
||||
},
|
||||
toc: {
|
||||
level: [1, 2, 3],
|
||||
},
|
||||
theme: {
|
||||
light: 'github-light',
|
||||
dark: 'github-dark',
|
||||
},
|
||||
},
|
||||
sitemap: {
|
||||
hostname: 'https://sukisu.org',
|
||||
transformItems(items) {
|
||||
return items
|
||||
.filter((item) => !item.url.includes('404'))
|
||||
.map((item) => ({
|
||||
...item,
|
||||
changefreq:
|
||||
item.url === '/' ? 'daily' : item.url.includes('/guide/') ? 'weekly' : 'monthly',
|
||||
priority: item.url === '/' ? 1.0 : item.url.includes('/guide/') ? 0.9 : 0.7,
|
||||
}))
|
||||
},
|
||||
},
|
||||
|
||||
// Critical performance transformations
|
||||
transformPageData(pageData) {
|
||||
const canonicalUrl = `https://sukisu.org${pageData.relativePath}`
|
||||
.replace(/index\.md$/, '')
|
||||
.replace(/\.md$/, '')
|
||||
|
||||
pageData.frontmatter.head ??= []
|
||||
pageData.frontmatter.head.push(
|
||||
['link', { rel: 'canonical', href: canonicalUrl }],
|
||||
['meta', { property: 'og:url', content: canonicalUrl }],
|
||||
['link', { rel: 'preload', href: '/logo.svg', as: 'image' }]
|
||||
)
|
||||
|
||||
return pageData
|
||||
},
|
||||
|
||||
head: [
|
||||
// Critical resource hints for global performance
|
||||
['link', { rel: 'dns-prefetch', href: '//github.com' }],
|
||||
['link', { rel: 'dns-prefetch', href: '//t.me' }],
|
||||
['link', { rel: 'dns-prefetch', href: '//sukisu.org' }],
|
||||
|
||||
// Essential favicon setup - synced from /favicon during build/dev
|
||||
['link', { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
|
||||
['link', { rel: 'icon', type: 'image/svg+xml', href: '/favicon.svg' }],
|
||||
['link', { rel: 'icon', type: 'image/png', sizes: '96x96', href: '/favicon-96x96.png' }],
|
||||
['link', { rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' }],
|
||||
['link', { rel: 'mask-icon', href: '/safari-pinned-tab.svg', color: '#64edff' }],
|
||||
// (Removed msapplication meta to avoid referencing non-existent files)
|
||||
|
||||
// Web App Manifest
|
||||
['link', { rel: 'manifest', href: '/site.webmanifest' }],
|
||||
|
||||
// Theme and app configuration
|
||||
['meta', { name: 'theme-color', content: '#64edff' }],
|
||||
['meta', { name: 'application-name', content: 'SukiSU-Ultra' }],
|
||||
['meta', { name: 'apple-mobile-web-app-title', content: 'SukiSU-Ultra' }],
|
||||
['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }],
|
||||
['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'default' }],
|
||||
|
||||
// Viewport and mobile optimization
|
||||
[
|
||||
'meta',
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1.0, viewport-fit=cover' },
|
||||
],
|
||||
['meta', { name: 'format-detection', content: 'telephone=no' }],
|
||||
['meta', { property: 'og:type', content: 'website' }],
|
||||
['meta', { property: 'og:site_name', content: 'SukiSU-Ultra' }],
|
||||
['meta', { property: 'og:url', content: 'https://sukisu.org/' }],
|
||||
['meta', { property: 'og:locale', content: 'en_US' }],
|
||||
['meta', { property: 'og:locale:alternate', content: 'zh_CN' }],
|
||||
|
||||
// Twitter optimization for global audience
|
||||
['meta', { property: 'twitter:card', content: 'summary_large_image' }],
|
||||
['meta', { property: 'twitter:site', content: '@sukisu_ultra' }],
|
||||
['meta', { property: 'twitter:creator', content: '@sukisu_ultra' }],
|
||||
// (Removed Twitter image as no PNG social image is provided)
|
||||
|
||||
// Additional SEO optimizations
|
||||
[
|
||||
'meta',
|
||||
{
|
||||
name: 'robots',
|
||||
content: 'index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1',
|
||||
},
|
||||
],
|
||||
['meta', { name: 'bingbot', content: 'index, follow' }],
|
||||
['meta', { name: 'referrer', content: 'strict-origin-when-cross-origin' }],
|
||||
|
||||
// Global SEO optimization
|
||||
[
|
||||
'meta',
|
||||
{
|
||||
name: 'keywords',
|
||||
content:
|
||||
'Android root, KernelSU, SukiSU-Ultra, Android kernel, root management, 安卓 root, カーネル, рут',
|
||||
},
|
||||
],
|
||||
['meta', { name: 'author', content: 'SukiSU-Ultra Team' }],
|
||||
|
||||
// Enhanced structured data for global search engines
|
||||
[
|
||||
'script',
|
||||
{ type: 'application/ld+json' },
|
||||
JSON.stringify({
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'SoftwareApplication',
|
||||
name: 'SukiSU-Ultra',
|
||||
description: 'Next-Generation Android Root Solution',
|
||||
applicationCategory: 'SystemApplication',
|
||||
operatingSystem: 'Android',
|
||||
url: 'https://sukisu.org',
|
||||
downloadUrl: 'https://github.com/sukisu-ultra/sukisu-ultra/releases',
|
||||
supportingData: {
|
||||
'@type': 'DataCatalog',
|
||||
name: 'Compatibility Database',
|
||||
},
|
||||
offers: {
|
||||
'@type': 'Offer',
|
||||
price: '0',
|
||||
priceCurrency: 'USD',
|
||||
},
|
||||
author: {
|
||||
'@type': 'Organization',
|
||||
name: 'SukiSU-Ultra Team',
|
||||
url: 'https://github.com/sukisu-ultra',
|
||||
},
|
||||
}),
|
||||
],
|
||||
|
||||
// PWA optimization for global mobile users (manifest declared above)
|
||||
['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }],
|
||||
['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'black-translucent' }],
|
||||
['meta', { name: 'apple-mobile-web-app-title', content: 'SukiSU-Ultra' }],
|
||||
|
||||
// Cloudflare Web Analytics
|
||||
[
|
||||
'script',
|
||||
{
|
||||
defer: '',
|
||||
src: 'https://static.cloudflareinsights.com/beacon.min.js',
|
||||
'data-cf-beacon': '{"token": "dcc5feef58bf4c56a170a99f4cec4798"}',
|
||||
},
|
||||
],
|
||||
],
|
||||
|
||||
themeConfig: {
|
||||
logo: { src: '/logo.svg', width: 24, height: 24 },
|
||||
|
||||
socialLinks: [
|
||||
{ icon: 'github', link: 'https://github.com/sukisu-ultra/sukisu-ultra' },
|
||||
{
|
||||
icon: {
|
||||
svg: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-brand-telegram"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 10l-4 4l6 6l4 -16l-18 7l4 2l2 6l3 -4" /></svg>',
|
||||
},
|
||||
link: 'https://t.me/sukiksu',
|
||||
},
|
||||
],
|
||||
search: {
|
||||
provider: 'local',
|
||||
},
|
||||
},
|
||||
|
||||
rewrites: {
|
||||
'en/:rest*': ':rest*',
|
||||
},
|
||||
|
||||
locales: {
|
||||
root: {
|
||||
label: 'English',
|
||||
},
|
||||
zh: {
|
||||
label: '简体中文',
|
||||
link: '/zh/',
|
||||
},
|
||||
},
|
||||
|
||||
vite: {
|
||||
plugins: [
|
||||
groupIconVitePlugin({
|
||||
customIcon: {
|
||||
bash: '<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 256 256"><g fill="none"><rect width="256" height="256" fill="#242938" rx="60"/><path fill="#242938" fill-rule="evenodd" d="m203.819 68.835l-63.14-37.48a23.79 23.79 0 0 0-24.361 0l-63.14 37.48C45.642 73.31 41 81.575 41 90.522v74.961c0 8.945 4.643 17.215 12.18 21.689l63.14 37.473a23.8 23.8 0 0 0 12.179 3.354a23.8 23.8 0 0 0 12.178-3.354l63.14-37.473c7.536-4.474 12.182-12.744 12.182-21.689v-74.96c0-8.948-4.646-17.214-12.18-21.688" clip-rule="evenodd"/><path fill="#fff" fill-rule="evenodd" d="m118.527 220.808l-63.14-37.474c-6.176-3.666-10.013-10.506-10.013-17.852V90.523c0-7.346 3.837-14.186 10.01-17.85l63.143-37.48a19.55 19.55 0 0 1 9.972-2.747c3.495 0 6.943.95 9.973 2.747l63.14 37.48c5.204 3.089 8.714 8.438 9.701 14.437c-2.094-4.469-6.817-5.684-12.32-2.47l-59.734 36.897c-7.448 4.354-12.94 9.24-12.945 18.221v73.604c-.004 5.378 2.168 8.861 5.504 9.871c-1.096.19-2.201.322-3.319.322a19.55 19.55 0 0 1-9.972-2.747m85.292-151.974l-63.14-37.478A23.8 23.8 0 0 0 128.499 28a23.8 23.8 0 0 0-12.181 3.356l-63.14 37.478C45.642 73.308 41 81.576 41 90.524v74.958c0 8.945 4.643 17.215 12.18 21.689l63.14 37.475A23.84 23.84 0 0 0 128.499 228a23.83 23.83 0 0 0 12.178-3.354l63.142-37.475c7.536-4.474 12.18-12.744 12.18-21.689V90.523c0-8.947-4.644-17.215-12.18-21.689" clip-rule="evenodd"/><path fill="#47b353" fill-rule="evenodd" d="m187.267 172.729l-15.722 9.41c-.417.243-.723.516-.726 1.017v4.114c0 .503.338.712.754.467l15.966-9.703c.416-.243.48-.708.483-1.209v-3.629c0-.5-.338-.71-.755-.467" clip-rule="evenodd"/><path fill="#242938" fill-rule="evenodd" d="M153.788 138.098c.509-.258.928.059.935.725l.053 5.439c2.277-.906 4.255-1.148 6.047-.734c.389.104.561.633.402 1.261l-1.197 4.82c-.093.364-.298.732-.545.961a1.3 1.3 0 0 1-.315.234a.7.7 0 0 1-.472.077c-.818-.185-2.763-.61-5.823.94c-3.21 1.625-4.333 4.414-4.311 6.484c.027 2.472 1.295 3.221 5.673 3.296c5.834.097 8.355 2.646 8.416 8.522c.06 5.77-3.02 11.966-7.732 15.763l.104 5.384c.006.648-.415 1.391-.924 1.649l-3.189 1.837c-.511.258-.93-.06-.937-.708l-.055-5.296c-2.731 1.135-5.499 1.409-7.267.699c-.333-.13-.476-.622-.344-1.182l1.156-4.868c.092-.384.295-.768.571-1.012q.147-.142.299-.219c.183-.092.362-.112.514-.055c1.905.642 4.342.342 6.685-.844c2.977-1.506 4.968-4.542 4.937-7.558c-.029-2.737-1.51-3.874-5.113-3.901c-4.586.013-8.861-.891-8.932-7.642c-.057-5.558 2.833-11.342 7.408-14.999l-.057-5.435c-.007-.668.401-1.403.926-1.667z" clip-rule="evenodd"/></g></svg>',
|
||||
},
|
||||
}),
|
||||
GitChangelog({ repoURL: () => 'https://github.com/SukiSU-Ultra/Website' }),
|
||||
GitChangelogMarkdownSection({
|
||||
exclude: (id) => id.endsWith('index.md'),
|
||||
sections: { disableContributors: true },
|
||||
}),
|
||||
],
|
||||
build: {
|
||||
minify: 'terser',
|
||||
chunkSizeWarningLimit: 800,
|
||||
assetsInlineLimit: 8192,
|
||||
target: 'esnext',
|
||||
cssCodeSplit: true,
|
||||
sourcemap: false,
|
||||
},
|
||||
|
||||
server: {
|
||||
fs: {
|
||||
allow: ['..'],
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
195
Website/docs/.vitepress/theme/components/ArticleShare.vue
Normal file
195
Website/docs/.vitepress/theme/components/ArticleShare.vue
Normal file
@@ -0,0 +1,195 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { useData } from 'vitepress'
|
||||
|
||||
const props = defineProps({
|
||||
shareText: {
|
||||
type: String,
|
||||
default: undefined,
|
||||
},
|
||||
copiedText: {
|
||||
type: String,
|
||||
default: undefined,
|
||||
},
|
||||
includeQuery: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
includeHash: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
copiedTimeout: {
|
||||
type: Number,
|
||||
default: 2000,
|
||||
},
|
||||
})
|
||||
|
||||
defineOptions({ name: 'ArticleShare' })
|
||||
|
||||
const copied = ref(false)
|
||||
const isClient = typeof window !== 'undefined' && typeof document !== 'undefined'
|
||||
|
||||
const { theme, lang } = useData()
|
||||
|
||||
const defaultShareText = computed(() =>
|
||||
lang.value?.toLowerCase().startsWith('zh') ? '分享链接' : 'Share link'
|
||||
)
|
||||
const defaultCopiedText = computed(() =>
|
||||
lang.value?.toLowerCase().startsWith('zh') ? '已复制!' : 'Copied!'
|
||||
)
|
||||
const defaultCopyFailedText = computed(() =>
|
||||
lang.value?.toLowerCase().startsWith('zh') ? '复制链接失败:' : 'Failed to copy link:'
|
||||
)
|
||||
|
||||
const i18nShareText = computed(
|
||||
() => props.shareText ?? (theme.value as any)?.articleShare?.shareText ?? defaultShareText.value
|
||||
)
|
||||
const i18nCopiedText = computed(
|
||||
() =>
|
||||
props.copiedText ?? (theme.value as any)?.articleShare?.copiedText ?? defaultCopiedText.value
|
||||
)
|
||||
const i18nCopyFailedText = computed(
|
||||
() => (theme.value as any)?.articleShare?.copyFailed ?? defaultCopyFailedText.value
|
||||
)
|
||||
|
||||
const shareLink = computed(() => {
|
||||
if (!isClient) return ''
|
||||
|
||||
const { origin, pathname, search, hash } = window.location
|
||||
const finalSearch = props.includeQuery ? search : ''
|
||||
const finalHash = props.includeHash ? hash : ''
|
||||
return `${origin}${pathname}${finalSearch}${finalHash}`
|
||||
})
|
||||
|
||||
async function copyToClipboard() {
|
||||
if (copied.value || !isClient) return
|
||||
|
||||
try {
|
||||
if (navigator.clipboard) {
|
||||
await navigator.clipboard.writeText(shareLink.value)
|
||||
} else {
|
||||
const input = document.createElement('input')
|
||||
input.setAttribute('readonly', 'readonly')
|
||||
input.setAttribute('value', shareLink.value)
|
||||
document.body.appendChild(input)
|
||||
input.select()
|
||||
document.execCommand('copy')
|
||||
document.body.removeChild(input)
|
||||
}
|
||||
|
||||
copied.value = true
|
||||
setTimeout(() => {
|
||||
copied.value = false
|
||||
}, props.copiedTimeout)
|
||||
} catch (error) {
|
||||
console.error(i18nCopyFailedText.value, error)
|
||||
}
|
||||
}
|
||||
|
||||
const shareIconSvg = `
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"></path>
|
||||
<polyline points="16 6 12 2 8 6"></polyline>
|
||||
<line x1="12" y1="2" x2="12" y2="15"></line>
|
||||
</svg>
|
||||
`
|
||||
|
||||
const copiedIconSvg = `
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M20 6 9 17l-5-5"></path>
|
||||
</svg>
|
||||
`
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="article-share">
|
||||
<button
|
||||
:class="['article-share__button', { copied: copied }]"
|
||||
:aria-label="copied ? i18nCopiedText : i18nShareText"
|
||||
aria-live="polite"
|
||||
@click="copyToClipboard"
|
||||
>
|
||||
<div v-if="!copied" class="content-wrapper">
|
||||
<span class="icon" v-html="shareIconSvg"></span>
|
||||
{{ i18nShareText }}
|
||||
</div>
|
||||
|
||||
<div v-else class="content-wrapper">
|
||||
<span class="icon" v-html="copiedIconSvg"></span>
|
||||
{{ i18nCopiedText }}
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.article-share {
|
||||
padding: 14px 0;
|
||||
}
|
||||
|
||||
.article-share__button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
transition: all 0.4s var(--ease-out-cubic, cubic-bezier(0.33, 1, 0.68, 1));
|
||||
cursor: pointer;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 14px;
|
||||
padding: 7px 14px;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
color: var(--vp-c-text-1, #333);
|
||||
background-color: var(--vp-c-bg-alt, #f6f6f7);
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.02);
|
||||
will-change: transform, box-shadow;
|
||||
}
|
||||
|
||||
.article-share__button::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
z-index: -1;
|
||||
transition: left 0.6s ease;
|
||||
background-color: var(--vp-c-brand-soft, #ddf4ff);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.article-share__button:hover {
|
||||
transform: translateY(-1px);
|
||||
border-color: var(--vp-c-brand-soft, #ddf4ff);
|
||||
background-color: var(--vp-c-brand-soft, #ddf4ff);
|
||||
}
|
||||
|
||||
.article-share__button:active {
|
||||
transform: scale(0.9);
|
||||
}
|
||||
|
||||
.article-share__button.copied {
|
||||
color: var(--vp-c-brand-1, #007acc);
|
||||
background-color: var(--vp-c-brand-soft, #ddf4ff);
|
||||
}
|
||||
|
||||
.article-share__button.copied::before {
|
||||
left: 0;
|
||||
background-color: var(--vp-c-brand-soft, #ddf4ff);
|
||||
}
|
||||
|
||||
.content-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin-right: 6px;
|
||||
}
|
||||
</style>
|
||||
12
Website/docs/.vitepress/theme/components/Confetti.vue
Normal file
12
Website/docs/.vitepress/theme/components/Confetti.vue
Normal file
@@ -0,0 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import confetti from 'canvas-confetti'
|
||||
|
||||
const media = window.matchMedia('(prefers-reduced-motion: reduce)')
|
||||
if (!media.matches) {
|
||||
confetti({
|
||||
particleCount: 100,
|
||||
spread: 170,
|
||||
origin: { y: 0.6 },
|
||||
})
|
||||
}
|
||||
</script>
|
||||
150
Website/docs/.vitepress/theme/components/backtotop.vue
Normal file
150
Website/docs/.vitepress/theme/components/backtotop.vue
Normal file
@@ -0,0 +1,150 @@
|
||||
<script setup>
|
||||
import { onBeforeUnmount, onMounted, ref, computed } from 'vue'
|
||||
|
||||
const showBackTop = ref(false) // 初始状态设为false
|
||||
const scrollProgress = ref(0)
|
||||
|
||||
// 圆形进度条计算
|
||||
const radius = 42
|
||||
const circumference = computed(() => 2 * Math.PI * radius)
|
||||
|
||||
function scrollToTop() {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth',
|
||||
})
|
||||
}
|
||||
|
||||
// 使用更高效的节流函数
|
||||
function throttle(fn, delay = 50) {
|
||||
let timer = null
|
||||
return function (...args) {
|
||||
if (!timer) {
|
||||
timer = setTimeout(() => {
|
||||
fn.apply(this, args)
|
||||
timer = null
|
||||
}, delay)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const updateScrollProgress = () => {
|
||||
const { scrollY, innerHeight } = window
|
||||
const { scrollHeight } = document.documentElement
|
||||
const totalScroll = scrollHeight - innerHeight
|
||||
scrollProgress.value = totalScroll > 0 ? Math.min(scrollY / totalScroll, 1) : 0
|
||||
}
|
||||
|
||||
const handleScroll = throttle(() => {
|
||||
// 当滚动超过100px时显示,否则隐藏
|
||||
const shouldShow = window.scrollY > 100
|
||||
showBackTop.value = shouldShow
|
||||
updateScrollProgress()
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('scroll', handleScroll)
|
||||
updateScrollProgress()
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('scroll', handleScroll)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Transition name="fade">
|
||||
<div class="back-top-container" v-show="showBackTop">
|
||||
<svg class="progress-ring" viewBox="0 0 100 100">
|
||||
<circle class="progress-ring-background" cx="50" cy="50" r="42" />
|
||||
<circle
|
||||
class="progress-ring-circle"
|
||||
cx="50"
|
||||
cy="50"
|
||||
r="42"
|
||||
:style="{ 'stroke-dashoffset': circumference - scrollProgress * circumference }"
|
||||
/>
|
||||
</svg>
|
||||
<div class="vitepress-backTop-main" title="返回顶部" @click="scrollToTop()">
|
||||
<svg class="icon" viewBox="0 0 1024 1024">
|
||||
<path
|
||||
d="M752.736 431.063C757.159 140.575 520.41 8.97 504.518 0.41V0l-0.45 0.205-0.41-0.205v0.41c-15.934 8.56-252.723 140.165-248.259 430.653-48.21 31.457-98.713 87.368-90.685 184.074 8.028 96.666 101.007 160.768 136.601 157.287 35.595-3.482 25.232-30.31 25.232-30.31l12.206-50.095s52.47 80.569 69.304 80.528c15.114-1.23 87-0.123 95.6 0h0.82c8.602-0.123 80.486-1.23 95.6 0 16.794 0 69.305-80.528 69.305-80.528l12.165 50.094s-10.322 26.83 25.272 30.31c35.595 3.482 128.574-60.62 136.602-157.286 8.028-96.665-42.475-152.617-90.685-184.074z m-248.669-4.26c-6.758-0.123-94.781-3.359-102.891-107.192 2.95-98.714 95.97-107.438 102.891-107.93 6.964 0.492 99.943 9.216 102.892 107.93-8.11 103.833-96.174 107.07-102.892 107.192z m-52.019 500.531c0 11.838-9.42 21.382-21.012 21.382a21.217 21.217 0 0 1-21.054-21.34V821.74c0-11.797 9.421-21.382 21.054-21.382 11.591 0 21.012 9.585 21.012 21.382v105.635z m77.333 57.222a21.504 21.504 0 0 1-21.34 21.626 21.504 21.504 0 0 1-21.34-21.626V827.474c0-11.96 9.543-21.668 21.299-21.668 11.796 0 21.38 9.708 21.38 21.668v157.082z m71.147-82.043c0 11.796-9.42 21.34-21.053 21.34a21.217 21.217 0 0 1-21.013-21.34v-75.367c0-11.755 9.421-21.299 21.013-21.299 11.632 0 21.053 9.544 21.053 21.3v75.366z"
|
||||
fill="#FFF"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.back-top-container {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.vitepress-backTop-main {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
cursor: pointer;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 50%;
|
||||
background-color: #3eaf7c;
|
||||
padding: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.vitepress-backTop-main:hover {
|
||||
background-color: #71cda3;
|
||||
}
|
||||
|
||||
.progress-ring {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transform: rotate(-90deg);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.progress-ring-background {
|
||||
fill: none;
|
||||
stroke: rgba(62, 175, 124, 0.15);
|
||||
stroke-width: 3;
|
||||
}
|
||||
|
||||
.progress-ring-circle {
|
||||
fill: none;
|
||||
stroke: #3eaf7c;
|
||||
stroke-width: 3;
|
||||
stroke-dasharray: 264; /* 2 * π * 42 */
|
||||
stroke-linecap: round;
|
||||
transition: stroke-dashoffset 0.15s ease-out;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
33
Website/docs/.vitepress/theme/index.ts
Normal file
33
Website/docs/.vitepress/theme/index.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
// .vitepress/theme/index.ts
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
import { NolebaseGitChangelogPlugin } from '@nolebase/vitepress-plugin-git-changelog/client'
|
||||
import 'virtual:group-icons.css'
|
||||
import { h, onMounted } from 'vue'
|
||||
import './style/style.css'
|
||||
import ArticleShare from './components/ArticleShare.vue'
|
||||
import backtotop from './components/backtotop.vue'
|
||||
import '@nolebase/vitepress-plugin-git-changelog/client/style.css'
|
||||
|
||||
export default {
|
||||
extends: DefaultTheme,
|
||||
Layout: () => {
|
||||
return h(DefaultTheme.Layout, null, {
|
||||
'aside-outline-before': () => h(ArticleShare),
|
||||
'doc-footer-before': () => h(backtotop),
|
||||
})
|
||||
},
|
||||
enhanceApp({ app }) {
|
||||
app.use(NolebaseGitChangelogPlugin)
|
||||
|
||||
// Register service worker in production for offline support and caching
|
||||
if (
|
||||
typeof window !== 'undefined' &&
|
||||
'serviceWorker' in navigator &&
|
||||
(import.meta as any).env?.PROD
|
||||
) {
|
||||
onMounted(() => {
|
||||
navigator.serviceWorker.register('/sw.js').catch(() => {})
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
192
Website/docs/.vitepress/theme/style/custom-block.css
Normal file
192
Website/docs/.vitepress/theme/style/custom-block.css
Normal file
@@ -0,0 +1,192 @@
|
||||
/* .vitepress/theme/style/custom-block.css */
|
||||
/* 深浅色卡 */
|
||||
:root {
|
||||
--custom-block-info-left: #cccccc;
|
||||
--custom-block-info-bg: #fafafa;
|
||||
|
||||
--custom-block-tip-left: #009400;
|
||||
--custom-block-tip-bg: #e6f6e6;
|
||||
|
||||
--custom-block-warning-left: #e6a700;
|
||||
--custom-block-warning-bg: #fff8e6;
|
||||
|
||||
--custom-block-danger-left: #e13238;
|
||||
--custom-block-danger-bg: #ffebec;
|
||||
|
||||
--custom-block-note-left: #4cb3d4;
|
||||
--custom-block-note-bg: #eef9fd;
|
||||
|
||||
--custom-block-important-left: #a371f7;
|
||||
--custom-block-important-bg: #f4eefe;
|
||||
|
||||
--custom-block-caution-left: #e0575b;
|
||||
--custom-block-caution-bg: #fde4e8;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--custom-block-info-left: #cccccc;
|
||||
--custom-block-info-bg: #474748;
|
||||
|
||||
--custom-block-tip-left: #009400;
|
||||
--custom-block-tip-bg: #003100;
|
||||
|
||||
--custom-block-warning-left: #e6a700;
|
||||
--custom-block-warning-bg: #4d3800;
|
||||
|
||||
--custom-block-danger-left: #e13238;
|
||||
--custom-block-danger-bg: #4b1113;
|
||||
|
||||
--custom-block-note-left: #4cb3d4;
|
||||
--custom-block-note-bg: #193c47;
|
||||
|
||||
--custom-block-important-left: #a371f7;
|
||||
--custom-block-important-bg: #230555;
|
||||
|
||||
--custom-block-caution-left: #e0575b;
|
||||
--custom-block-caution-bg: #391c22;
|
||||
}
|
||||
|
||||
/* 标题字体大小 */
|
||||
.custom-block-title {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* info容器:背景色、左侧 */
|
||||
.custom-block.info {
|
||||
border-left: 5px solid var(--custom-block-info-left);
|
||||
background-color: var(--custom-block-info-bg);
|
||||
}
|
||||
|
||||
/* info容器:svg图 */
|
||||
.custom-block.info [class*='custom-block-title']::before {
|
||||
content: '';
|
||||
background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-11v6h2v-6h-2zm0-4v2h2V7h-2z' fill='%23ccc'/%3E%3C/svg%3E");
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
margin-right: 4px;
|
||||
left: -5px;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
/* 提示容器:边框色、背景色、左侧 */
|
||||
.custom-block.tip {
|
||||
/* border-color: var(--custom-block-tip); */
|
||||
border-left: 5px solid var(--custom-block-tip-left);
|
||||
background-color: var(--custom-block-tip-bg);
|
||||
}
|
||||
|
||||
/* 提示容器:svg图 */
|
||||
.custom-block.tip [class*='custom-block-title']::before {
|
||||
content: '';
|
||||
background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23009400' d='M7.941 18c-.297-1.273-1.637-2.314-2.187-3a8 8 0 1 1 12.49.002c-.55.685-1.888 1.726-2.185 2.998H7.94zM16 20v1a2 2 0 0 1-2 2h-4a2 2 0 0 1-2-2v-1h8zm-3-9.995V6l-4.5 6.005H11v4l4.5-6H13z'/%3E%3C/svg%3E");
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
margin-right: 4px;
|
||||
left: -5px;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
/* 警告容器:背景色、左侧 */
|
||||
.custom-block.warning {
|
||||
border-left: 5px solid var(--custom-block-warning-left);
|
||||
background-color: var(--custom-block-warning-bg);
|
||||
}
|
||||
|
||||
/* 警告容器:svg图 */
|
||||
.custom-block.warning [class*='custom-block-title']::before {
|
||||
content: '';
|
||||
background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1024 1024'%3E%3Cpath d='M576.286 752.57v-95.425q0-7.031-4.771-11.802t-11.3-4.772h-96.43q-6.528 0-11.3 4.772t-4.77 11.802v95.424q0 7.031 4.77 11.803t11.3 4.77h96.43q6.528 0 11.3-4.77t4.77-11.803zm-1.005-187.836 9.04-230.524q0-6.027-5.022-9.543-6.529-5.524-12.053-5.524H456.754q-5.524 0-12.053 5.524-5.022 3.516-5.022 10.547l8.538 229.52q0 5.023 5.022 8.287t12.053 3.265h92.913q7.032 0 11.803-3.265t5.273-8.287zM568.25 95.65l385.714 707.142q17.578 31.641-1.004 63.282-8.538 14.564-23.354 23.102t-31.892 8.538H126.286q-17.076 0-31.892-8.538T71.04 866.074q-18.582-31.641-1.004-63.282L455.75 95.65q8.538-15.57 23.605-24.61T512 62t32.645 9.04 23.605 24.61z' fill='%23e6a700'/%3E%3C/svg%3E");
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
margin-right: 4px;
|
||||
left: -5px;
|
||||
}
|
||||
|
||||
/* 危险容器:背景色、左侧 */
|
||||
.custom-block.danger {
|
||||
border-left: 5px solid var(--custom-block-danger-left);
|
||||
background-color: var(--custom-block-danger-bg);
|
||||
}
|
||||
|
||||
/* 危险容器:svg图 */
|
||||
.custom-block.danger [class*='custom-block-title']::before {
|
||||
content: '';
|
||||
background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2c5.523 0 10 4.477 10 10v3.764a2 2 0 0 1-1.106 1.789L18 19v1a3 3 0 0 1-2.824 2.995L14.95 23a2.5 2.5 0 0 0 .044-.33L15 22.5V22a2 2 0 0 0-1.85-1.995L13 20h-2a2 2 0 0 0-1.995 1.85L9 22v.5c0 .171.017.339.05.5H9a3 3 0 0 1-3-3v-1l-2.894-1.447A2 2 0 0 1 2 15.763V12C2 6.477 6.477 2 12 2zm-4 9a2 2 0 1 0 0 4 2 2 0 0 0 0-4zm8 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4z' fill='%23e13238'/%3E%3C/svg%3E");
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
margin-right: 4px;
|
||||
left: -5px;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
/* 提醒容器:背景色、左侧 */
|
||||
.custom-block.note {
|
||||
border-left: 5px solid var(--custom-block-note-left);
|
||||
background-color: var(--custom-block-note-bg);
|
||||
}
|
||||
|
||||
/* 提醒容器:svg图 */
|
||||
.custom-block.note [class*='custom-block-title']::before {
|
||||
content: '';
|
||||
background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-11v6h2v-6h-2zm0-4v2h2V7h-2z' fill='%234cb3d4'/%3E%3C/svg%3E");
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
margin-right: 4px;
|
||||
left: -5px;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
/* 重要容器:背景色、左侧 */
|
||||
.custom-block.important {
|
||||
border-left: 5px solid var(--custom-block-important-left);
|
||||
background-color: var(--custom-block-important-bg);
|
||||
}
|
||||
|
||||
/* 重要容器:svg图 */
|
||||
.custom-block.important [class*='custom-block-title']::before {
|
||||
content: '';
|
||||
background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1024 1024'%3E%3Cpath d='M512 981.333a84.992 84.992 0 0 1-84.907-84.906h169.814A84.992 84.992 0 0 1 512 981.333zm384-128H128v-42.666l85.333-85.334v-256A298.325 298.325 0 0 1 448 177.92V128a64 64 0 0 1 128 0v49.92a298.325 298.325 0 0 1 234.667 291.413v256L896 810.667v42.666zm-426.667-256v85.334h85.334v-85.334h-85.334zm0-256V512h85.334V341.333h-85.334z' fill='%23a371f7'/%3E%3C/svg%3E");
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
margin-right: 4px;
|
||||
left: -5px;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
/* 注意容器:背景色、左侧 */
|
||||
.custom-block.caution {
|
||||
border-left: 5px solid var(--custom-block-caution-left);
|
||||
background-color: var(--custom-block-caution-bg);
|
||||
}
|
||||
|
||||
/* 注意容器:svg图 */
|
||||
.custom-block.caution [class*='custom-block-title']::before {
|
||||
content: '';
|
||||
background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2c5.523 0 10 4.477 10 10v3.764a2 2 0 0 1-1.106 1.789L18 19v1a3 3 0 0 1-2.824 2.995L14.95 23a2.5 2.5 0 0 0 .044-.33L15 22.5V22a2 2 0 0 0-1.85-1.995L13 20h-2a2 2 0 0 0-1.995 1.85L9 22v.5c0 .171.017.339.05.5H9a3 3 0 0 1-3-3v-1l-2.894-1.447A2 2 0 0 1 2 15.763V12C2 6.477 6.477 2 12 2zm-4 9a2 2 0 1 0 0 4 2 2 0 0 0 0-4zm8 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4z' fill='%23e13238'/%3E%3C/svg%3E");
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
margin-right: 4px;
|
||||
left: -5px;
|
||||
top: -1px;
|
||||
}
|
||||
125
Website/docs/.vitepress/theme/style/doc-fade-in.css
Normal file
125
Website/docs/.vitepress/theme/style/doc-fade-in.css
Normal file
@@ -0,0 +1,125 @@
|
||||
#app a:focus-visible,
|
||||
#app button:focus-visible,
|
||||
#app input[type='checkbox']:focus-visible {
|
||||
--at-apply: outline-1 outline-primary ring-2 ring-primary;
|
||||
}
|
||||
|
||||
.VPSidebar::-webkit-scrollbar {
|
||||
background: transparent;
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
#app > div > div.VPLocalNav > div > div > div.outline {
|
||||
outline-style: none !important;
|
||||
}
|
||||
|
||||
.vp-doc .color-swatch {
|
||||
display: inline-block;
|
||||
width: 0.85em;
|
||||
height: 0.85em;
|
||||
min-width: 12px;
|
||||
min-height: 12px;
|
||||
font-size: inherit;
|
||||
border: 0;
|
||||
border-radius: 2px;
|
||||
margin: 0 3px 0 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.medium-zoom-overlay {
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.medium-zoom-image {
|
||||
z-index: 21;
|
||||
}
|
||||
|
||||
@keyframes slide-enter {
|
||||
0% {
|
||||
transform: translateY(10px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
transform: translateY(0);
|
||||
opacity: 100;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
html:not(.no-sliding) [slide-enter],
|
||||
html:not(.no-sliding) .slide-enter,
|
||||
html:not(.no-sliding) .main > div > *,
|
||||
html:not(.no-sliding) #VPContent > div > div.VPFeatures.VPHomeFeatures > *,
|
||||
html:not(.no-sliding) .TeamPage > *,
|
||||
html:not(.no-sliding) .VPHomeHero > * {
|
||||
--enter-stage: 0;
|
||||
--enter-step: 90ms;
|
||||
--enter-initial: 0ms;
|
||||
animation: slide-enter 1s both 1;
|
||||
animation-delay: calc(var(--enter-initial) + var(--enter-stage) * var(--enter-step));
|
||||
}
|
||||
|
||||
.main > div > *:nth-child(1) {
|
||||
--enter-stage: 1;
|
||||
}
|
||||
.main > div > *:nth-child(2) {
|
||||
--enter-stage: 2;
|
||||
}
|
||||
.main > div > *:nth-child(3) {
|
||||
--enter-stage: 3;
|
||||
}
|
||||
.main > div > *:nth-child(4) {
|
||||
--enter-stage: 4;
|
||||
}
|
||||
.main > div > *:nth-child(5) {
|
||||
--enter-stage: 5;
|
||||
}
|
||||
.main > div > *:nth-child(6) {
|
||||
--enter-stage: 6;
|
||||
}
|
||||
.main > div > *:nth-child(7) {
|
||||
--enter-stage: 7;
|
||||
}
|
||||
.main > div > *:nth-child(8) {
|
||||
--enter-stage: 8;
|
||||
}
|
||||
.main > div > *:nth-child(9) {
|
||||
--enter-stage: 9;
|
||||
}
|
||||
.main > div > *:nth-child(10) {
|
||||
--enter-stage: 10;
|
||||
}
|
||||
.main > div > *:nth-child(11) {
|
||||
--enter-stage: 11;
|
||||
}
|
||||
.main > div > *:nth-child(12) {
|
||||
--enter-stage: 12;
|
||||
}
|
||||
.main > div > *:nth-child(13) {
|
||||
--enter-stage: 13;
|
||||
}
|
||||
.main > div > *:nth-child(14) {
|
||||
--enter-stage: 14;
|
||||
}
|
||||
.main > div > *:nth-child(15) {
|
||||
--enter-stage: 15;
|
||||
}
|
||||
.main > div > *:nth-child(16) {
|
||||
--enter-stage: 16;
|
||||
}
|
||||
.main > div > *:nth-child(17) {
|
||||
--enter-stage: 17;
|
||||
}
|
||||
.main > div > *:nth-child(18) {
|
||||
--enter-stage: 18;
|
||||
}
|
||||
.main > div > *:nth-child(19) {
|
||||
--enter-stage: 19;
|
||||
}
|
||||
.main > div > *:nth-child(20) {
|
||||
--enter-stage: 20;
|
||||
}
|
||||
}
|
||||
158
Website/docs/.vitepress/theme/style/style.css
Normal file
158
Website/docs/.vitepress/theme/style/style.css
Normal file
@@ -0,0 +1,158 @@
|
||||
@import './custom-block.css';
|
||||
@import './doc-fade-in.css';
|
||||
|
||||
:root:where(:lang(fa)) {
|
||||
--vp-font-family-base:
|
||||
'Vazirmatn', 'Inter', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji',
|
||||
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||
}
|
||||
|
||||
:root {
|
||||
--vp-home-hero-name-color: transparent;
|
||||
--vp-home-hero-name-background: -webkit-linear-gradient(120deg, #bd34fe 30%, #41d1ff);
|
||||
--vp-home-hero-image-background-image: linear-gradient(-45deg, #bd34fe 50%, #47caff 50%);
|
||||
--vp-home-hero-image-filter: blur(44px);
|
||||
|
||||
/* Enhanced brand color for better contrast */
|
||||
--vp-c-brand-1: #1e40af;
|
||||
--vp-c-brand-2: #2563eb;
|
||||
--vp-c-brand-3: #3b82f6;
|
||||
--vp-c-brand-soft: rgba(30, 64, 175, 0.14);
|
||||
|
||||
/* Button contrast improvements */
|
||||
--vp-button-brand-bg: #1e40af;
|
||||
--vp-button-brand-text: #ffffff;
|
||||
--vp-button-brand-hover-bg: #1d4ed8;
|
||||
--vp-button-brand-hover-text: #ffffff;
|
||||
--vp-button-brand-active-bg: #1e3a8a;
|
||||
--vp-button-brand-active-text: #ffffff;
|
||||
}
|
||||
|
||||
/* Dark mode color overrides for better contrast */
|
||||
.dark:root {
|
||||
--vp-c-brand-1: #60a5fa;
|
||||
--vp-c-brand-2: #3b82f6;
|
||||
--vp-c-brand-3: #2563eb;
|
||||
--vp-c-brand-soft: rgba(96, 165, 250, 0.16);
|
||||
|
||||
--vp-button-brand-bg: #3b82f6;
|
||||
--vp-button-brand-text: #000000;
|
||||
--vp-button-brand-hover-bg: #60a5fa;
|
||||
--vp-button-brand-hover-text: #000000;
|
||||
--vp-button-brand-active-bg: #2563eb;
|
||||
--vp-button-brand-active-text: #000000;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
:root {
|
||||
--vp-home-hero-image-filter: blur(56px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
:root {
|
||||
--vp-home-hero-image-filter: blur(68px);
|
||||
}
|
||||
}
|
||||
|
||||
.VPHero .VPImage {
|
||||
filter: drop-shadow(-2px 4px 6px rgba(0, 0, 0, 0.2));
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
/* used in reference/default-theme-search */
|
||||
img[src='/search.png'] {
|
||||
width: 100%;
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
|
||||
/* Enhanced button contrast for accessibility */
|
||||
.VPButton.brand {
|
||||
background-color: var(--vp-button-brand-bg) !important;
|
||||
color: var(--vp-button-brand-text) !important;
|
||||
border: none;
|
||||
font-weight: 600;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.VPButton.brand:hover {
|
||||
background-color: var(--vp-button-brand-hover-bg) !important;
|
||||
color: var(--vp-button-brand-hover-text) !important;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(30, 64, 175, 0.4);
|
||||
}
|
||||
|
||||
.VPButton.brand:active {
|
||||
background-color: var(--vp-button-brand-active-bg) !important;
|
||||
color: var(--vp-button-brand-active-text) !important;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* Dark mode support for buttons */
|
||||
.dark .VPButton.brand {
|
||||
background-color: #3b82f6 !important;
|
||||
color: #000000 !important;
|
||||
}
|
||||
|
||||
.dark .VPButton.brand:hover {
|
||||
background-color: #60a5fa !important;
|
||||
color: #000000 !important;
|
||||
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
|
||||
}
|
||||
|
||||
.dark .VPButton.brand:active {
|
||||
background-color: #2563eb !important;
|
||||
color: #000000 !important;
|
||||
}
|
||||
|
||||
/* Ensure proper contrast for all text elements */
|
||||
.VPButton.brand .text {
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
/* Focus states for accessibility */
|
||||
.VPButton.brand:focus-visible {
|
||||
outline: 2px solid #ffffff;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.dark .VPButton.brand:focus-visible {
|
||||
outline: 2px solid #000000;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'HarmonyOS Sans SC';
|
||||
src: url('/HarmonyOS_Sans_SC.ttf') format('truetype');
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'HarmonyOS Sans SC', sans-serif;
|
||||
line-height: 1.8;
|
||||
letter-spacing: 0.05em;
|
||||
word-spacing: 0.05em;
|
||||
}
|
||||
|
||||
p,
|
||||
li,
|
||||
a,
|
||||
span,
|
||||
div,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
word-break: break-word;
|
||||
text-justify: inter-ideograph;
|
||||
-ms-text-autospace: ideograph-alpha;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
pre,
|
||||
code {
|
||||
letter-spacing: normal;
|
||||
word-spacing: normal;
|
||||
}
|
||||
Reference in New Issue
Block a user