Compare commits

...

8 Commits

Author SHA1 Message Date
f2d0bbf36b Merge remote-tracking branch 'origin/main' into develop
Some checks failed
site-dist-deploy / build-and-deploy (push) Has been cancelled
2026-01-04 21:42:51 -08:00
97c2832e89 下载 2026-01-04 21:18:14 -08:00
9d43162830 下载 2026-01-04 21:04:03 -08:00
530df9ce09 增加客服 2026-01-04 05:07:26 -08:00
9f2264514d 增加隐私协议和政策 2026-01-04 04:41:07 -08:00
57d7b49aa9 增加隐私协议和政策 2026-01-04 04:37:45 -08:00
8e7434f67c 增加隐私协议和政策 2026-01-04 04:28:58 -08:00
d8e29af1dc 增加教程样式 2026-01-04 01:38:25 -08:00
50 changed files with 303 additions and 70 deletions

View File

@ -21,6 +21,7 @@
"axios": "^1.13.2",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"crisp-sdk-web": "^1.0.27",
"crypto-js": "^4.2.0",
"lucide-vue-next": "^0.562.0",
"reka-ui": "^2.7.0",

8
pnpm-lock.yaml generated
View File

@ -23,6 +23,9 @@ importers:
clsx:
specifier: ^2.1.1
version: 2.1.1
crisp-sdk-web:
specifier: ^1.0.27
version: 1.0.27
crypto-js:
specifier: ^4.2.0
version: 4.2.0
@ -1048,6 +1051,9 @@ packages:
resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==}
engines: {node: '>=18'}
crisp-sdk-web@1.0.27:
resolution: {integrity: sha512-aNWR3te65YiaVFu/iwdqOo3cyUBZHUheE4d6EtgQu/T18jh/9SpoYXjXF/OzUD3Cqy0pGryoqtuy5gxD8tqX9Q==}
cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
@ -3047,6 +3053,8 @@ snapshots:
dependencies:
is-what: 5.5.0
crisp-sdk-web@1.0.27: {}
cross-spawn@7.0.6:
dependencies:
path-key: 3.1.1

View File

@ -1,9 +1,3 @@
<script setup lang="ts">
import { RouterView } from 'vue-router'
import 'vue-sonner/style.css'
import { Toaster } from '@/components/ui/sonner'
</script>
<template>
<div>
<main>
@ -22,4 +16,33 @@ import { Toaster } from '@/components/ui/sonner'
</div>
</template>
<script setup lang="ts">
import { RouterView } from 'vue-router'
import { onMounted } from 'vue'
import 'vue-sonner/style.css'
import { Toaster } from '@/components/ui/sonner'
import { Crisp } from 'crisp-sdk-web'
const WEBSITE_ID = '47fcc1ac-9674-4ab1-9e3c-6b5666f59a38'
onMounted(() => {
//
const loadCrisp = () => {
console.log('页面资源已就绪,开始初始化 Crisp...')
Crisp.configure(WEBSITE_ID)
//
// Crisp.chat.hide();
}
//
if (document.readyState === 'complete') {
loadCrisp()
} else {
// window load CSS
window.addEventListener('load', loadCrisp, { once: true })
}
})
</script>
<style scoped></style>

View File

