初始化

This commit is contained in:
李琦
2026-07-24 16:52:39 +08:00
parent 1473a11300
commit 5724440f88
9 changed files with 692 additions and 17 deletions

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue</title>
<title>萧康云医</title>
</head>
<body>
<div id="app"></div>

View File

@@ -55,13 +55,15 @@ const themeOptions = [
const menuGroups = [
{ key: 'home', label: '首页', to: '/', links: siteConfig.navigation.secondary.home },
{ key: 'product', label: '产品', to: '/product', links: siteConfig.navigation.secondary.product },
{ key: 'video', label: '视频', to: '/video/user', activePath: '/video', links: siteConfig.navigation.secondary.video }
{ key: 'video', label: '视频', to: '/video/user', activePath: '/video', links: siteConfig.navigation.secondary.video },
{ key: 'about', label: '关于我们', to: '/about', links: siteConfig.navigation.secondary.about }
]
const activeTheme = computed(() => themeOptions.find((item) => item.value === themeMode.value) || themeOptions[0])
const isHome = computed(() => route.path === '/')
const isProduct = computed(() => route.path.startsWith('/product'))
const isVideo = computed(() => route.path.startsWith('/video'))
const isAbout = computed(() => route.path.startsWith('/about'))
const isNavSolid = computed(() => isPastFirstScreen.value)
const navTone = computed(() => {
if (isHome.value && !isNavSolid.value) return 'dark'
@@ -92,6 +94,14 @@ const routeSearchItems = computed(() => [
to: '/video/user',
category: '页面',
keywords: ['视频库', '演示视频', '用户端', '医生端', '店长端']
},
{
id: 'route-about',
title: '关于我们',
description: siteConfig.about.visionTitle,
to: '/about',
category: '页面',
keywords: ['关于我们', '愿景', '位置', siteConfig.about.locationName, siteConfig.about.visionBody]
}
])
@@ -99,7 +109,8 @@ const navigationSearchItems = computed(() => {
const groups = [
{ category: '首页标题', links: siteConfig.navigation.secondary.home },
{ category: '产品标题', links: siteConfig.navigation.secondary.product },
{ category: '视频分区', links: siteConfig.navigation.secondary.video }
{ category: '视频分区', links: siteConfig.navigation.secondary.video },
{ category: '关于我们', links: siteConfig.navigation.secondary.about }
]
return groups.flatMap((group) =>
@@ -197,7 +208,34 @@ const contentSearchItems = computed(() => {
}))
])
return [...homeItems, ...productItems, ...videoItems]
const aboutItems = [
{
id: 'about-vision',
title: '我们的愿景',
description: siteConfig.about.visionTitle,
to: '/about#vision',
category: '关于我们',
keywords: ['愿景', siteConfig.about.visionTitle, siteConfig.about.visionBody]
},
...siteConfig.about.principles.map((item) => ({
id: `about-principle-${item.title}`,
title: item.title,
description: item.body,
to: '/about#principles',
category: '发展理念',
keywords: [item.title, item.body]
})),
{
id: 'about-location',
title: siteConfig.about.locationName,
description: `在高德地图中查看${siteConfig.about.locationName}`,
to: '/about#location',
category: '公司位置',
keywords: ['高德地图', '地图', siteConfig.about.locationName, siteConfig.about.mapQuery]
}
]
return [...homeItems, ...productItems, ...videoItems, ...aboutItems]
})
const searchItems = computed(() => {
@@ -425,7 +463,8 @@ onBeforeUnmount(() => {
'site-header-home': isHome && !isNavSolid,
'site-header-solid': isNavSolid,
'site-header-product': isProduct,
'site-header-video': isVideo
'site-header-video': isVideo,
'site-header-about': isAbout
}
]"
>
@@ -437,7 +476,8 @@ onBeforeUnmount(() => {
'site-nav-solid': isNavSolid,
'site-nav-overlay': !isNavSolid,
'site-nav-product': isProduct,
'site-nav-video': isVideo
'site-nav-video': isVideo,
'site-nav-about': isAbout
}
]"
style="animation-delay: 0ms"

View File

@@ -0,0 +1,129 @@
<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref } from 'vue';
type TagName = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span';
type AnimateBy = 'chars' | 'words';
type Direction = 'top' | 'bottom';
interface Props {
text: string;
className?: string;
tag?: TagName;
animateBy?: AnimateBy;
direction?: Direction;
delay?: number;
duration?: number;
threshold?: number;
rootMargin?: string;
}
const props = withDefaults(defineProps<Props>(), {
className: '',
tag: 'p',
animateBy: 'chars',
direction: 'bottom',
delay: 65,
duration: 820,
threshold: 0.1,
rootMargin: '0px'
});
const rootRef = ref<HTMLElement | null>(null);
const isVisible = ref(false);
let observer: IntersectionObserver | null = null;
const tokens = computed(() => {
if (props.animateBy === 'words') {
return props.text.split(/(\s+)/).filter(Boolean);
}
return Array.from(props.text);
});
const rootClass = computed(() => ['blur-text', props.className].filter(Boolean).join(' '));
const yOffset = computed(() => (props.direction === 'top' ? '-0.72em' : '0.72em'));
function reveal() {
isVisible.value = true;
observer?.disconnect();
observer = null;
}
onMounted(() => {
const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (reduceMotion || !rootRef.value || !('IntersectionObserver' in window)) {
reveal();
return;
}
observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) reveal();
},
{
threshold: props.threshold,
rootMargin: props.rootMargin
}
);
observer.observe(rootRef.value);
});
onBeforeUnmount(() => {
observer?.disconnect();
});
</script>
<template>
<component :is="tag" ref="rootRef" :class="rootClass" :aria-label="text">
<span
v-for="(token, index) in tokens"
:key="`${token}-${index}`"
class="blur-text-token"
:class="{ 'blur-text-token-visible': isVisible }"
:style="{
'--blur-text-delay': `${index * delay}ms`,
'--blur-text-duration': `${duration}ms`,
'--blur-text-y': yOffset
}"
aria-hidden="true"
>
{{ token }}
</span>
</component>
</template>
<style scoped>
.blur-text {
display: block;
overflow-wrap: anywhere;
white-space: normal;
}
.blur-text-token {
display: inline-block;
filter: blur(12px);
opacity: 0;
transform: translate3d(0, var(--blur-text-y), 0);
transition:
filter var(--blur-text-duration) cubic-bezier(0.16, 1, 0.3, 1),
opacity var(--blur-text-duration) cubic-bezier(0.16, 1, 0.3, 1),
transform var(--blur-text-duration) cubic-bezier(0.16, 1, 0.3, 1);
transition-delay: var(--blur-text-delay);
will-change: filter, opacity, transform;
}
.blur-text-token-visible {
filter: blur(0);
opacity: 1;
transform: translate3d(0, 0, 0);
}
@media (prefers-reduced-motion: reduce) {
.blur-text-token {
filter: none;
opacity: 1;
transform: none;
transition: none;
}
}
</style>

