9
app.vue
9
app.vue
@@ -28,4 +28,13 @@ useHead({
|
||||
opacity: 0;
|
||||
filter: blur(1rem);
|
||||
}
|
||||
.layout-enter-active,
|
||||
.layout-leave-active {
|
||||
transition: all 0.4s;
|
||||
}
|
||||
.layout-enter-from,
|
||||
.layout-leave-to {
|
||||
opacity: 0;
|
||||
filter: blur(1rem);
|
||||
}
|
||||
</style>
|
||||
|
||||
90
components/common/Docs.vue
Normal file
90
components/common/Docs.vue
Normal file
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<PageBackground>
|
||||
<div class="flex relative h-[calc(100vh-var(--header-height))] overflow-y-auto flex-col md:flex-row">
|
||||
<!-- Sidebar -->
|
||||
<aside
|
||||
class="md:sticky md:top-0 md:w-44 md:ml-48 w-full border-b md:border-b-0 md:border-r border-gray-200 dark:border-teal-900 overflow-y-auto">
|
||||
<nav class="p-4 space-y-1">
|
||||
<div class="mb-4">
|
||||
<h3 class="px-3 text-sm font-semibold text-gray-500 dark:text-gray-400">开始使用</h3>
|
||||
<div class="mt-1 space-y-1">
|
||||
<NuxtLink
|
||||
to="/docs/getting-started/introduction"
|
||||
class="flex items-center px-3 py-2 text-sm rounded-lg md:ml-4"
|
||||
:class="{
|
||||
'text-teal-600': $route.path === '/docs/getting-started/introduction',
|
||||
'hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-700 dark:text-gray-300':
|
||||
$route.path !== '/docs/getting-started/introduction'
|
||||
}">
|
||||
<div
|
||||
:class="[
|
||||
'w-5 h-5 mr-2 flex items-center justify-center rounded',
|
||||
$route.path === '/docs/getting-started/introduction'
|
||||
? 'bg-teal-600'
|
||||
: 'bg-gray-200 dark:bg-gray-700'
|
||||
]">
|
||||
<Icon
|
||||
name="ph:book-open"
|
||||
:class="[
|
||||
'w-3.5 h-3.5',
|
||||
$route.path === '/docs/getting-started/introduction'
|
||||
? 'text-white'
|
||||
: 'text-gray-500 dark:text-gray-400'
|
||||
]" />
|
||||
</div>
|
||||
安装与启动
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</aside>
|
||||
|
||||
<!-- Main content -->
|
||||
<main class="flex-1 md:ml-2 overflow-y-auto" style="scrollbar-width: none">
|
||||
<div class="container mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||
<slot />
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</PageBackground>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<style scoped>
|
||||
.photon-effect {
|
||||
position: absolute;
|
||||
width: 2px;
|
||||
height: 100%;
|
||||
animation: movePhoton 3s linear infinite;
|
||||
}
|
||||
|
||||
.light-photon {
|
||||
background: linear-gradient(180deg, transparent, rgba(14, 165, 233, 0.5), transparent);
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.dark-photon {
|
||||
background: linear-gradient(180deg, transparent, #fff, transparent);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.delay-2 {
|
||||
animation-delay: 1s;
|
||||
left: 30%;
|
||||
}
|
||||
|
||||
.delay-4 {
|
||||
animation-delay: 2s;
|
||||
left: 70%;
|
||||
}
|
||||
|
||||
@keyframes movePhoton {
|
||||
0% {
|
||||
transform: translateY(-100%) translateX(-100%);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(100%) translateX(100%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
65
components/common/Footer.vue
Normal file
65
components/common/Footer.vue
Normal file
@@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<footer class="bg-gray-50 dark:bg-gray-900 border-t border-gray-200 dark:border-gray-800 py-8 md:py-12">
|
||||
<div class="container mx-auto px-4 grid grid-cols-2 md:grid-cols-4 gap-6 md:gap-8">
|
||||
<!-- Product Section -->
|
||||
<div class="text-center md:text-left">
|
||||
<h4 class="font-semibold text-gray-800 dark:text-gray-200 mb-3 md:mb-4">产品展示</h4>
|
||||
<nav class="flex flex-col space-y-2">
|
||||
<a href="#" class="text-gray-600 dark:text-gray-400 hover:text-teal-600 transition text-sm">定制</a>
|
||||
<a href="#" class="text-gray-600 dark:text-gray-400 hover:text-teal-600 transition text-sm">路线图</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Developers Section -->
|
||||
<div class="text-center md:text-left">
|
||||
<h4 class="font-semibold text-gray-800 dark:text-gray-200 mb-3 md:mb-4">开发人员</h4>
|
||||
<nav class="flex flex-col space-y-2">
|
||||
<a
|
||||
href="https://github.com/orgs/HuLaSpark/teams"
|
||||
class="text-gray-600 dark:text-gray-400 hover:text-teal-600 transition text-sm"
|
||||
>HuLaSpark团队</a
|
||||
>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Community Section -->
|
||||
<div class="text-center md:text-left">
|
||||
<h4 class="font-semibold text-gray-800 dark:text-gray-200 mb-3 md:mb-4">社区</h4>
|
||||
<nav class="flex flex-col space-y-2">
|
||||
<a href="#" class="text-gray-600 dark:text-gray-400 hover:text-teal-600 transition text-sm">微信群聊</a>
|
||||
<a href="#" class="text-gray-600 dark:text-gray-400 hover:text-teal-600 transition text-sm">QQ</a>
|
||||
<a href="#" class="text-gray-600 dark:text-gray-400 hover:text-teal-600 transition text-sm">HuLa</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Company Section -->
|
||||
<div class="text-center md:text-left">
|
||||
<h4 class="font-semibold text-gray-800 dark:text-gray-200 mb-3 md:mb-4">团队简介</h4>
|
||||
<nav class="flex flex-col space-y-2">
|
||||
<a href="#" class="text-gray-600 dark:text-gray-400 hover:text-teal-600 transition text-sm">关于HuLaSpark</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="container mx-auto px-4 mt-6 md:mt-8 pt-6 md:pt-8 border-t border-gray-200 dark:border-gray-800 text-center">
|
||||
<div class="flex flex-col md:flex-row justify-between items-center space-y-4 md:space-y-0">
|
||||
<div class="text-gray-600 dark:text-gray-400 text-xs md:text-sm">
|
||||
{{ currentYear }} HuLaSpark. All rights reserved.
|
||||
</div>
|
||||
<div class="flex space-x-4">
|
||||
<a href="#" class="text-gray-600 dark:text-gray-400 hover:text-teal-600 transition text-xs md:text-sm">
|
||||
隐私条款
|
||||
</a>
|
||||
<a href="#" class="text-gray-600 dark:text-gray-400 hover:text-teal-600 transition text-xs md:text-sm">
|
||||
服务协议
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const currentYear = new Date().getFullYear()
|
||||
</script>
|
||||
@@ -94,19 +94,97 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="isMobileMenuOpen" class="fixed inset-0 bg-white dark:bg-gray-900 z-50 flex flex-col">
|
||||
<div v-if="isMobileMenuOpen" class="fixed inset-0 bg-white dark:bg-gray-900 z-50 flex flex-col overflow-y-auto">
|
||||
<button
|
||||
@click="isMobileMenuOpen = false"
|
||||
class="absolute top-4 right-4 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200">
|
||||
<UIcon name="solar:close-circle-linear" class="w-6 h-6" />
|
||||
</button>
|
||||
<div class="p-4">
|
||||
<span
|
||||
:class="{ 'text-teal-600': isActive('/docs/getting-started/introduction') }"
|
||||
class="font-semibold text-sm/6 inline-block relative">
|
||||
开始使用
|
||||
</span>
|
||||
<span class="text-sm leading-snug text-gray-500 dark:text-gray-400 line-clamp-2"> 了解如何开始使用 HuLa </span>
|
||||
|
||||
<div class="p-4 space-y-4">
|
||||
<div class="flex items-center gap-2.5 border-b pb-4 border-gray-200 dark:border-gray-800">
|
||||
<NuxtLink to="/" @click="isMobileMenuOpen = false" class="inline-flex items-center gap-2.5">
|
||||
<img class="w-7 h-7" src="~/assets/logo/logo.png" alt="" />
|
||||
<span class="text-lg text-teal-900 dark:text-teal-600 font-semibold">HuLa</span>
|
||||
</NuxtLink>
|
||||
<span
|
||||
class="inline-flex items-center text-xs px-1.5 py-0.5 bg-teal-50 dark:bg-teal-400 dark:bg-opacity-10 text-teal-500 dark:text-teal-400 ring-1 ring-inset ring-teal-500 dark:ring-teal-400 ring-opacity-25 dark:ring-opacity-25 rounded font-semibold">
|
||||
{{ config.MasterVersion }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<h3 class="text-sm font-semibold text-gray-600 dark:text-gray-400 mb-2">文档</h3>
|
||||
<div class="space-y-1">
|
||||
<NuxtLink
|
||||
to="/docs/getting-started/introduction"
|
||||
@click="isMobileMenuOpen = false"
|
||||
:class="{ 'text-teal-600': isActive('/docs/getting-started/introduction') }"
|
||||
class="block px-2 py-1.5 rounded-md hover:bg-gray-100/50 dark:hover:bg-gray-950/50 flex items-center gap-2">
|
||||
<UIcon
|
||||
name="solar:bolt-outline"
|
||||
:class="{ 'text-teal-600': isActive('/docs/getting-started/introduction') }"
|
||||
class="w-4 h-4 text-gray-500 dark:text-gray-400 flex-shrink-0" />
|
||||
<div>
|
||||
<span
|
||||
:class="{ 'text-teal-600': isActive('/docs/getting-started/introduction') }"
|
||||
class="font-semibold text-sm/6 block">
|
||||
开始使用
|
||||
</span>
|
||||
<span class="text-xs text-gray-500 dark:text-gray-400 line-clamp-1"> 了解如何开始使用 HuLa </span>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2 mt-4">
|
||||
<h3 class="text-sm font-semibold text-gray-600 dark:text-gray-400 mb-2">快捷操作</h3>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<button
|
||||
@click="handleMobileAction('new-file')"
|
||||
class="flex items-center gap-2 px-2 py-1.5 rounded-md hover:bg-gray-100/50 dark:hover:bg-gray-950/50">
|
||||
<UIcon name="i-heroicons-document-plus" class="w-4 h-4 text-gray-500 dark:text-gray-400" />
|
||||
<span class="text-sm">新建文件</span>
|
||||
</button>
|
||||
<button
|
||||
@click="handleMobileAction('new-folder')"
|
||||
class="flex items-center gap-2 px-2 py-1.5 rounded-md hover:bg-gray-100/50 dark:hover:bg-gray-950/50">
|
||||
<UIcon name="i-heroicons-folder-plus" class="w-4 h-4 text-gray-500 dark:text-gray-400" />
|
||||
<span class="text-sm">新建文件夹</span>
|
||||
</button>
|
||||
<button
|
||||
@click="handleMobileAction('hashtag')"
|
||||
class="flex items-center gap-2 px-2 py-1.5 rounded-md hover:bg-gray-100/50 dark:hover:bg-gray-950/50">
|
||||
<UIcon name="i-heroicons-hashtag" class="w-4 h-4 text-gray-500 dark:text-gray-400" />
|
||||
<span class="text-sm">添加标签</span>
|
||||
</button>
|
||||
<button
|
||||
@click="handleMobileAction('label')"
|
||||
class="flex items-center gap-2 px-2 py-1.5 rounded-md hover:bg-gray-100/50 dark:hover:bg-gray-950/50">
|
||||
<UIcon name="i-heroicons-tag" class="w-4 h-4 text-gray-500 dark:text-gray-400" />
|
||||
<span class="text-sm">添加标签</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2 mt-4">
|
||||
<h3 class="text-sm font-semibold text-gray-600 dark:text-gray-400 mb-2">链接</h3>
|
||||
<div class="space-y-1">
|
||||
<a
|
||||
v-for="user in users"
|
||||
:key="user.id"
|
||||
:href="user.href"
|
||||
target="_blank"
|
||||
class="flex items-center gap-2 px-2 py-1.5 rounded-md hover:bg-gray-100/50 dark:hover:bg-gray-950/50">
|
||||
<img
|
||||
:src="user.avatar.src"
|
||||
:srcset="user.avatar.srcset"
|
||||
:loading="user.avatar.loading as any"
|
||||
class="w-6 h-6 rounded-full" />
|
||||
<span class="text-sm">{{ user.label }}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -229,6 +307,25 @@ const onSelect = (option: any) => {
|
||||
const isActive = (path: string) => {
|
||||
return route.path === path
|
||||
}
|
||||
|
||||
const handleMobileAction = (action: string) => {
|
||||
switch (action) {
|
||||
case 'new-file':
|
||||
toast.add({ title: 'New file added!' })
|
||||
break
|
||||
case 'new-folder':
|
||||
toast.add({ title: 'New folder added!' })
|
||||
break
|
||||
case 'hashtag':
|
||||
toast.add({ title: 'Hashtag added!' })
|
||||
break
|
||||
case 'label':
|
||||
toast.add({ title: 'Label added!' })
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
94
components/common/PackageManagerTabs.vue
Normal file
94
components/common/PackageManagerTabs.vue
Normal file
@@ -0,0 +1,94 @@
|
||||
<template>
|
||||
<div class="flex border-b border-gray-200 dark:border-gray-700 mb-4 items-center overflow-x-auto">
|
||||
<div class="flex flex-1 min-w-max">
|
||||
<button
|
||||
v-for="manager in props.packageManagers"
|
||||
:key="manager"
|
||||
:class="[
|
||||
'px-4 py-2 text-sm font-medium flex items-center gap-2 transition-colors duration-200',
|
||||
manager === 'npm' || manager === 'yarn'
|
||||
? 'text-gray-300 dark:text-gray-600 cursor-not-allowed opacity-50'
|
||||
: activeManager === manager
|
||||
? 'text-teal-600 dark:text-teal-500 border-b-2 border-transparent border-teal-600 dark:border-teal-500'
|
||||
: ''
|
||||
]"
|
||||
:disabled="manager === 'npm' || manager === 'yarn'"
|
||||
@click="handleManagerChange(manager)">
|
||||
<img :src="managerIcons[manager].icon" :alt="manager" class="w-4 h-4" />
|
||||
{{ manager }}
|
||||
<span
|
||||
v-if="manager === 'pnpm'"
|
||||
class="ml-2 px-2 py-0.5 text-xs font-medium text-teal-700 bg-teal-100 rounded-full">
|
||||
推荐
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="relative">
|
||||
<button
|
||||
v-if="activeManager === 'pnpm' || activeManager === 'bun'"
|
||||
@click="handleCopy"
|
||||
class="ml-4 text-gray-500 hover:text-teal-600 transition-colors relative">
|
||||
<Icon name="ph:copy-simple-fill" class="w-5 h-5" />
|
||||
</button>
|
||||
<div
|
||||
v-if="showCopyTooltip"
|
||||
class="absolute -top-8 left-1/2 transform -translate-x-1/2 bg-gray-200 dark:bg-gray-700 text-gray-800 dark:text-white text-xs px-2 py-1 rounded shadow-sm inline-flex whitespace-nowrap transition-all duration-300 ease-in-out">
|
||||
复制成功
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<slot :activeManager="activeManager"></slot>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
manager: {
|
||||
type: String,
|
||||
default: 'pnpm'
|
||||
},
|
||||
packageManagers: {
|
||||
type: Array as PropType<string[]>,
|
||||
default: () => ['npm', 'yarn', 'pnpm', 'bun']
|
||||
}
|
||||
})
|
||||
|
||||
const managerIcons: Record<string, { icon: string; color: string }> = {
|
||||
npm: {
|
||||
icon: '/assets/svg/npm.svg',
|
||||
color: '#CB3837'
|
||||
},
|
||||
yarn: {
|
||||
icon: '/assets/svg/yarn.svg',
|
||||
color: '#2C8EBB'
|
||||
},
|
||||
pnpm: {
|
||||
icon: '/assets/svg/pnpm.svg',
|
||||
color: '#F69220'
|
||||
},
|
||||
bun: {
|
||||
icon: '/assets/svg/bun.svg',
|
||||
color: '#FBF0DF'
|
||||
}
|
||||
}
|
||||
|
||||
const activeManager = ref(props.manager)
|
||||
const showCopyTooltip = ref(false)
|
||||
|
||||
const emit = defineEmits(['update:manager', 'copy'])
|
||||
|
||||
const handleManagerChange = (manager: string) => {
|
||||
if (manager !== 'npm' && manager !== 'yarn') {
|
||||
activeManager.value = manager
|
||||
emit('update:manager', manager)
|
||||
}
|
||||
}
|
||||
|
||||
const handleCopy = () => {
|
||||
emit('copy')
|
||||
showCopyTooltip.value = true
|
||||
|
||||
setTimeout(() => {
|
||||
showCopyTooltip.value = false
|
||||
}, 2000)
|
||||
}
|
||||
</script>
|
||||
57
components/common/PageBackground.vue
Normal file
57
components/common/PageBackground.vue
Normal file
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<div class="min-h-[calc(100vh-var(--header-height))] relative bg-[#f8fafc] dark:bg-[#111729] overflow-hidden">
|
||||
<img
|
||||
class="pointer-events-none absolute w-full top-[1px] text-teal flex-shrink-0 z-10"
|
||||
src="/assets/svg/header.svg"
|
||||
alt="" />
|
||||
<div class="absolute inset-0">
|
||||
<div
|
||||
class="absolute inset-0 bg-gradient-to-b from-[#f8fafc] via-[#e2e8f0] to-[#f8fafc] dark:from-[#111729] dark:via-[#0c1322] dark:to-[#111729] opacity-60 dark:opacity-80"></div>
|
||||
<div
|
||||
class="absolute inset-0 bg-[url('/assets/svg/grid-light.svg')] dark:bg-[url('/assets/svg/grid.svg')] bg-center [mask-image:linear-gradient(180deg,white,rgba(255,255,255,0))]">
|
||||
<div class="photon-effect light-photon dark:dark-photon"></div>
|
||||
<div class="photon-effect light-photon dark:dark-photon delay-2"></div>
|
||||
<div class="photon-effect light-photon dark:dark-photon delay-4"></div>
|
||||
</div>
|
||||
</div>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.photon-effect {
|
||||
position: absolute;
|
||||
width: 2px;
|
||||
height: 100%;
|
||||
animation: movePhoton 3s linear infinite;
|
||||
}
|
||||
|
||||
.light-photon {
|
||||
background: linear-gradient(180deg, transparent, rgba(14, 165, 233, 0.5), transparent);
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.dark-photon {
|
||||
background: linear-gradient(180deg, transparent, #fff, transparent);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.delay-2 {
|
||||
animation-delay: 1s;
|
||||
left: 30%;
|
||||
}
|
||||
|
||||
.delay-4 {
|
||||
animation-delay: 2s;
|
||||
left: 70%;
|
||||
}
|
||||
|
||||
@keyframes movePhoton {
|
||||
0% {
|
||||
transform: translateY(-100%) translateX(-100%);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(100%) translateX(100%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,9 +1,10 @@
|
||||
<template>
|
||||
<div>
|
||||
<Header />
|
||||
<slot name="left" />
|
||||
<slot name="main" />
|
||||
<slot name="right" />
|
||||
<Docs>
|
||||
<slot />
|
||||
</Docs>
|
||||
<Footer />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ export default defineNuxtConfig({
|
||||
modules: ['@nuxt/test-utils/module', '@nuxt/ui', '@nuxt/image', '@nuxtjs/color-mode'],
|
||||
app: {
|
||||
pageTransition: { name: 'page', mode: 'out-in' },
|
||||
layoutTransition: { name: 'layout', mode: 'out-in' },
|
||||
head: {
|
||||
script: [{ src: '/icon.js' }]
|
||||
}
|
||||
|
||||
@@ -1,12 +1,224 @@
|
||||
<template>
|
||||
<div class="w-full min-h-[calc(100vh-var(--header-height))] flex justify-center items-center">
|
||||
官网正在编写中,敬请期待!
|
||||
<div class="max-w-3xl mx-auto lg:mx-24 px-4 sm:px-6 lg:px-8">
|
||||
<div class="mb-8">
|
||||
<h1 class="text-3xl sm:text-4xl font-bold text-gray-900 dark:text-white">HuLa 介绍</h1>
|
||||
<p class="mt-2 text-base sm:text-lg text-gray-600 dark:text-gray-400">了解 HuLa 的特性,开始你的第一个项目:</p>
|
||||
</div>
|
||||
|
||||
<div class="prose prose-sm max-w-none dark:prose-invert">
|
||||
<div class="mb-8">
|
||||
<h2 class="text-xl sm:text-2xl font-semibold">什么是 HuLa?</h2>
|
||||
<p>
|
||||
HuLa 是一个基于 Tauri、Vite 5、Vue 3 和 TypeScript 构建的即时通讯系统。它利用了 Tauri 的跨平台能力和 Vue 3
|
||||
的响应式设计,结合了 TypeScript 的类型安全特性和 Vite 5
|
||||
的快速构建,为用户提供了一个高效、安全和易用的通讯解决方案。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mb-8">
|
||||
<h2 class="text-xl sm:text-2xl font-semibold">核心特性</h2>
|
||||
<ul class="space-y-4">
|
||||
<li class="flex items-start">
|
||||
<Icon name="ph:lightning" class="w-5 h-5 sm:w-6 sm:h-6 mr-2 text-teal-600" />
|
||||
<div>
|
||||
<strong>现代架构</strong>
|
||||
<p class="mt-1 text-sm sm:text-base">基于前沿技术构建,实现最佳性能和开发体验。</p>
|
||||
</div>
|
||||
</li>
|
||||
<li class="flex items-start">
|
||||
<Icon name="ph:code" class="w-5 h-5 sm:w-6 sm:h-6 mr-2 text-teal-600" />
|
||||
<div>
|
||||
<strong>开发体验</strong>
|
||||
<p class="mt-1 text-sm sm:text-base">良好的开发规范和工具链,封装通用的组件和 API,实现快速开发。</p>
|
||||
</div>
|
||||
</li>
|
||||
<li class="flex items-start">
|
||||
<Icon name="ph:rocket" class="w-5 h-5 sm:w-6 sm:h-6 mr-2 text-teal-600" />
|
||||
<div>
|
||||
<strong>高性能</strong>
|
||||
<p class="mt-1 text-sm sm:text-base">使用Rust优化的构建过程和基于Vite 6 的高性能,打造极速应用。</p>
|
||||
</div>
|
||||
</li>
|
||||
<li class="flex items-start">
|
||||
<Icon name="ph:puzzle-piece" class="w-5 h-5 sm:w-6 sm:h-6 mr-2 text-teal-600" />
|
||||
<div>
|
||||
<strong>可扩展性</strong>
|
||||
<span class="ml-2 px-2 py-0.5 text-xs font-medium text-purple-700 bg-purple-100 rounded-full">
|
||||
Beta
|
||||
</span>
|
||||
<p class="mt-1 text-sm sm:text-base">丰富的插件和模块生态系统,轻松扩展功能。</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="mb-8">
|
||||
<h2 class="text-xl sm:text-2xl font-semibold">快速开始</h2>
|
||||
<p class="mb-4 text-sm sm:text-base">准备开始了吗?按照以下步骤启动你的第一个 HuLa 项目:</p>
|
||||
<div class="space-y-6">
|
||||
<h3 class="text-base sm:text-lg font-medium mb-3">第一步:克隆项目</h3>
|
||||
<div class="not-prose bg-gray-50 dark:bg-gray-800 rounded-lg p-4">
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="relative">
|
||||
<div class="bg-gray-100 dark:bg-gray-900 p-2 rounded pr-10 text-xs sm:text-sm overflow-x-auto">
|
||||
Gitee: {{ commands.clone.gitee }}
|
||||
</div>
|
||||
<button
|
||||
@click="copyLink(commands.clone.gitee)"
|
||||
class="absolute top-2 right-2 text-gray-500 hover:text-teal-600 transition-colors">
|
||||
<Icon name="ph:copy-simple-fill" class="w-4 h-4 sm:w-5 sm:h-5" />
|
||||
</button>
|
||||
</div>
|
||||
<p class="text-center text-sm">或者</p>
|
||||
<div class="relative">
|
||||
<div class="bg-gray-100 dark:bg-gray-900 p-2 rounded pr-10 text-xs sm:text-sm overflow-x-auto">
|
||||
GitHub: {{ commands.clone.github }}
|
||||
</div>
|
||||
<button
|
||||
@click="copyLink(commands.clone.github)"
|
||||
class="absolute top-2 right-2 text-gray-500 hover:text-teal-600 transition-colors">
|
||||
<Icon name="ph:copy-simple-fill" class="w-4 h-4 sm:w-5 sm:h-5" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="text-base sm:text-lg font-medium mb-3">第二步:进入项目目录</h3>
|
||||
<div class="not-prose bg-gray-50 dark:bg-gray-800 rounded-lg p-4">
|
||||
<div class="relative">
|
||||
<div class="bg-gray-100 dark:bg-gray-900 p-2 rounded pr-10 text-xs sm:text-sm overflow-x-auto">
|
||||
{{ commands.directory }}
|
||||
</div>
|
||||
<button
|
||||
@click="copyLink(commands.directory)"
|
||||
class="absolute top-2 right-2 text-gray-500 hover:text-teal-600 transition-colors">
|
||||
<Icon name="ph:copy-simple-fill" class="w-4 h-4 sm:w-5 sm:h-5" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="text-base sm:text-lg font-medium mb-3">第三步:安装依赖</h3>
|
||||
<div class="not-prose bg-gray-50 dark:bg-gray-800 rounded-lg p-4">
|
||||
<PackageManagerTabs v-model:manager="activeManager" @copy="copyCommand(commands[activeManager].install)">
|
||||
<template #default="{ activeManager }">
|
||||
<div>
|
||||
<div
|
||||
v-if="activeManager === 'pnpm'"
|
||||
class="bg-gray-100 dark:bg-gray-900 p-2 rounded text-xs sm:text-sm overflow-x-auto">
|
||||
{{ commands.pnpm.install }}
|
||||
</div>
|
||||
<div
|
||||
v-if="activeManager === 'bun'"
|
||||
class="bg-gray-100 dark:bg-gray-900 p-2 rounded text-xs sm:text-sm overflow-x-auto">
|
||||
{{ commands.bun.install }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</PackageManagerTabs>
|
||||
</div>
|
||||
|
||||
<h3 class="text-base sm:text-lg font-medium mb-3">第四步:启动项目</h3>
|
||||
<div class="not-prose bg-gray-50 dark:bg-gray-800 rounded-lg p-4">
|
||||
<PackageManagerTabs v-model:manager="activeManager" @copy="copyCommand(commands[activeManager].dev)">
|
||||
<template #default="{ activeManager }">
|
||||
<div>
|
||||
<div
|
||||
v-if="activeManager === 'pnpm'"
|
||||
class="bg-gray-100 dark:bg-gray-900 p-2 rounded text-xs sm:text-sm overflow-x-auto">
|
||||
{{ commands.pnpm.dev }}
|
||||
</div>
|
||||
<div
|
||||
v-if="activeManager === 'bun'"
|
||||
class="bg-gray-100 dark:bg-gray-900 p-2 rounded text-xs sm:text-sm overflow-x-auto">
|
||||
{{ commands.bun.dev }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</PackageManagerTabs>
|
||||
</div>
|
||||
|
||||
<h3 class="text-base sm:text-lg font-medium mb-3">后续(可操作):打包项目</h3>
|
||||
<div class="not-prose bg-gray-50 dark:bg-gray-800 rounded-lg p-4">
|
||||
<PackageManagerTabs v-model:manager="activeManager" @copy="copyCommand(commands[activeManager].build)">
|
||||
<template #default="{ activeManager }">
|
||||
<div>
|
||||
<div
|
||||
v-if="activeManager === 'pnpm'"
|
||||
class="bg-gray-100 dark:bg-gray-900 p-2 rounded text-xs sm:text-sm overflow-x-auto">
|
||||
{{ commands.pnpm.build }}
|
||||
</div>
|
||||
<div
|
||||
v-if="activeManager === 'bun'"
|
||||
class="bg-gray-100 dark:bg-gray-900 p-2 rounded text-xs sm:text-sm overflow-x-auto">
|
||||
{{ commands.bun.build }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</PackageManagerTabs>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-8">
|
||||
<h2 class="text-xl sm:text-2xl font-semibold">为什么选择 HuLa?</h2>
|
||||
<p class="text-sm sm:text-base">
|
||||
HuLa 将现代 Web 开发的最佳实践与直观的开发体验相结合。无论你是构建小型应用还是大型项目,HuLa
|
||||
都能为你提供所需的工具和结构支持,助你取得成功。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
useSeoMeta({
|
||||
title: 'introduction · 介绍'
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
layout: 'custom'
|
||||
})
|
||||
|
||||
useSeoMeta({
|
||||
title: '产品介绍 · HuLa',
|
||||
description: '开始使用 HuLa - 用于构建高效、可扩展应用程序的现代 Web 开发框架'
|
||||
})
|
||||
|
||||
const activeManager = ref('pnpm')
|
||||
|
||||
const commands = {
|
||||
clone: {
|
||||
gitee: 'git clone https://gitee.com/HuLaSpark/HuLa',
|
||||
github: 'git clone https://github.com/HuLaSpark/HuLa'
|
||||
},
|
||||
directory: 'cd HuLa',
|
||||
pnpm: {
|
||||
install: 'pnpm install',
|
||||
dev: 'pnpm run tauri:dev',
|
||||
build: 'pnpm run tauri:build'
|
||||
},
|
||||
bun: {
|
||||
install: 'bun install',
|
||||
dev: 'bun tauri:dev',
|
||||
build: 'bun tauri:build'
|
||||
}
|
||||
} as any
|
||||
|
||||
const copyLink = (command: string) => {
|
||||
navigator.clipboard
|
||||
.writeText(command)
|
||||
.then(() => {
|
||||
console.log(`Copied: ${command}`)
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Failed to copy: ', err)
|
||||
})
|
||||
}
|
||||
|
||||
const copyCommand = (command: string) => {
|
||||
navigator.clipboard
|
||||
.writeText(command)
|
||||
.then(() => {
|
||||
console.log(`Copied: ${command}`)
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Failed to copy: ', err)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
557
pages/index.vue
557
pages/index.vue
@@ -1,310 +1,292 @@
|
||||
<template>
|
||||
<main class="min-h-[calc(100vh-var(--header-height))] relative bg-[#f8fafc] dark:bg-[#111729]">
|
||||
<img
|
||||
class="pointer-events-none absolute w-full top-[1px] text-teal flex-shrink-0 z-10"
|
||||
src="/assets/svg/header.svg"
|
||||
alt="" />
|
||||
|
||||
<PageBackground>
|
||||
<!-- 首页介绍 -->
|
||||
<div class="bg-[#f8fafc] dark:bg-[#111729] min-h-screen relative overflow-hidden">
|
||||
<div class="absolute inset-0">
|
||||
<div
|
||||
class="absolute inset-0 bg-gradient-to-b from-[#f8fafc] via-[#e2e8f0] to-[#f8fafc] dark:from-[#111729] dark:via-[#0c1322] dark:to-[#111729] opacity-60 dark:opacity-80"></div>
|
||||
<div
|
||||
class="absolute inset-0 bg-[url('/assets/svg/grid-light.svg')] dark:bg-[url('/assets/svg/grid.svg')] bg-center [mask-image:linear-gradient(180deg,white,rgba(255,255,255,0))]">
|
||||
<div class="photon-effect light-photon dark:dark-photon"></div>
|
||||
<div class="photon-effect light-photon dark:dark-photon delay-2"></div>
|
||||
<div class="photon-effect light-photon dark:dark-photon delay-4"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative pt-20 pb-16 sm:pb-24 lg:pb-32">
|
||||
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
<!-- Hero Section -->
|
||||
<div class="text-center relative z-[1]">
|
||||
<div class="mb-8 animate-fade-in">
|
||||
<NuxtLink to="https://github.com/HuLaSpark/HuLa" target="_blank" rel="noopener noreferrer">
|
||||
<span
|
||||
class="inline-flex items-center text-sm px-3 py-1.5 bg-teal-50 dark:bg-teal-400/10 text-teal-500 dark:text-teal-400 ring-1 ring-inset ring-teal-500/25 dark:ring-teal-400/25 rounded-full font-semibold transition hover:bg-teal-100 dark:hover:bg-teal-400/15">
|
||||
<span>HuLa {{ config.MasterVersion }} 现已发布</span>
|
||||
<UIcon name="solar:arrow-right-line-duotone" class="w-5 h-5 ml-1" />
|
||||
</span>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
|
||||
<div class="relative pt-20 pb-16 sm:pb-24 lg:pb-32">
|
||||
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
<!-- Hero Section -->
|
||||
<div class="text-center relative z-[1]">
|
||||
<div class="mb-8 animate-fade-in">
|
||||
<NuxtLink to="https://github.com/HuLaSpark/HuLa" target="_blank" rel="noopener noreferrer">
|
||||
<span
|
||||
class="inline-flex items-center text-sm px-3 py-1.5 bg-teal-50 dark:bg-teal-400/10 text-teal-500 dark:text-teal-400 ring-1 ring-inset ring-teal-500/25 dark:ring-teal-400/25 rounded-full font-semibold transition hover:bg-teal-100 dark:hover:bg-teal-400/15">
|
||||
<span>HuLa {{ config.MasterVersion }} 现已发布</span>
|
||||
<UIcon name="solar:arrow-right-line-duotone" class="w-5 h-5 ml-1" />
|
||||
</span>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<h1 class="text-4xl font-bold tracking-tight text-gray-900 dark:text-white sm:text-6xl lg:text-7xl mb-6">
|
||||
<span class="block">高度集成的</span>
|
||||
<span class="block mt-2 text-teal-600 dark:text-teal-500">IM 框架</span>
|
||||
</h1>
|
||||
|
||||
<h1 class="text-4xl font-bold tracking-tight text-gray-900 dark:text-white sm:text-6xl lg:text-7xl mb-6">
|
||||
<span class="block">高度集成的</span>
|
||||
<span class="block mt-2 text-teal-600 dark:text-teal-500">IM 框架</span>
|
||||
</h1>
|
||||
<p class="mx-auto max-w-2xl text-lg text-gray-600 dark:text-gray-300 leading-relaxed mb-2">
|
||||
HuLa 是一款
|
||||
<a
|
||||
href="https://github.com/HuLaSpark/HuLa"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-teal-600 dark:text-teal-400 hover:underline">
|
||||
开源的即时通讯应用程序
|
||||
</a>
|
||||
功能更全面和强大。
|
||||
</p>
|
||||
|
||||
<p class="mx-auto max-w-2xl text-lg text-gray-600 dark:text-gray-300 leading-relaxed mb-2">
|
||||
HuLa 是一款
|
||||
<a
|
||||
href="https://github.com/HuLaSpark/HuLa"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-teal-600 dark:text-teal-400 hover:underline">
|
||||
开源的即时通讯应用程序
|
||||
</a>
|
||||
功能更全面和强大。
|
||||
</p>
|
||||
<p class="mx-auto max-w-2xl text-lg text-gray-600 dark:text-gray-300 leading-relaxed">
|
||||
可集成更多应用插件,满足各种应用场景。
|
||||
</p>
|
||||
|
||||
<p class="mx-auto max-w-2xl text-lg text-gray-600 dark:text-gray-300 leading-relaxed">
|
||||
可集成更多应用插件,满足各种应用场景。
|
||||
</p>
|
||||
|
||||
<!-- CTA Buttons -->
|
||||
<div class="mt-10 flex flex-wrap items-center justify-center gap-6">
|
||||
<a
|
||||
href="/docs/getting-started/introduction"
|
||||
class="inline-flex items-center px-6 py-3 rounded-lg bg-teal-500 text-white hover:bg-teal-600 transition shadow-lg shadow-teal-500/20">
|
||||
<span class="font-medium">开始使用</span>
|
||||
<UIcon name="solar:arrow-right-linear" class="w-5 h-5 ml-2" />
|
||||
</a>
|
||||
<div v-if="!isMobile" class="hidden md:block">
|
||||
<!-- Mac下载按钮 -->
|
||||
<UPopover v-if="system === 'mac'" v-model:open="panelVisible" mode="hover">
|
||||
<div class="flex items-center gap-4">
|
||||
<div
|
||||
:class="{ 'text-teal-600': panelVisible }"
|
||||
class="group flex items-center gap-2 text-sm bg-[#fefefe] w-fit px-6 py-2 rounded-md dark:bg-gray-800">
|
||||
<svg class="size-6 group-hover:text-teal-600"><use href="#mac"></use></svg>
|
||||
<span class="group-hover:text-teal-600">MacOS</span>
|
||||
<UIcon
|
||||
name="solar:alt-arrow-down-line-duotone"
|
||||
:class="{ 'rotate-180': panelVisible }"
|
||||
class="w-4 h-4 group-hover:text-teal-600 group-hover:rotate-180" />
|
||||
</div>
|
||||
<!-- CTA Buttons -->
|
||||
<div class="mt-10 flex flex-wrap items-center justify-center gap-6">
|
||||
<a
|
||||
href="/docs/getting-started/introduction"
|
||||
class="inline-flex items-center px-6 py-3 rounded-lg bg-teal-500 text-white hover:bg-teal-600 transition shadow-lg shadow-teal-500/20">
|
||||
<span class="font-medium">开始使用</span>
|
||||
<UIcon name="solar:arrow-right-linear" class="w-5 h-5 ml-2" />
|
||||
</a>
|
||||
<div v-if="!isMobile" class="hidden md:block">
|
||||
<!-- Mac下载按钮 -->
|
||||
<UPopover v-if="system === 'mac'" v-model:open="panelVisible" mode="hover">
|
||||
<div class="flex items-center gap-4">
|
||||
<div
|
||||
:class="{ 'text-teal-600': panelVisible }"
|
||||
class="group flex items-center gap-2 text-sm bg-[#fefefe] w-fit px-6 py-2 rounded-md dark:bg-gray-800">
|
||||
<svg class="size-6 group-hover:text-teal-600"><use href="#mac"></use></svg>
|
||||
<span class="group-hover:text-teal-600">MacOS</span>
|
||||
<UIcon
|
||||
name="solar:alt-arrow-down-line-duotone"
|
||||
:class="{ 'rotate-180': panelVisible }"
|
||||
class="w-4 h-4 group-hover:text-teal-600 group-hover:rotate-180" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #panel>
|
||||
<div class="p-2 flex flex-col gap-2">
|
||||
<a
|
||||
v-for="(item, index) in macDownloads"
|
||||
:key="index"
|
||||
class="flex items-center gap-4 py-1 px-2 box-border rounded-md hover:bg-gray-100 hover:dark:bg-gray-800"
|
||||
rel="noopener noreferrer"
|
||||
:href="item.url">
|
||||
<svg class="size-4 flex-shrink-0"><use href="#to-bottom"></use></svg>
|
||||
<p class="text-end w-full">{{ item.label }}</p>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
</UPopover>
|
||||
|
||||
<!-- Windows下载按钮 -->
|
||||
<template v-if="system === 'windows'">
|
||||
<div class="flex items-center gap-4">
|
||||
<template #panel>
|
||||
<div class="p-2 flex flex-col gap-2">
|
||||
<a
|
||||
class="group flex items-center gap-2 text-sm bg-[#fefefe] w-fit px-6 py-2 rounded-md dark:bg-gray-800"
|
||||
v-for="(item, index) in macDownloads"
|
||||
:key="index"
|
||||
class="flex items-center gap-4 py-1 px-2 box-border rounded-md hover:bg-gray-100 hover:dark:bg-gray-800"
|
||||
rel="noopener noreferrer"
|
||||
:href="windowsDownload.url">
|
||||
<svg class="size-6 group-hover:text-teal-600"><use href="#windows"></use></svg>
|
||||
<span class="group-hover:text-teal-600">Windows</span>
|
||||
:href="item.url">
|
||||
<svg class="size-4 flex-shrink-0"><use href="#to-bottom"></use></svg>
|
||||
<p class="text-end w-full">{{ item.label }}</p>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div v-else class="text-center py-4 text-gray-500">移动端版本敬请期待</div>
|
||||
</UPopover>
|
||||
|
||||
<!-- Windows下载按钮 -->
|
||||
<template v-if="system === 'windows'">
|
||||
<div class="flex items-center gap-4">
|
||||
<a
|
||||
class="group flex items-center gap-2 text-sm bg-[#fefefe] w-fit px-6 py-2 rounded-md dark:bg-gray-800"
|
||||
rel="noopener noreferrer"
|
||||
:href="windowsDownload.url">
|
||||
<svg class="size-6 group-hover:text-teal-600"><use href="#windows"></use></svg>
|
||||
<span class="group-hover:text-teal-600">Windows</span>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div v-else class="text-center py-4 text-gray-500">移动端版本敬请期待</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Key Features -->
|
||||
<div class="mt-32 grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3">
|
||||
<div
|
||||
class="relative rounded-2xl border border-gray-200 dark:border-gray-800 p-8 hover:border-teal-500 dark:hover:border-teal-500 transition group">
|
||||
<div class="absolute -top-4 left-4">
|
||||
<span
|
||||
class="inline-flex items-center justify-center w-8 h-8 rounded-lg bg-teal-500 text-white transform group-hover:scale-110 transition">
|
||||
<UIcon name="solar:chat-dots-bold" class="w-5 h-5" />
|
||||
</span>
|
||||
</div>
|
||||
<h3
|
||||
class="mt-4 text-xl font-semibold text-gray-900 dark:text-white group-hover:text-teal-500 dark:group-hover:text-teal-400 transition">
|
||||
即时通讯
|
||||
</h3>
|
||||
<p class="mt-2 text-gray-600 dark:text-gray-400">
|
||||
支持文本、图片、语音等多种消息类型,实现流畅的即时通讯体验。基于 WebSocket
|
||||
的实时通信,确保消息的及时送达。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Key Features -->
|
||||
<div class="mt-32 grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3">
|
||||
<div
|
||||
class="relative rounded-2xl border border-gray-200 dark:border-gray-800 p-8 hover:border-teal-500 dark:hover:border-teal-500 transition group">
|
||||
<div class="absolute -top-4 left-4">
|
||||
<span
|
||||
class="inline-flex items-center justify-center w-8 h-8 rounded-lg bg-teal-500 text-white transform group-hover:scale-110 transition">
|
||||
<UIcon name="solar:chat-dots-bold" class="w-5 h-5" />
|
||||
</span>
|
||||
</div>
|
||||
<h3
|
||||
class="mt-4 text-xl font-semibold text-gray-900 dark:text-white group-hover:text-teal-500 dark:group-hover:text-teal-400 transition">
|
||||
即时通讯
|
||||
</h3>
|
||||
<p class="mt-2 text-gray-600 dark:text-gray-400">
|
||||
支持文本、图片、语音等多种消息类型,实现流畅的即时通讯体验。基于 WebSocket
|
||||
的实时通信,确保消息的及时送达。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="relative rounded-2xl border border-gray-200 dark:border-gray-800 p-8 hover:border-teal-500 dark:hover:border-teal-500 transition group">
|
||||
<div class="absolute -top-4 left-4">
|
||||
<span
|
||||
class="inline-flex items-center justify-center w-8 h-8 rounded-lg bg-teal-500 text-white transform group-hover:scale-110 transition">
|
||||
<UIcon name="solar:shield-keyhole-bold" class="w-5 h-5" />
|
||||
</span>
|
||||
</div>
|
||||
<h3
|
||||
class="mt-4 text-xl font-semibold text-gray-900 dark:text-white group-hover:text-teal-500 dark:group-hover:text-teal-400 transition">
|
||||
安全可靠
|
||||
</h3>
|
||||
<p class="mt-2 text-gray-600 dark:text-gray-400">
|
||||
采用端到端加密技术,确保用户隐私和数据安全。支持消息加密传输,保护您的通信内容不被窃取。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="relative rounded-2xl border border-gray-200 dark:border-gray-800 p-8 hover:border-teal-500 dark:hover:border-teal-500 transition group">
|
||||
<div class="absolute -top-4 left-4">
|
||||
<span
|
||||
class="inline-flex items-center justify-center w-8 h-8 rounded-lg bg-teal-500 text-white transform group-hover:scale-110 transition">
|
||||
<UIcon name="solar:code-square-bold" class="w-5 h-5" />
|
||||
</span>
|
||||
</div>
|
||||
<h3
|
||||
class="mt-4 text-xl font-semibold text-gray-900 dark:text-white group-hover:text-teal-500 dark:group-hover:text-teal-400 transition">
|
||||
开源生态
|
||||
</h3>
|
||||
<p class="mt-2 text-gray-600 dark:text-gray-400">
|
||||
完全开源,支持自定义开发和扩展,打造属于你的IM系统。提供丰富的API接口,方便与其他系统集成。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="relative rounded-2xl border border-gray-200 dark:border-gray-800 p-8 hover:border-teal-500 dark:hover:border-teal-500 transition group">
|
||||
<div class="absolute -top-4 left-4">
|
||||
<span
|
||||
class="inline-flex items-center justify-center w-8 h-8 rounded-lg bg-teal-500 text-white transform group-hover:scale-110 transition">
|
||||
<UIcon name="solar:widget-bold" class="w-5 h-5" />
|
||||
</span>
|
||||
</div>
|
||||
<h3
|
||||
class="mt-4 text-xl font-semibold text-gray-900 dark:text-white group-hover:text-teal-500 dark:group-hover:text-teal-400 transition">
|
||||
跨平台支持
|
||||
</h3>
|
||||
<p class="mt-2 text-gray-600 dark:text-gray-400">
|
||||
支持 Windows、MacOS 等多个平台,提供统一的用户体验。基于 Tauri 构建,确保应用性能和稳定性。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="relative rounded-2xl border border-gray-200 dark:border-gray-800 p-8 hover:border-teal-500 dark:hover:border-teal-500 transition group">
|
||||
<div class="absolute -top-4 left-4">
|
||||
<span
|
||||
class="inline-flex items-center justify-center w-8 h-8 rounded-lg bg-teal-500 text-white transform group-hover:scale-110 transition">
|
||||
<UIcon name="solar:user-plus-bold" class="w-5 h-5" />
|
||||
</span>
|
||||
</div>
|
||||
<h3
|
||||
class="mt-4 text-xl font-semibold text-gray-900 dark:text-white group-hover:text-teal-500 dark:group-hover:text-teal-400 transition">
|
||||
社区驱动
|
||||
</h3>
|
||||
<p class="mt-2 text-gray-600 dark:text-gray-400">
|
||||
活跃的开发者社区,持续提供功能更新和问题修复。欢迎参与项目开发,共同打造更好的即时通讯工具。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="relative rounded-2xl border border-gray-200 dark:border-gray-800 p-8 hover:border-teal-500 dark:hover:border-teal-500 transition group">
|
||||
<div class="absolute -top-4 left-4">
|
||||
<span
|
||||
class="inline-flex items-center justify-center w-8 h-8 rounded-lg bg-teal-500 text-white transform group-hover:scale-110 transition">
|
||||
<UIcon name="solar:settings-bold" class="w-5 h-5" />
|
||||
</span>
|
||||
</div>
|
||||
<h3
|
||||
class="mt-4 text-xl font-semibold text-gray-900 dark:text-white group-hover:text-teal-500 dark:group-hover:text-teal-400 transition">
|
||||
高度可定制
|
||||
</h3>
|
||||
<p class="mt-2 text-gray-600 dark:text-gray-400">
|
||||
提供丰富的配置选项,满足不同场景的需求。支持主题定制、插件扩展,打造个性化的通讯工具。
|
||||
</p>
|
||||
<div
|
||||
class="relative rounded-2xl border border-gray-200 dark:border-gray-800 p-8 hover:border-teal-500 dark:hover:border-teal-500 transition group">
|
||||
<div class="absolute -top-4 left-4">
|
||||
<span
|
||||
class="inline-flex items-center justify-center w-8 h-8 rounded-lg bg-teal-500 text-white transform group-hover:scale-110 transition">
|
||||
<UIcon name="solar:shield-keyhole-bold" class="w-5 h-5" />
|
||||
</span>
|
||||
</div>
|
||||
<h3
|
||||
class="mt-4 text-xl font-semibold text-gray-900 dark:text-white group-hover:text-teal-500 dark:group-hover:text-teal-400 transition">
|
||||
安全可靠
|
||||
</h3>
|
||||
<p class="mt-2 text-gray-600 dark:text-gray-400">
|
||||
采用端到端加密技术,确保用户隐私和数据安全。支持消息加密传输,保护您的通信内容不被窃取。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 图片 -->
|
||||
<div class="mt-32 w-full flex items-center justify-center" @click="toggleImage">
|
||||
<Transition name="fade" mode="out-in">
|
||||
<img
|
||||
v-if="showFirstImage"
|
||||
key="first"
|
||||
class="dark:hidden w-full max-w-5xl aspect-auto md:aspect-[5xl] select-none cursor-pointer"
|
||||
src="/assets/images/1.png"
|
||||
alt="" />
|
||||
<img
|
||||
v-else
|
||||
key="second"
|
||||
class="dark:hidden w-full max-w-5xl aspect-auto md:aspect-[5xl] select-none cursor-pointer"
|
||||
src="/assets/images/3.png"
|
||||
alt="" />
|
||||
</Transition>
|
||||
<Transition name="fade" mode="out-in">
|
||||
<img
|
||||
v-if="showFirstImage"
|
||||
key="first-dark"
|
||||
class="hidden dark:block w-full max-w-5xl aspect-auto md:aspect-[5xl] select-none cursor-pointer"
|
||||
src="/assets/images/2.png"
|
||||
alt="" />
|
||||
<img
|
||||
v-else
|
||||
key="second-dark"
|
||||
class="hidden dark:block w-full max-w-5xl aspect-auto md:aspect-[5xl] select-none cursor-pointer"
|
||||
src="/assets/images/4.png"
|
||||
alt="" />
|
||||
</Transition>
|
||||
<div
|
||||
class="relative rounded-2xl border border-gray-200 dark:border-gray-800 p-8 hover:border-teal-500 dark:hover:border-teal-500 transition group">
|
||||
<div class="absolute -top-4 left-4">
|
||||
<span
|
||||
class="inline-flex items-center justify-center w-8 h-8 rounded-lg bg-teal-500 text-white transform group-hover:scale-110 transition">
|
||||
<UIcon name="solar:code-square-bold" class="w-5 h-5" />
|
||||
</span>
|
||||
</div>
|
||||
<h3
|
||||
class="mt-4 text-xl font-semibold text-gray-900 dark:text-white group-hover:text-teal-500 dark:group-hover:text-teal-400 transition">
|
||||
开源生态
|
||||
</h3>
|
||||
<p class="mt-2 text-gray-600 dark:text-gray-400">
|
||||
完全开源,支持自定义开发和扩展,打造属于你的IM系统。提供丰富的API接口,方便与其他系统集成。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Technical Features -->
|
||||
<div class="mt-32 relative">
|
||||
<!-- Background glow effect -->
|
||||
<div
|
||||
class="relative rounded-2xl border border-gray-200 dark:border-gray-800 p-8 hover:border-teal-500 dark:hover:border-teal-500 transition group">
|
||||
<div class="absolute -top-4 left-4">
|
||||
<span
|
||||
class="inline-flex items-center justify-center w-8 h-8 rounded-lg bg-teal-500 text-white transform group-hover:scale-110 transition">
|
||||
<UIcon name="solar:widget-bold" class="w-5 h-5" />
|
||||
</span>
|
||||
</div>
|
||||
<h3
|
||||
class="mt-4 text-xl font-semibold text-gray-900 dark:text-white group-hover:text-teal-500 dark:group-hover:text-teal-400 transition">
|
||||
跨平台支持
|
||||
</h3>
|
||||
<p class="mt-2 text-gray-600 dark:text-gray-400">
|
||||
支持 Windows、MacOS 等多个平台,提供统一的用户体验。基于 Tauri 构建,确保应用性能和稳定性。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="relative rounded-2xl border border-gray-200 dark:border-gray-800 p-8 hover:border-teal-500 dark:hover:border-teal-500 transition group">
|
||||
<div class="absolute -top-4 left-4">
|
||||
<span
|
||||
class="inline-flex items-center justify-center w-8 h-8 rounded-lg bg-teal-500 text-white transform group-hover:scale-110 transition">
|
||||
<UIcon name="solar:user-plus-bold" class="w-5 h-5" />
|
||||
</span>
|
||||
</div>
|
||||
<h3
|
||||
class="mt-4 text-xl font-semibold text-gray-900 dark:text-white group-hover:text-teal-500 dark:group-hover:text-teal-400 transition">
|
||||
社区驱动
|
||||
</h3>
|
||||
<p class="mt-2 text-gray-600 dark:text-gray-400">
|
||||
活跃的开发者社区,持续提供功能更新和问题修复。欢迎参与项目开发,共同打造更好的即时通讯工具。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="relative rounded-2xl border border-gray-200 dark:border-gray-800 p-8 hover:border-teal-500 dark:hover:border-teal-500 transition group">
|
||||
<div class="absolute -top-4 left-4">
|
||||
<span
|
||||
class="inline-flex items-center justify-center w-8 h-8 rounded-lg bg-teal-500 text-white transform group-hover:scale-110 transition">
|
||||
<UIcon name="solar:settings-bold" class="w-5 h-5" />
|
||||
</span>
|
||||
</div>
|
||||
<h3
|
||||
class="mt-4 text-xl font-semibold text-gray-900 dark:text-white group-hover:text-teal-500 dark:group-hover:text-teal-400 transition">
|
||||
高度可定制
|
||||
</h3>
|
||||
<p class="mt-2 text-gray-600 dark:text-gray-400">
|
||||
提供丰富的配置选项,满足不同场景的需求。支持主题定制、插件扩展,打造个性化的通讯工具。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图片 -->
|
||||
<div class="mt-32 w-full flex items-center justify-center" @click="toggleImage">
|
||||
<Transition name="fade" mode="out-in">
|
||||
<img
|
||||
v-if="showFirstImage"
|
||||
key="first"
|
||||
class="dark:hidden w-full max-w-5xl aspect-auto md:aspect-[5xl] select-none cursor-pointer"
|
||||
src="/assets/images/1.png"
|
||||
alt="" />
|
||||
<img
|
||||
v-else
|
||||
key="second"
|
||||
class="dark:hidden w-full max-w-5xl aspect-auto md:aspect-[5xl] select-none cursor-pointer"
|
||||
src="/assets/images/3.png"
|
||||
alt="" />
|
||||
</Transition>
|
||||
<Transition name="fade" mode="out-in">
|
||||
<img
|
||||
v-if="showFirstImage"
|
||||
key="first-dark"
|
||||
class="hidden dark:block w-full max-w-5xl aspect-auto md:aspect-[5xl] select-none cursor-pointer"
|
||||
src="/assets/images/2.png"
|
||||
alt="" />
|
||||
<img
|
||||
v-else
|
||||
key="second-dark"
|
||||
class="hidden dark:block w-full max-w-5xl aspect-auto md:aspect-[5xl] select-none cursor-pointer"
|
||||
src="/assets/images/4.png"
|
||||
alt="" />
|
||||
</Transition>
|
||||
</div>
|
||||
|
||||
<!-- Technical Features -->
|
||||
<div class="mt-32 relative">
|
||||
<!-- Background glow effect -->
|
||||
<div
|
||||
class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[400px] pointer-events-none">
|
||||
<div
|
||||
class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[400px] pointer-events-none">
|
||||
<div
|
||||
class="absolute inset-0 bg-gradient-to-r from-teal-500/30 to-blue-500/30 blur-[64px] opacity-20 animate-pulse"></div>
|
||||
class="absolute inset-0 bg-gradient-to-r from-teal-500/30 to-blue-500/30 blur-[64px] opacity-20 animate-pulse"></div>
|
||||
</div>
|
||||
|
||||
<div class="text-center mb-16 relative">
|
||||
<h2 class="text-3xl font-bold text-gray-900 dark:text-white">技术特性</h2>
|
||||
<p class="mt-4 text-lg text-gray-600 dark:text-gray-400">基于现代化技术栈,提供强大的功能支持</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 relative">
|
||||
<div
|
||||
class="p-6 rounded-xl bg-white/50 dark:bg-gray-800/50 backdrop-blur-sm group hover:scale-[1.02] transition duration-300 hover:shadow-xl">
|
||||
<h3 class="text-xl font-semibold text-gray-900 dark:text-white mb-4 flex items-center">
|
||||
<UIcon name="solar:server-bold" class="w-6 h-6 mr-2 text-teal-500" />
|
||||
后端架构
|
||||
</h3>
|
||||
<ul class="space-y-3 text-gray-600 dark:text-gray-400">
|
||||
<li class="flex items-center">
|
||||
<UIcon name="solar:check-circle-bold" class="w-5 h-5 mr-2 text-teal-500" />
|
||||
基于 Spring Boot 的微服务架构
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<UIcon name="solar:check-circle-bold" class="w-5 h-5 mr-2 text-teal-500" />
|
||||
高性能的 WebSocket 服务
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<UIcon name="solar:check-circle-bold" class="w-5 h-5 mr-2 text-teal-500" />
|
||||
分布式消息队列支持
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="text-center mb-16 relative">
|
||||
<h2 class="text-3xl font-bold text-gray-900 dark:text-white">技术特性</h2>
|
||||
<p class="mt-4 text-lg text-gray-600 dark:text-gray-400">基于现代化技术栈,提供强大的功能支持</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 relative">
|
||||
<div
|
||||
class="p-6 rounded-xl bg-white/50 dark:bg-gray-800/50 backdrop-blur-sm group hover:scale-[1.02] transition duration-300 hover:shadow-xl">
|
||||
<h3 class="text-xl font-semibold text-gray-900 dark:text-white mb-4 flex items-center">
|
||||
<UIcon name="solar:server-bold" class="w-6 h-6 mr-2 text-teal-500" />
|
||||
后端架构
|
||||
</h3>
|
||||
<ul class="space-y-3 text-gray-600 dark:text-gray-400">
|
||||
<li class="flex items-center">
|
||||
<UIcon name="solar:check-circle-bold" class="w-5 h-5 mr-2 text-teal-500" />
|
||||
基于 Spring Boot 的微服务架构
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<UIcon name="solar:check-circle-bold" class="w-5 h-5 mr-2 text-teal-500" />
|
||||
高性能的 WebSocket 服务
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<UIcon name="solar:check-circle-bold" class="w-5 h-5 mr-2 text-teal-500" />
|
||||
分布式消息队列支持
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="p-6 rounded-xl bg-white/50 dark:bg-gray-800/50 backdrop-blur-sm group hover:scale-[1.02] transition duration-300 hover:shadow-xl">
|
||||
<h3 class="text-xl font-semibold text-gray-900 dark:text-white mb-4 flex items-center">
|
||||
<UIcon name="solar:screencast-2-bold" class="w-6 h-6 mr-2 text-teal-500" />
|
||||
客户端技术
|
||||
</h3>
|
||||
<ul class="space-y-3 text-gray-600 dark:text-gray-400">
|
||||
<li class="flex items-center">
|
||||
<UIcon name="solar:check-circle-bold" class="w-5 h-5 mr-2 text-teal-500" />
|
||||
Tauri + Vue3 + Typescript 构建
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<UIcon name="solar:check-circle-bold" class="w-5 h-5 mr-2 text-teal-500" />
|
||||
优雅的UI设计和交互体验
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<UIcon name="solar:check-circle-bold" class="w-5 h-5 mr-2 text-teal-500" />
|
||||
高效的消息处理机制
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
class="p-6 rounded-xl bg-white/50 dark:bg-gray-800/50 backdrop-blur-sm group hover:scale-[1.02] transition duration-300 hover:shadow-xl">
|
||||
<h3 class="text-xl font-semibold text-gray-900 dark:text-white mb-4 flex items-center">
|
||||
<UIcon name="solar:screencast-2-bold" class="w-6 h-6 mr-2 text-teal-500" />
|
||||
客户端技术
|
||||
</h3>
|
||||
<ul class="space-y-3 text-gray-600 dark:text-gray-400">
|
||||
<li class="flex items-center">
|
||||
<UIcon name="solar:check-circle-bold" class="w-5 h-5 mr-2 text-teal-500" />
|
||||
Tauri + Vue3 + Typescript 构建
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<UIcon name="solar:check-circle-bold" class="w-5 h-5 mr-2 text-teal-500" />
|
||||
优雅的UI设计和交互体验
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<UIcon name="solar:check-circle-bold" class="w-5 h-5 mr-2 text-teal-500" />
|
||||
高效的消息处理机制
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -438,8 +420,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Community Section -->
|
||||
<div class="mt-32 text-center px-4 sm:px-6">
|
||||
<!-- 社区部分 -->
|
||||
<div class="relative mt-32 text-center px-4 sm:px-6">
|
||||
<h2 class="text-2xl sm:text-3xl font-bold text-gray-900 dark:text-white">加入我们</h2>
|
||||
<p class="mt-4 text-base sm:text-lg text-gray-600 dark:text-gray-400 max-w-2xl mx-auto">
|
||||
HuLa
|
||||
@@ -464,7 +446,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 页脚部分 -->
|
||||
<footer class="mt-32 bg-[#f8fafc] dark:bg-gray-900 w-full">
|
||||
<footer class="relative mt-32 bg-[#f8fafc] dark:bg-gray-900 w-full">
|
||||
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-12">
|
||||
<!-- 联系方式 -->
|
||||
<div class="flex items-start gap-8 mb-8">
|
||||
@@ -526,7 +508,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</main>
|
||||
</PageBackground>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useUserSystem } from '~/hooks/useUserSystem'
|
||||
@@ -600,6 +582,7 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/** */
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.5s ease;
|
||||
|
||||
1
public/assets/svg/bun.svg
Normal file
1
public/assets/svg/bun.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="Bun" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 70"><title>Bun Logo</title><path id="Shadow" d="M71.09,20.74c-.16-.17-.33-.34-.5-.5s-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5A26.46,26.46,0,0,1,75.5,35.7c0,16.57-16.82,30.05-37.5,30.05-11.58,0-21.94-4.23-28.83-10.86l.5.5.5.5.5.5.5.5.5.5.5.5.5.5C19.55,65.3,30.14,69.75,42,69.75c20.68,0,37.5-13.48,37.5-30C79.5,32.69,76.46,26,71.09,20.74Z"/><g id="Body"><path id="Background" d="M73,35.7c0,15.21-15.67,27.54-35,27.54S3,50.91,3,35.7C3,26.27,9,17.94,18.22,13S33.18,3,38,3s8.94,4.13,19.78,10C67,17.94,73,26.27,73,35.7Z" style="fill:#fbf0df"/><path id="Bottom_Shadow" data-name="Bottom Shadow" d="M73,35.7a21.67,21.67,0,0,0-.8-5.78c-2.73,33.3-43.35,34.9-59.32,24.94A40,40,0,0,0,38,63.24C57.3,63.24,73,50.89,73,35.7Z" style="fill:#f6dece"/><path id="Light_Shine" data-name="Light Shine" d="M24.53,11.17C29,8.49,34.94,3.46,40.78,3.45A9.29,9.29,0,0,0,38,3c-2.42,0-5,1.25-8.25,3.13-1.13.66-2.3,1.39-3.54,2.15-2.33,1.44-5,3.07-8,4.7C8.69,18.13,3,26.62,3,35.7c0,.4,0,.8,0,1.19C9.06,15.48,20.07,13.85,24.53,11.17Z" style="fill:#fffefc"/><path id="Top" d="M35.12,5.53A16.41,16.41,0,0,1,29.49,18c-.28.25-.06.73.3.59,3.37-1.31,7.92-5.23,6-13.14C35.71,5,35.12,5.12,35.12,5.53Zm2.27,0A16.24,16.24,0,0,1,39,19c-.12.35.31.65.55.36C41.74,16.56,43.65,11,37.93,5,37.64,4.74,37.19,5.14,37.39,5.49Zm2.76-.17A16.42,16.42,0,0,1,47,17.12a.33.33,0,0,0,.65.11c.92-3.49.4-9.44-7.17-12.53C40.08,4.54,39.82,5.08,40.15,5.32ZM21.69,15.76a16.94,16.94,0,0,0,10.47-9c.18-.36.75-.22.66.18-1.73,8-7.52,9.67-11.12,9.45C21.32,16.4,21.33,15.87,21.69,15.76Z" style="fill:#ccbea7;fill-rule:evenodd"/><path id="Outline" d="M38,65.75C17.32,65.75.5,52.27.5,35.7c0-10,6.18-19.33,16.53-24.92,3-1.6,5.57-3.21,7.86-4.62,1.26-.78,2.45-1.51,3.6-2.19C32,1.89,35,.5,38,.5s5.62,1.2,8.9,3.14c1,.57,2,1.19,3.07,1.87,2.49,1.54,5.3,3.28,9,5.27C69.32,16.37,75.5,25.69,75.5,35.7,75.5,52.27,58.68,65.75,38,65.75ZM38,3c-2.42,0-5,1.25-8.25,3.13-1.13.66-2.3,1.39-3.54,2.15-2.33,1.44-5,3.07-8,4.7C8.69,18.13,3,26.62,3,35.7,3,50.89,18.7,63.25,38,63.25S73,50.89,73,35.7C73,26.62,67.31,18.13,57.78,13,54,11,51.05,9.12,48.66,7.64c-1.09-.67-2.09-1.29-3-1.84C42.63,4,40.42,3,38,3Z"/></g><g id="Mouth"><g id="Background-2" data-name="Background"><path d="M45.05,43a8.93,8.93,0,0,1-2.92,4.71,6.81,6.81,0,0,1-4,1.88A6.84,6.84,0,0,1,34,47.71,8.93,8.93,0,0,1,31.12,43a.72.72,0,0,1,.8-.81H44.26A.72.72,0,0,1,45.05,43Z" style="fill:#b71422"/></g><g id="Tongue"><path id="Background-3" data-name="Background" d="M34,47.79a6.91,6.91,0,0,0,4.12,1.9,6.91,6.91,0,0,0,4.11-1.9,10.63,10.63,0,0,0,1-1.07,6.83,6.83,0,0,0-4.9-2.31,6.15,6.15,0,0,0-5,2.78C33.56,47.4,33.76,47.6,34,47.79Z" style="fill:#ff6164"/><path id="Outline-2" data-name="Outline" d="M34.16,47a5.36,5.36,0,0,1,4.19-2.08,6,6,0,0,1,4,1.69c.23-.25.45-.51.66-.77a7,7,0,0,0-4.71-1.93,6.36,6.36,0,0,0-4.89,2.36A9.53,9.53,0,0,0,34.16,47Z"/></g><path id="Outline-3" data-name="Outline" d="M38.09,50.19a7.42,7.42,0,0,1-4.45-2,9.52,9.52,0,0,1-3.11-5.05,1.2,1.2,0,0,1,.26-1,1.41,1.41,0,0,1,1.13-.51H44.26a1.44,1.44,0,0,1,1.13.51,1.19,1.19,0,0,1,.25,1h0a9.52,9.52,0,0,1-3.11,5.05A7.42,7.42,0,0,1,38.09,50.19Zm-6.17-7.4c-.16,0-.2.07-.21.09a8.29,8.29,0,0,0,2.73,4.37A6.23,6.23,0,0,0,38.09,49a6.28,6.28,0,0,0,3.65-1.73,8.3,8.3,0,0,0,2.72-4.37.21.21,0,0,0-.2-.09Z"/></g><g id="Face"><ellipse id="Right_Blush" data-name="Right Blush" cx="53.22" cy="40.18" rx="5.85" ry="3.44" style="fill:#febbd0"/><ellipse id="Left_Bluch" data-name="Left Bluch" cx="22.95" cy="40.18" rx="5.85" ry="3.44" style="fill:#febbd0"/><path id="Eyes" d="M25.7,38.8a5.51,5.51,0,1,0-5.5-5.51A5.51,5.51,0,0,0,25.7,38.8Zm24.77,0A5.51,5.51,0,1,0,45,33.29,5.5,5.5,0,0,0,50.47,38.8Z" style="fill-rule:evenodd"/><path id="Iris" d="M24,33.64a2.07,2.07,0,1,0-2.06-2.07A2.07,2.07,0,0,0,24,33.64Zm24.77,0a2.07,2.07,0,1,0-2.06-2.07A2.07,2.07,0,0,0,48.75,33.64Z" style="fill:#fff;fill-rule:evenodd"/></g></svg>
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
1
public/assets/svg/npm.svg
Normal file
1
public/assets/svg/npm.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill="#cb3837" d="M2 38.5h124v43.71H64v7.29H36.44v-7.29H2zm6.89 36.43h13.78V53.07h6.89v21.86h6.89V45.79H8.89zm34.44-29.14v36.42h13.78v-7.28h13.78V45.79zm13.78 7.29H64v14.56h-6.89zm20.67-7.29v29.14h13.78V53.07h6.89v21.86h6.89V53.07h6.89v21.86h6.89V45.79z"/></svg>
|
||||
|
After Width: | Height: | Size: 330 B |
1
public/assets/svg/pnpm.svg
Normal file
1
public/assets/svg/pnpm.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill="#f8ab00" d="M0 .004V40h39.996V.004Zm43.996 0V40h40V.004Zm44.008 0V40H128V.004Zm0 43.996v39.996H128V44Z"/><path fill="#4c4c4c" d="M43.996 44v39.996h40V44ZM0 87.996v40h39.996v-40Zm43.996 0v40h40v-40Zm44.008 0v40H128v-40Z"/></svg>
|
||||
|
After Width: | Height: | Size: 302 B |
1
public/assets/svg/yarn.svg
Normal file
1
public/assets/svg/yarn.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"> <path fill="#2c8ebb" d="M64 0a64 64 0 1 0 64 64A64 64 0 0 0 64 0Zm4.685 21.948a5.037 5.037 0 0 1 2.21.802c.671.444 1.528 1.032 4.026 6.194a4.841 4.841 0 0 1 2.942-.103 3.933 3.933 0 0 1 2.468 2.004c2.55 4.893 2.889 13.614 1.774 19.22a34.89 34.89 0 0 1-6.028 13.74 26.56 26.56 0 0 1 5.957 9.733 26.24 26.24 0 0 1 1.456 10.746 29.626 29.626 0 0 0 3.22-1.796c3.158-1.951 7.927-4.894 13.615-4.966a6.834 6.834 0 0 1 7.225 5.885 6.555 6.555 0 0 1-5.046 7.256c-3.458.836-5.069 1.486-9.714 4.5a69.161 69.161 0 0 1-16.062 7.412 8.991 8.991 0 0 1-3.758 1.828c-3.933.96-17.425 1.682-18.488 1.682h-.248c-4.13 0-6.47-1.28-7.73-2.621-3.51 1.755-8.052 1.03-11.355-.714a5.729 5.729 0 0 1-3.097-4.024 6.194 6.194 0 0 1 0-2.127 6.875 6.875 0 0 1-.816-1.032 16.908 16.908 0 0 1-2.333-10.386c.3-3.85 2.964-7.287 4.698-9.114A29.481 29.481 0 0 1 35.726 64a27.685 27.685 0 0 1 7.04-9.29c-1.703-2.87-3.436-7.288-1.754-11.789 1.208-3.21 2.199-4.996 4.377-5.76a7.06 7.06 0 0 0 2.59-1.383 18.22 18.22 0 0 1 12.243-5.843c.196-.495.423-1.033.671-1.508 1.652-3.51 3.406-5.48 5.46-6.193a5.037 5.037 0 0 1 2.332-.286zm-.558 3.697c-2.703.089-5.355 8.099-5.355 8.099a14.452 14.452 0 0 0-12.089 4.645 9.951 9.951 0 0 1-3.973 2.345c-.424.144-.94.122-2.22 3.58-1.961 5.234 3.345 11.16 3.345 11.16s-6.328 4.47-8.672 10.034a25.58 25.58 0 0 0-1.806 12.057s-4.5 3.901-4.788 7.927a13.285 13.285 0 0 0 1.826 8.083 2.003 2.003 0 0 0 2.714.94s-2.993 3.487-.196 4.963c2.55 1.331 6.844 2.065 9.115-.196 1.652-1.651 1.982-5.335 2.591-6.842.144-.351.64.588 1.115 1.032a10.323 10.323 0 0 0 1.403 1.032s-4.024 1.734-2.373 5.688c.547 1.31 2.498 2.145 5.688 2.125 1.187 0 14.203-.743 17.671-1.58a4.47 4.47 0 0 0 2.696-1.505 65.032 65.032 0 0 0 15.99-7.226c4.892-3.19 6.895-4.059 10.848-4.998 3.262-.774 3.045-5.83-1.28-5.758-4.48.052-8.402 2.363-11.716 4.427-6.193 3.83-9.29 3.583-9.29 3.583l-.105-.175c-.423-.692 1.983-6.896-.712-14.287-2.91-8.082-7.534-10.033-7.163-10.653 1.58-2.673 5.534-6.917 7.113-14.824.94-4.79.691-12.676-1.435-16.805-.393-.764-3.902 1.28-3.902 1.28s-3.283-7.319-4.201-7.907a1.442 1.442 0 0 0-.839-.244z" /> </svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
Reference in New Issue
Block a user