@ -1,15 +1,15 @@
<template>
<div class="font-sans text-white">
<div class="flex flex-col gap-5">
<div class="flex flex-col gap-[10px]">
<div
v-for="item in downloadMethods"
:key="item.id"
@click="toggle(item.id)"
class="group relative flex cursor-pointer flex-col rounded-[30px] border-[4px] border-white bg-black pt-4 pb-2 transition-all active:scale-[0.97] md:pb-6"
class="group relative flex cursor-pointer flex-col rounded-[30px] border-[4px] border-white bg-black pt-4 pb-2 transition-all md:pb-6"
>
<div class="px-4 md:px-[42px]">
<div class="px-4 md:pl-[42px]">
<div
class="flex flex-wrap items-center gap-x-2 text-sm leading-tight font-bold md:text-4xl"
class="flex flex-wrap items-center gap-x-2 text-sm leading-tight font-bold md:text-2xl"
>
<StartIcon v-if="item.isHot" class="size-[20px] md:size-[30px]" />
<span>{{ item.title }}</span>
@ -23,11 +23,14 @@
<!-- 打开按钮 -->
<div
class="mt-2 flex items-center justify-end gap-1.5 self-end text-sm font-bold group-hover:opacity-100"
class="flex items-center justify-end gap-1.5 self-end text-sm font-bold group-hover:opacity-100"
>
<div v-show="activeId !== item.id" class="flex items-center gap-[10px] md:text-2xl">
<div
v-show="activeId !== item.id"
class="mt-[16px] flex items-center gap-[10px] md:mt-[60px] md:text-xl"
>
<span class="tracking-tight">点击展开详情</span>
<ArrowIcon class="size-[12px] md:size-[22px]" />
<ArrowIcon class="size-[12px] md:size-[18px]" />
</div>
</div>
</div>
@ -36,30 +39,68 @@
<div
class="animate-in fade-in zoom-in-95 border-t-2 border-white pt-[10px] text-[15px] leading-relaxed duration-200 md:pt-[20px]"
>
<!-- 收起按钮 (仅保留底部悬浮或单一按钮此处移除上方重复项) -->
<div class="relative px-2">
<!-- 内容区域 (点击图片不收起只有特定的关闭按钮收起) -->
<div class="relative px-2" @click.stop>
<div
class="flex items-center justify-end gap-1.5 self-end text-sm font-bold group-hover:opacity-100 md:text-2xl"
class="flex items-center justify-end gap-1.5 self-end text-sm font-bold group-hover:opacity-100 md:text-xl"
>
<div class="flex items-center gap-[10px]">
<div class="relative z-10 flex items-center gap-[10px]" @click="toggle(item.id)">
<span class="tracking-tight">点击收起</span>
<ArrowIcon class="size-[12px] rotate-180 md:size-[22px]" />
</div>
</div>
<img :src="item.mobileSrc" class="-mt-10 w-full md:hidden" alt="mobile guide" />
<img :src="item.pcSrc" class="-mt-10 hidden w-full md:block" alt="pc guide" />
<!-- 底部收起按钮 -->
<div class="absolute right-4 bottom-4">
<!-- Mobile Image Stack -->
<div class="relative -mt-10 flex flex-col md:hidden">
<img
v-for="(img, idx) in item.mobileImages"
:key="idx"
:src="img"
class="w-full"
alt="mobile guide"
/>
<!-- Mobile Hot Zones -->
<div
class="flex items-center justify-end gap-1.5 text-sm font-bold group-hover:opacity-100 md:text-2xl"
>
<div
class="flex items-center gap-[10px] rounded-full bg-black/40 px-3 py-1 backdrop-blur-sm transition-all hover:bg-black/60"
>
<span class="tracking-tight">点击收起</span>
<ArrowIcon class="size-[12px] rotate-180 md:size-[22px]" />
</div>
</div>
v-for="(hz, hzIdx) in item.mobileHotzones"
:key="hzIdx"
class="absolute z-20 cursor-pointer"
:style="{
left: hz.x + '%',
top: hz.y + '%',
width: hz.w + '%',
height: hz.h + '%',
}"
@click="handleHotzone(hz)"
></div>
</div>
<!-- PC Image Stack -->
<div class="relative mt-4 hidden flex-col md:flex">
<img
v-for="(img, idx) in item.pcImages"
:key="idx"
:src="img"
class="w-full"
alt="pc guide"
/>
<!-- PC Hot Zones -->
<div
v-for="(hz, hzIdx) in item.pcHotzones"
:key="hzIdx"
class="absolute z-20 cursor-pointer"
:style="{
left: hz.x + '%',
top: hz.y + '%',
width: hz.w + '%',
height: hz.h + '%',
}"
@click="handleHotzone(hz)"
></div>
</div>
<!-- 底部收起按钮 -->
<div class="absolute right-4 bottom-4 z-10">
<div @click="toggle(item.id)" class="h-[30px] w-[200px]"></div>
</div>
</div>
</div>
@ -73,13 +114,42 @@
import { ref } from 'vue'
import ArrowIcon from './arrow-icon.svg?component'
import StartIcon from './Star-1.svg?component'
import { toast } from 'vue-sonner'
import mobile1 from './mobile1.png'
import mobile2 from './mobile2.png'
import mobile3 from './mobile3.png'
import pc1 from './pc-1.png'
import pc2 from './pc-2.png'
import pc3 from './pc-3.png'
// Sliced WebP Images
// Method 1
import m1_1 from './mobile1/row-1-column-1.webp'
import m1_2 from './mobile1/row-2-column-1.webp'
import m1_3 from './mobile1/row-3-column-1.webp'
import pc1_1 from './pc1/row-1-column-1.webp'
import pc1_2 from './pc1/row-2-column-1.webp'
import pc1_3 from './pc1/row-3-column-1.webp'
// Method 2
import m2_1 from './mobile2/row-1-column-1.webp'
import m2_2 from './mobile2/row-2-column-1.webp'
import m2_3 from './mobile2/row-3-column-1.webp'
import pc2_1 from './pc2/row-1-column-1.webp'
import pc2_2 from './pc2/row-2-column-1.webp'
import pc2_3 from './pc2/row-3-column-1.webp'
// Method 3
import m3_1 from './mobile3/row-1-column-1.webp'
import m3_2 from './mobile3/row-2-column-1.webp'
import m3_3 from './mobile3/row-3-column-1.webp'
import pc3_1 from './pc3/row-1-column-1.webp'
import pc3_2 from './pc3/row-2-column-1.webp'
import pc3_3 from './pc3/row-3-column-1.webp'
interface Hotzone {
x: number //
y: number //
w: number //
h: number //
type: 'copy' | 'link'
payload: string
label?: string
}
//
const downloadMethods = ref([
@ -89,8 +159,10 @@ const downloadMethods = ref([
subtitle: '首推',
isHot: true,
highlight: '',
mobileSrc: mobile1,
pcSrc: pc1,
mobileImages: [m1_1, m1_2, m1_3],
pcImages: [pc1_1, pc1_2, pc1_3],
mobileHotzones: [] as Hotzone[],
pcHotzones: [] as Hotzone[],
},
{
id: 2,
@ -98,8 +170,10 @@ const downloadMethods = ref([
subtitle: '',
isHot: false,
highlight: '',
mobileSrc: mobile2,
pcSrc: pc2,
mobileImages: [m2_1, m2_2, m2_3],
pcImages: [pc2_1, pc2_2, pc2_3],
mobileHotzones: [] as Hotzone[],
pcHotzones: [] as Hotzone[],
},
{
id: 3,
@ -107,8 +181,10 @@ const downloadMethods = ref([
subtitle: '',
isHot: false,
highlight: '谨慎选择',
mobileSrc: mobile3,
pcSrc: pc3,
mobileImages: [m3_1, m3_2, m3_3],
pcImages: [pc3_1, pc3_2, pc3_3],
mobileHotzones: [] as Hotzone[],
pcHotzones: [] as Hotzone[],
},
])
@ -117,6 +193,15 @@ const activeId = ref<number | null>(null)
const toggle = (id: number) => {
activeId.value = activeId.value === id ? null : id
}
const handleHotzone = (hz: Hotzone) => {
if (hz.type === 'copy') {
navigator.clipboard.writeText(hz.payload)
toast.success(`${hz.label || '内容'}已复制`)
} else if (hz.type === 'link') {
window.open(hz.payload, '_blank')
}
}
</script>
<style scoped>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 276 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 311 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 305 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 358 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 418 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

View File

@ -1,50 +1,48 @@
<template>
<div class="min-h-screen bg-black text-white">
<!-- Full Width Header -->
<div class="h-[88px] md:h-[125px]">
<div class="fixed z-50 w-full bg-black pt-[20px] md:pt-[45px]">
<div class="h-[88px] md:h-[94px]">
<div class="fixed z-50 w-full bg-black pt-[20px] md:pt-[34px]">
<div class="container">
<header
class="flex h-[68px] items-center justify-between rounded-full bg-[#ADFF5B] pr-[30px] pl-6 md:h-[80px] md:pr-[58px] md:pl-[41px]"
class="flex h-[68px] items-center justify-between rounded-full bg-[#ADFF5B] pr-[30px] pl-6 md:h-[60px] md:pr-[58px] md:pl-[41px]"
>
<router-link to="/" class="flex items-center gap-2">
<!-- Desktop Logo -->
<!-- <Logo :src="Logo" alt="Hi快VPN" class="hidden h-10 w-auto text-black md:block" />-->
<!-- Mobile Logo -->
<MobileLogo alt="Hi快VPN" class="block h-[28px] text-black md:h-[50px]" />
<MobileLogo alt="Hi快VPN" class="block h-[28px] text-black md:h-[36px]" />
</router-link>
<RightText class="block h-[15px] text-black md:h-[31px]" />
<RightText class="block h-[15px] text-black md:h-[24px]" />
</header>
</div>
</div>
</div>
<div class="h-[145px] md:h-[262px]">
<div class="h-[125px] md:h-[180px]">
<div class="fixed z-50 w-full bg-black">
<div class="container pb-[10px] md:px-[12vw]">
<div
class="pt-[34px] pb-[15px] text-center text-xl font-[900] md:pt-[110px] md:pb-[30px] md:text-3xl"
>
<div class="m-auto w-[340px] pb-[10px] md:w-[760px]">
<div class="pt-[30px] pb-[15px] text-center text-xl font-[900] md:pb-[30px] md:text-2xl">
请选择适用您情形的选项
</div>
<div class="flex items-center justify-between">
<div
class="w-1/2 rounded-full border-5 p-[6px] p-[10px] md:border-[10px]"
class="w-1/2 rounded-full border-5 p-[6px] md:border-[10px] md:p-[10px]"
:class="[activeIndex === 0 ? 'border-white' : 'border-black']"
@click="activeIndex = 0"
>
<Button
class="w-full cursor-pointer rounded-full bg-[#ADFF5B] text-xs text-black hover:bg-[#ADFF5B]/90 md:h-[60px] md:text-2xl"
class="h-[30px] w-full cursor-pointer rounded-full bg-[#ADFF5B] text-xs text-black hover:bg-[#ADFF5B]/90 md:h-[40px] md:text-xl"
>
我只有中国大陆Apple ID
</Button>
</div>
<div
class="w-1/2 rounded-full border-5 p-[6px] p-[10px] md:border-[10px]"
class="w-1/2 rounded-full border-5 p-[6px] md:border-[10px] md:p-[10px]"
:class="[activeIndex === 1 ? 'border-white' : 'border-black']"
@click="activeIndex = 1"
>
<Button
class="w-full cursor-pointer rounded-full bg-[#ADFF5B] text-xs text-black hover:bg-[#ADFF5B]/90 md:h-[60px] md:text-2xl"
class="h-[30px] w-full cursor-pointer rounded-full bg-[#ADFF5B] text-xs text-black hover:bg-[#ADFF5B]/90 md:h-[40px] md:text-xl"
>
我有海外Apple ID
</Button>
@ -54,13 +52,11 @@
</div>
</div>
<div class="container md:px-[12vw]">
<div class="m-auto w-[340px] md:w-[760px]">
<Transition name="fade" mode="out-in">
<!-- tab1 -->
<div v-if="activeIndex === 0" key="tab1">
<div
class="pt-[34px] pb-[15px] text-center text-xl font-[900] md:pt-[100px] md:pb-[39px] md:text-3xl"
>
<div class="pt-[15px] pb-[15px] text-center text-xl font-[900] md:pb-[39px] md:text-2xl">
Hi快提供三种下载方式
</div>
<DownloadMethodList />
@ -68,7 +64,7 @@
<!-- tab2 -->
<div v-else-if="activeIndex === 1" key="tab2">
<div
class="mx-auto flex w-[237px] items-center justify-center pt-[34px] pb-[15px] text-center text-xl font-[900] md:w-full md:gap-[18px] md:pt-[100px] md:text-3xl"
class="mx-auto flex w-[237px] items-center justify-center pt-[34px] text-center text-xl font-[900] md:w-full md:gap-[18px] md:text-2xl"
>
<ChatIcon class="h-[60px] w-[50px]" />登录海外 Apple ID 后再点击下方下载按钮
</div>
@ -86,7 +82,7 @@
</div>
<div class="container md:px-[92px]">
<div class="pt-[56px] pb-[15px] text-center text-xl font-[900] md:pb-[69px] md:text-3xl">
<div class="pt-[56px] pb-[15px] text-center text-xl font-[900] md:text-2xl">
常见问题与解答
</div>
<div class="px-[24px]">

View File

@ -4,7 +4,7 @@
<router-link
v-if="item.isInternal"
:to="item.link"
class="flex h-[40px] w-[140px] shrink-0 items-center space-x-2 rounded-full transition-transform active:scale-95 md:h-[50px] md:w-[180px]"
class="flex h-[40px] w-[140px] shrink-0 items-center space-x-2 rounded-full transition-transform hover:brightness-110 active:scale-95 md:h-[50px] md:w-[180px]"
style="
backdrop-filter: blur(36px);
box-shadow:
@ -29,7 +29,7 @@
v-else
:href="item.link"
target="_blank"
class="flex h-[40px] w-[140px] shrink-0 items-center space-x-2 rounded-full transition-transform active:scale-95 md:h-[50px] md:w-[180px]"
class="flex h-[40px] w-[140px] shrink-0 items-center space-x-2 rounded-full transition-transform hover:brightness-110 active:scale-95 md:h-[50px] md:w-[180px]"
style="
backdrop-filter: blur(36px);
box-shadow:

View File

@ -41,7 +41,7 @@
<button
v-else
@click="openLoginModal"
class="flex h-[48px] items-center justify-center rounded-full bg-[#78788029] px-6 text-sm font-bold backdrop-blur-md transition hover:scale-[0.97] hover:bg-white/30 md:h-[60px] md:w-[220px] md:text-2xl"
class="flex h-[48px] cursor-pointer items-center justify-center rounded-full bg-[#78788029] px-6 text-sm font-bold backdrop-blur-md transition hover:brightness-110 md:h-[60px] md:w-[220px] md:text-2xl"
>
登录 / 注册
</button>
@ -96,14 +96,14 @@
class="mb-5 w-full text-center text-xs leading-5 font-[300] md:ml-[17px] md:text-left md:text-sm"
>
<p>最新加密协议-安全有保障</p>
<p>EPL专线-纯净稳定</p>
<p>IEPL专线-纯净稳定</p>
<p>不限速/不限流-网速多快Hi快多快</p>
<p>极速闪连-永远快人一步</p>
<div class="flex justify-center md:justify-start">
<a
href="https://x.com/hifasttech"
target="_blank"
class="mt-[12px] flex h-[30px] w-[100px] shrink-0 items-center justify-center space-x-2 rounded-full transition-transform active:scale-95 md:mt-[16px]"
class="mt-[12px] flex h-[30px] w-[100px] shrink-0 items-center justify-center space-x-2 rounded-full transition-transform hover:brightness-110 md:mt-[16px]"
style="
backdrop-filter: blur(36px);
box-shadow:
@ -132,8 +132,8 @@
</div>
<div class="text-center text-[10px] leading-[14px] font-[300] md:ml-[17px] md:text-left">
<span class="font-[600]">Hi快VPN</span> &copy; All rights reserved.<br />
<a href="#" class="underline">Terms of Service</a>
<a href="#" class="ml-2 underline">Privacy Policy</a>
<router-link to="/terms-of-service" class="underline">Terms of Service</router-link>
<router-link to="/privacy-policy" class="ml-2 underline">Privacy Policy</router-link>
</div>
</div>
@ -174,7 +174,7 @@ import DownloadButton from './components/DownloadButton.vue'
import Logo from './logo.svg?component'
import MobileLogo from './mobile-logo.svg?component'
import ScreenshotMobile from './screenshot-mobile.png'
import ScreenshotDesktop from './screenshot-desktop.png'
import ScreenshotDesktop from './screenshot-desktop.webp'
import request from '@/utils/request'
const route = useRoute()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

View File

@ -0,0 +1,53 @@
<template>
<div class="min-h-screen bg-black text-white" style="font-family: 'Roboto', sans-serif">
<!-- Main Content -->
<main class="mx-auto max-w-[1000px] px-6 md:px-2 md:pt-16 md:pb-[50px]">
<!-- Mobile Images -->
<div class="md:hidden">
<img
src="./mobile/row-1-column-1.webp"
alt="Terms of Service - Part 1"
class="mb-0 w-full"
/>
<img
src="./mobile/row-2-column-1.webp"
alt="Terms of Service - Part 2"
class="mb-0 w-full"
/>
<img
src="./mobile/row-3-column-1.webp"
alt="Terms of Service - Part 3"
class="mb-0 w-full"
/>
</div>
<!-- Desktop Images (2x) -->
<div class="hidden md:block">
<img
src="./pc/row1.png"
alt="Terms of Service - Part 1"
class="mb-10 origin-left scale-50"
/>
<img
src="./pc/row2.png"
alt="Terms of Service - Part 2"
class="mb-0 w-full"
style="width: 100%; height: auto"
/>
<img
src="./pc/row3.png"
alt="Terms of Service - Part 3"
class="m-auto mt-[60px] h-[28px] w-[594px]"
/>
</div>
</main>
</div>
</template>
<script setup lang="ts">
// No additional logic needed for this static page
</script>
<style scoped>
/* No additional styles needed */
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -0,0 +1,49 @@
<template>
<div class="min-h-screen bg-black text-white" style="font-family: 'Roboto', sans-serif">
<!-- Main Content -->
<main class="mx-auto max-w-[1000px] px-6 md:px-2 md:pt-16 md:pb-[50px]">
<!-- Mobile Images -->
<div class="md:hidden">
<img
src="./mobile/row-1-column-1.webp"
alt="Terms of Service - Part 1"
class="mb-0 w-full"
/>
<img
src="./mobile/row-2-column-1.webp"
alt="Terms of Service - Part 2"
class="mb-0 w-full"
/>
<img
src="./mobile/row-3-column-1.webp"
alt="Terms of Service - Part 3"
class="mb-0 w-full"
/>
</div>
<!-- Desktop Images (2x) -->
<div class="hidden md:block">
<img src="./pc/row1.png" alt="Terms of Service - Part 1" class="mb-10 h-[18px] w-[206px]" />
<img
src="./pc/row2.png"
alt="Terms of Service - Part 2"
class="mb-0 w-full"
style="width: 100%; height: auto"
/>
<img
src="./pc/row3.png"
alt="Terms of Service - Part 3"
class="m-auto mt-[60px] h-[70px] w-[693px]"
/>
</div>
</main>
</div>
</template>
<script setup lang="ts">
// No additional logic needed for this static page
</script>
<style scoped>
/* No additional styles needed */
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -18,6 +18,16 @@ const router = createRouter({
name: 'user-center',
component: () => import('../pages/UserCenter/index.vue'),
},
{
path: '/terms-of-service',
name: 'terms-of-service',
component: () => import('../pages/TermsOfService/index.vue'),
},
{
path: '/privacy-policy',
name: 'privacy-policy',
component: () => import('../pages/PrivacyPolicy/index.vue'),
},
],
})

View File

@ -1,3 +1,11 @@
@font-face {
font-family: 'Roboto';
src: url('/src/styles/roboto.woff2') format('woff2');
font-weight: 100 900;
font-style: normal;
font-display: swap;
}
@import "tailwindcss";
@import "tw-animate-css";
@layer utilities {

BIN
src/styles/roboto.woff2 Normal file

Binary file not shown.