View File

@@ -9,6 +9,7 @@ const route = useRoute()
const backdropClass = computed(() => {
if (route.path.startsWith('/video')) return 'video-route-backdrop'
if (route.path.startsWith('/product')) return 'product-route-backdrop'
if (route.path.startsWith('/about')) return 'about-route-backdrop'
return 'home-route-backdrop'
})
</script>
@@ -30,6 +31,7 @@ const backdropClass = computed(() => {
<RouterLink to="/">首页</RouterLink>
<RouterLink to="/product">产品</RouterLink>
<RouterLink to="/video/user">视频</RouterLink>
<RouterLink to="/about">关于我们</RouterLink>
<RouterLink to="/#business">业务介绍</RouterLink>
<RouterLink to="/product#pricing">定价计划</RouterLink>
<RouterLink to="/product#contact">联系咨询</RouterLink>

View File

@@ -11,6 +11,7 @@ const routes = [
{ path: 'product', name: 'Product', component: () => import('@/views/product/index.vue') },
{ path: 'video', redirect: '/video/user' },
{ path: 'video/:audience(user|doctor|manager)', name: 'VideoShowcase', component: () => import('@/views/video/index.vue') },
{ path: 'about', name: 'About', component: () => import('@/views/about/index.vue') },
],
},
]

View File

@@ -8,7 +8,8 @@ export const siteConfig = {
primary: [
{ label: '首页', to: '/' },
{ label: '产品', to: '/product' },
{ label: '视频', to: '/video/user' }
{ label: '视频', to: '/video/user' },
{ label: '关于我们', to: '/about' }
],
secondary: {
home: [
@@ -28,6 +29,12 @@ export const siteConfig = {
{ label: '用户端', to: '/video/user' },
{ label: '医生端', to: '/video/doctor' },
{ label: '小程序店长管理端', to: '/video/manager' }
],
about: [
{ label: '我们的愿景', to: '/about#vision' },
{ label: '发展理念', to: '/about#principles' },
{ label: '公司位置', to: '/about#location' },
{ label: '联系咨询', to: '/product#contact' }
]
}
},
@@ -42,6 +49,32 @@ export const siteConfig = {
phone: '400-820-9618',
email: 'hello@xiaokangcloudmed.cn',
address: '上海市浦东新区张江医疗创新园'
},
about: {
visionTitle: '让基层医疗机构以更低门槛拥有稳定、合规、可持续的数字化能力。',
visionBody: '萧康云医希望把复杂的医疗协同、经营管理和线上服务能力,沉淀成机构每天都能用得顺手的云端工作台。我们关注的不只是系统上线,而是医生、运营团队和患者之间能否形成长期、可靠、可追踪的服务闭环。',
principles: [
{
title: '医疗协同',
body: '围绕患者、医生和机构角色建立统一任务流,让跨岗位协作更清晰。'
},
{
title: '长期服务',
body: '支持随访、复诊、回访和转诊沉淀,帮助机构建立持续服务能力。'
},
{
title: '合规安全',
body: '以权限、审计、备案协助和部署选择为基础,适配医疗行业的合规要求。'
},
{
title: '经营增长',
body: '把挂号、处方、对账、推广和客户运营串联起来,帮助机构看清经营状态。'
}
],
locationName: '大远科创园A栋',
mapQuery: '大远科创园A栋',
mapUrl: 'https://www.amap.com/search?query=%E5%A4%A7%E8%BF%9C%E7%A7%91%E5%88%9B%E5%9B%ADA%E6%A0%8B',
mapOpenUrl: 'https://www.amap.com/search?query=%E5%A4%A7%E8%BF%9C%E7%A7%91%E5%88%9B%E5%9B%ADA%E6%A0%8B'
}
}

View File

@@ -2573,7 +2573,7 @@ textarea {
display: block;
font-size: clamp(3rem, 13vw, 9.5rem);
font-weight: 400;
letter-spacing: -0.04em;
letter-spacing: 0;
line-height: 0.92;
margin: 0 0 1.2rem;
perspective: 900px;
@@ -4219,6 +4219,351 @@ textarea {
}
}
/* About page */
.about-page {
--about-bg: #f8fbfc;
--about-bg-deep: #eef5f6;
--about-ink: #101416;
--about-muted: #5c6d74;
--about-panel: rgba(255, 255, 255, 0.92);
--about-panel-solid: #ffffff;
--about-line: rgba(15, 23, 42, 0.12);
--about-line-strong: rgba(13, 148, 136, 0.28);
--about-accent: #0f766e;
--about-accent-strong: #0f4f4a;
--about-sky: #0891b2;
--about-shadow: 0 24px 70px rgba(15, 23, 42, 0.12);
color: var(--about-ink);
overflow: clip;
}
:root[data-theme="dark"] .about-route-backdrop,
:root[data-theme="dark"] .about-page {
--about-bg: #0c0f10;
--about-bg-deep: #050707;
--about-ink: #eef7fb;
--about-muted: rgba(215, 226, 234, 0.72);
--about-panel: rgba(13, 18, 20, 0.9);
--about-panel-solid: #0d1214;
--about-line: rgba(215, 226, 234, 0.14);
--about-line-strong: rgba(45, 212, 191, 0.32);
--about-accent: #2dd4bf;
--about-accent-strong: #99f6e4;
--about-sky: #22d3ee;
--about-shadow: 0 28px 82px rgba(0, 0, 0, 0.38);
}
.about-route-backdrop {
background:
linear-gradient(180deg, var(--about-bg) 0%, var(--about-bg-deep) 48%, var(--about-bg) 100%);
}
.about-route-backdrop::before {
background:
linear-gradient(180deg, rgba(255, 255, 255, 0.72), rgba(245, 251, 252, 0.58) 22%, rgba(245, 251, 252, 0.62) 82%, rgba(255, 255, 255, 0.74));
}
:root[data-theme="dark"] .about-route-backdrop::before {
background:
linear-gradient(180deg, rgba(5, 9, 10, 0.8), rgba(5, 9, 10, 0.58) 24%, rgba(5, 9, 10, 0.66) 82%, rgba(5, 9, 10, 0.84));
}
.about-route-backdrop .theme-backdrop-canvas {
opacity: 0.16;
}
:root[data-theme="dark"] .about-route-backdrop .theme-backdrop-canvas {
opacity: 0.28;
}
.about-hero {
min-height: 88vh;
padding-bottom: 4rem;
}
.about-hero-inner,
.about-section-inner,
.about-location-shell {
margin: 0 auto;
max-width: 1180px;
width: 100%;
}
.about-hero-copy {
display: grid;
gap: 1.25rem;
max-width: 880px;
}
.about-eyebrow,
.about-section-heading span,
.about-vision-panel > span,
.about-map-meta span {
align-items: center;
color: var(--about-accent-strong);
display: inline-flex;
font-size: 0.8rem;
font-weight: 900;
gap: 0.5rem;
}
.about-eyebrow {
background: color-mix(in srgb, var(--about-accent) 10%, var(--about-panel-solid));
border: 1px solid var(--about-line-strong);
border-radius: 999px;
padding: 0.5rem 0.78rem;
width: max-content;
}
.about-hero-title {
color: var(--about-ink);
font-size: clamp(2.35rem, 6vw, 5.25rem);
font-weight: 900;
letter-spacing: 0;
line-height: 1.02;
margin: 0;
max-width: 960px;
text-wrap: balance;
}
.about-hero-subtitle,
.about-section-heading p,
.about-vision-panel p,
.about-principle-card p,
.about-map-meta small {
color: var(--about-muted);
line-height: 1.78;
}
.about-hero-subtitle {
font-size: clamp(1.05rem, 2vw, 1.45rem);
max-width: 720px;
}
.about-hero-actions {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
margin-top: 0.75rem;
}
.about-primary-action,
.about-secondary-action,
.about-map-meta a {
align-items: center;
border-radius: 999px;
display: inline-flex;
font-weight: 900;
gap: 0.45rem;
min-height: 46px;
padding: 0.75rem 1rem;
text-decoration: none;
transition: background 180ms ease-out, border-color 180ms ease-out, color 180ms ease-out, transform 180ms ease-out;
}
.about-primary-action,
.about-map-meta a {
background: var(--about-ink);
color: var(--about-bg);
}
.about-primary-action:hover,
.about-map-meta a:hover {
background: linear-gradient(135deg, #ffffff 0%, #c8fff2 48%, #ffffff 100%);
color: #041012;
transform: translateY(-1px);
}
.about-secondary-action {
border: 1px solid var(--about-line-strong);
color: var(--about-ink);
}
.about-secondary-action:hover {
background: color-mix(in srgb, var(--about-accent) 10%, transparent);
}
.about-section {
padding: 5.5rem 0;
}
.about-section-muted {
background:
linear-gradient(120deg, color-mix(in srgb, var(--about-accent) 8%, transparent), transparent 42%),
color-mix(in srgb, var(--about-panel-solid) 74%, transparent);
}
:root[data-theme="dark"] .about-section-muted {
background:
linear-gradient(120deg, color-mix(in srgb, var(--about-accent) 10%, transparent), transparent 42%),
rgba(7, 20, 23, 0.34);
}
.about-vision-panel,
.about-principle-card,
.about-map-panel {
background: var(--about-panel);
border: 1px solid var(--about-line);
box-shadow: var(--about-shadow);
color: var(--about-ink);
overflow: hidden;
position: relative;
}
.about-vision-panel {
border-radius: 30px;
display: grid;
gap: 1rem;
padding: clamp(1.5rem, 4vw, 2.5rem);
}
.about-vision-panel h2,
.about-section-heading h2 {
color: var(--about-ink);
font-size: clamp(2rem, 4vw, 3.6rem);
font-weight: 900;
line-height: 1.08;
margin: 0.4rem 0 0;
text-wrap: balance;
}
.about-vision-panel p {
font-size: 1.08rem;
max-width: 880px;
}
.about-section-heading {
display: grid;
gap: 0.6rem;
max-width: 760px;
}
.about-principle-grid {
display: grid;
gap: 1rem;
grid-template-columns: repeat(4, minmax(0, 1fr));
margin-top: 2rem;
}
.about-principle-reveal {
height: 100%;
}
.about-principle-card {
border-radius: 24px;
display: grid;
gap: 0.7rem;
height: 100%;
min-height: 240px;
padding: 1.2rem;
transition: border-color 180ms ease-out, box-shadow 180ms ease-out, transform 180ms ease-out;
}
.about-principle-card:hover {
border-color: var(--about-line-strong);
box-shadow: 0 28px 78px color-mix(in srgb, var(--about-accent) 12%, rgba(15, 23, 42, 0.12));
transform: translateY(-2px);
}
.about-principle-card svg,
.about-map-meta > svg {
color: var(--about-accent);
}
.about-principle-card h3 {
color: var(--about-ink);
font-size: 1.18rem;
font-weight: 900;
margin: 0;
}
.about-location-shell {
display: grid;
gap: 1.5rem;
max-width: 1480px;
}
.about-map-panel {
border-radius: 30px;
display: grid;
gap: 1rem;
grid-template-columns: minmax(0, 1.45fr) minmax(300px, 0.36fr);
padding: 1rem;
}
.about-map-frame {
aspect-ratio: 16 / 9;
background:
linear-gradient(135deg, color-mix(in srgb, var(--about-accent) 12%, var(--about-panel-solid)), var(--about-panel-solid));
border: 1px solid var(--about-line);
border-radius: 24px;
min-height: 560px;
overflow: hidden;
position: relative;
}
.about-map-frame iframe {
border: 0;
height: 100%;
width: 100%;
}
.about-map-meta {
align-content: center;
display: grid;
gap: 1rem;
padding: 0.5rem;
}
.about-map-meta strong {
color: var(--about-ink);
display: block;
font-size: 1.35rem;
margin: 0.25rem 0;
}
@media (max-width: 1023px) {
.about-principle-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.about-map-panel {
grid-template-columns: 1fr;
}
.about-map-frame {
min-height: 500px;
}
}
@media (max-width: 767px) {
.about-hero {
min-height: auto;
}
.about-hero-actions,
.about-primary-action,
.about-secondary-action,
.about-map-meta a {
width: 100%;
}
.about-primary-action,
.about-secondary-action,
.about-map-meta a {
justify-content: center;
}
.about-principle-grid {
grid-template-columns: 1fr;
}
.about-map-frame {
aspect-ratio: 4 / 5;
min-height: 460px;
}
}
/* Final nav contrast, backdrop interaction, and home marquee fixes */
.site-header {
--nav-ink: #f8ffff;
@@ -4242,7 +4587,8 @@ textarea {
.site-header-home,
:root[data-theme="dark"] .site-header-solid,
:root[data-theme="dark"] .site-header-product {
:root[data-theme="dark"] .site-header-product,
:root[data-theme="dark"] .site-header-about {
--nav-ink: #f8ffff;
--nav-muted: rgba(215, 226, 234, 0.78);
--nav-panel: rgba(12, 12, 12, 0.78);

126
src/views/about/index.vue Normal file
View File

@@ -0,0 +1,126 @@
<script setup>
import { ArrowRight, Building2, CheckCircle2, MapPinned, ShieldCheck, Sparkles } from 'lucide-vue-next'
import AnimatedContent from '@/components/vue-bits/AnimatedContent.vue'
import DecryptedText from '@/components/vue-bits/DecryptedText.vue'
import SplitText from '@/components/vue-bits/SplitText.vue'
import { siteConfig } from '@/site.config'
const principleIcons = [Sparkles, CheckCircle2, ShieldCheck, Building2]
</script>
<template>
<main class="about-page">
<section class="about-hero section-pad">
<div class="about-hero-inner px-5 pt-24 md:px-8">
<AnimatedContent :distance="54" :duration="0.9" class-name="about-hero-copy">
<div class="about-eyebrow">
<Building2 :size="16" aria-hidden="true" />
关于{{ siteConfig.brand.name }}
</div>
<SplitText
:text="siteConfig.about.visionTitle"
tag="h1"
class-name="about-hero-title"
split-type="lines"
:delay="58"
:duration="0.92"
ease="power4.out"
:from="{ opacity: 0, y: 38, filter: 'blur(12px)' }"
:to="{ opacity: 1, y: 0, filter: 'blur(0)' }"
/>
<p class="about-hero-subtitle">
<DecryptedText
:text="siteConfig.brand.description"
animate-on="view"
reveal-direction="center"
:speed="30"
:max-iterations="10"
encrypted-class-name="decrypted-ghost"
class-name="decrypted-final"
/>
</p>
<div class="about-hero-actions">
<a href="#vision" class="about-primary-action">
了解愿景
<ArrowRight :size="18" aria-hidden="true" />
</a>
<a :href="siteConfig.about.mapOpenUrl" target="_blank" rel="noreferrer" class="about-secondary-action">
查看公司位置
</a>
</div>
</AnimatedContent>
</div>
</section>
<section id="vision" class="about-section">
<div class="about-section-inner px-5 md:px-8">
<AnimatedContent :distance="44" :duration="0.8" class-name="about-vision-panel">
<span>我们的愿景</span>
<h2>{{ siteConfig.about.visionTitle }}</h2>
<p>{{ siteConfig.about.visionBody }}</p>
</AnimatedContent>
</div>
</section>
<section id="principles" class="about-section about-section-muted">
<div class="about-section-inner px-5 md:px-8">
<AnimatedContent :distance="42" :duration="0.8" class-name="about-section-heading">
<span>发展理念</span>
<h2>把医疗服务机构经营和合规能力放进同一个长期系统</h2>
</AnimatedContent>
<div class="about-principle-grid">
<AnimatedContent
v-for="(item, index) in siteConfig.about.principles"
:key="item.title"
:delay="index * 0.08"
:distance="44"
class-name="about-principle-reveal"
>
<article class="about-principle-card">
<component :is="principleIcons[index % principleIcons.length]" :size="24" aria-hidden="true" />
<h3>{{ item.title }}</h3>
<p>{{ item.body }}</p>
</article>
</AnimatedContent>
</div>
</div>
</section>
<section id="location" class="about-section">
<div class="about-location-shell px-5 md:px-8">
<AnimatedContent :distance="42" :duration="0.8" class-name="about-section-heading align-left">
<span>公司位置</span>
<h2>在高德地图中查看{{ siteConfig.about.locationName }}</h2>
<p>地图使用高德官网公开搜索页嵌入不接入开放平台 SDK不需要 API Key</p>
</AnimatedContent>
<AnimatedContent :distance="48" direction="horizontal" :reverse="true" :duration="0.86" class-name="about-map-panel">
<div class="about-map-frame">
<iframe
:src="siteConfig.about.mapUrl"
:title="`${siteConfig.about.locationName} 高德地图`"
loading="lazy"
referrerpolicy="no-referrer-when-downgrade"
/>
</div>
<div class="about-map-meta">
<MapPinned :size="24" aria-hidden="true" />
<div>
<span>搜索目标</span>
<strong>{{ siteConfig.about.locationName }}</strong>
<small>如果浏览器限制 iframe 加载可使用下方按钮在高德地图中打开</small>
</div>
<a :href="siteConfig.about.mapOpenUrl" target="_blank" rel="noreferrer">
在高德地图中打开
<ArrowRight :size="17" aria-hidden="true" />
</a>
</div>
</AnimatedContent>
</div>
</section>
</main>
</template>

View File

@@ -5,6 +5,7 @@ import { ArrowLeft, ArrowRight, Calendar, CheckCircle2, Clock3, Play, ShieldChec
import { homeCaseCards, homeMarqueeItems, homeServiceItems, metrics, siteConfig } from '@/site.config'
import AnimatedContent from '@/components/vue-bits/AnimatedContent.vue'
import DecryptedText from '@/components/vue-bits/DecryptedText.vue'
import BlurText from '@/components/vue-bits/BlurText.vue'
import Magnet from '@/components/vue-bits/Magnet.vue'
import Silk from '@/components/vue-bits/Silk.vue'
import SplitText from '@/components/vue-bits/SplitText.vue'
@@ -99,19 +100,16 @@ onBeforeUnmount(() => {
</span>
</div>
<SplitText
<BlurText
:text="siteConfig.brand.name"
tag="h1"
class-name="cinematic-title"
split-type="chars"
:delay="80"
:duration="1.15"
ease="power4.out"
animate-by="chars"
direction="bottom"
:delay="90"
:duration="980"
:threshold="0.05"
root-margin="0px"
:from="{ opacity: 0, y: 70, filter: 'blur(18px)', rotateX: -22 }"
:to="{ opacity: 1, y: 0, filter: 'blur(0px)', rotateX: 0 }"
text-align="left"
/>
<p class="cinematic-subtitle animate-blur-fade-up" style="animation-delay: 500ms">
<DecryptedText