feat: 新增作品和动态详情页

 Work 详情页 (/work/[slug]):
- Hero 大图 + 渐变遮罩
- 项目概述、挑战、解决方案
- 项目截图画廊
- 右侧信息卡片(客户、年份、周期、服务)
- 访问项目按钮
- 相关项目推荐
- 返回列表按钮
- 完整中英文内容

 News 详情页 (/news/[slug]):
- Hero 大图 + 渐变遮罩
- 分类标签 + 日期 + 阅读时间 + 作者
- 文章正文(多段落 + 引用 + 图片)
- 分享按钮(Twitter、LinkedIn、复制链接)
- 相关文章推荐
- 返回列表按钮
- 完整中英文内容

🔧 列表页更新:
- work.vue → work/index.vue
- news.vue → news/index.vue
- 卡片链接改为 NuxtLink 到详情页

🌍 国际化:
- 6 个作品详情(中文 + 英文)
- 6 篇文章详情(中文 + 英文)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
陈春
2026-06-03 20:35:02 +08:00
parent 05f2e56ff3
commit 3d68f56a94
6 changed files with 811 additions and 163 deletions
+236
View File
@@ -0,0 +1,236 @@
<template>
<main class="min-h-screen">
<!-- 返回按钮 -->
<div class="fixed top-28 left-4 md:left-8 z-30">
<NuxtLink
to="/news"
class="inline-flex items-center gap-2 px-4 py-2.5 rounded-full bg-white/90 backdrop-blur-sm shadow-lg hover:shadow-xl transition-all duration-300 text-sm font-semibold text-black hover:-translate-x-1"
>
<Icon name="ph:arrow-left" class="w-5 h-5" />
{{ t('news.backToList') }}
</NuxtLink>
</div>
<!-- 文章 Hero -->
<section class="relative h-[50vh] md:h-[60vh] overflow-hidden">
<img
:src="article.image"
:alt="article.title"
class="w-full h-full object-cover"
/>
<div class="absolute inset-0 bg-gradient-to-t from-black/80 via-black/40 to-transparent"></div>
<div class="absolute bottom-0 left-0 right-0 p-8 md:p-16">
<div class="max-w-[800px] mx-auto">
<span
class="inline-block px-3 py-1.5 text-xs md:text-sm font-semibold rounded-full mb-4"
:class="article.badge"
>
{{ article.category }}
</span>
<h1 class="text-3xl md:text-5xl lg:text-6xl font-bold text-white mb-4 tracking-tight">
{{ article.title }}
</h1>
<div class="flex items-center gap-4 text-white/80 text-sm md:text-base">
<span class="flex items-center gap-1.5">
<Icon name="ph:calendar-blank" class="w-4 h-4" />
{{ article.date }}
</span>
<span class="flex items-center gap-1.5">
<Icon name="ph:clock" class="w-4 h-4" />
{{ article.readTime }}
</span>
<span class="flex items-center gap-1.5">
<Icon name="ph:user" class="w-4 h-4" />
{{ article.author }}
</span>
</div>
</div>
</div>
</section>
<!-- 文章内容 -->
<section class="max-w-[800px] mx-auto px-6 md:px-10 py-16 md:py-24">
<article class="prose prose-lg max-w-none">
<p class="text-gray-700 text-lg leading-relaxed mb-8">
{{ t(`news.detail.items.${slug}.content`) }}
</p>
<h2 class="text-2xl md:text-3xl font-bold text-black mb-6 mt-12">
{{ t(`news.detail.items.${slug}.section1Title`) }}
</h2>
<p class="text-gray-700 text-lg leading-relaxed mb-8">
{{ t(`news.detail.items.${slug}.section1Content`) }}
</p>
<!-- 引用 -->
<blockquote class="border-l-4 border-black pl-6 my-10 italic text-gray-600 text-lg">
"{{ t(`news.detail.items.${slug}.quote`) }}"
</blockquote>
<h2 class="text-2xl md:text-3xl font-bold text-black mb-6 mt-12">
{{ t(`news.detail.items.${slug}.section2Title`) }}
</h2>
<p class="text-gray-700 text-lg leading-relaxed mb-8">
{{ t(`news.detail.items.${slug}.section2Content`) }}
</p>
<!-- 文章内图片 -->
<div class="my-10 rounded-2xl overflow-hidden">
<img :src="article.image" :alt="article.title" class="w-full h-auto" />
</div>
<h2 class="text-2xl md:text-3xl font-bold text-black mb-6 mt-12">
{{ t(`news.detail.items.${slug}.section3Title`) }}
</h2>
<p class="text-gray-700 text-lg leading-relaxed mb-8">
{{ t(`news.detail.items.${slug}.section3Content`) }}
</p>
</article>
<!-- 分享按钮 -->
<div class="mt-16 pt-8 border-t border-gray-200">
<div class="flex items-center justify-between">
<p class="text-sm text-gray-500">{{ t('news.detail.shareArticle') }}</p>
<div class="flex gap-3">
<button class="w-10 h-10 rounded-full bg-gray-100 hover:bg-black hover:text-white flex items-center justify-center transition-all duration-300">
<Icon name="ph:x-logo" class="w-5 h-5" />
</button>
<button class="w-10 h-10 rounded-full bg-gray-100 hover:bg-black hover:text-white flex items-center justify-center transition-all duration-300">
<Icon name="ph:linkedin-logo" class="w-5 h-5" />
</button>
<button class="w-10 h-10 rounded-full bg-gray-100 hover:bg-black hover:text-white flex items-center justify-center transition-all duration-300">
<Icon name="ph:link" class="w-5 h-5" />
</button>
</div>
</div>
</div>
</section>
<!-- 相关文章 -->
<section class="bg-gray-50 py-16 md:py-24">
<div class="max-w-[1200px] mx-auto px-6 md:px-10">
<h2 class="text-2xl md:text-3xl font-bold text-black mb-10 text-center">{{ t('news.detail.relatedArticles') }}</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<NuxtLink
v-for="related in relatedArticles"
:key="related.id"
:to="`/news/${related.id}`"
class="group block rounded-2xl overflow-hidden bg-white shadow-lg hover:shadow-xl transition-all duration-300 hover:-translate-y-1"
>
<div class="relative aspect-[16/10] overflow-hidden">
<img :src="related.image" :alt="related.title" class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105" />
</div>
<div class="p-5">
<span class="text-xs text-gray-500">{{ related.date }}</span>
<h3 class="text-lg font-bold text-black group-hover:text-gray-600 transition-colors mt-1 line-clamp-2">
{{ related.title }}
</h3>
</div>
</NuxtLink>
</div>
</div>
</section>
</main>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useRoute } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { useSeoMeta, createError } from '#imports'
const { t } = useI18n()
const route = useRoute()
const slug = route.params.slug as string
interface NewsItem {
id: string
title: string
image: string
category: string
badge: string
date: string
readTime: string
author: string
}
const newsData: Record<string, NewsItem> = {
'design-trends-2026': {
id: 'design-trends-2026',
title: 'Design Trends Shaping 2026',
image: 'https://picsum.photos/id/1/1200/800',
category: 'Insights',
badge: 'bg-purple-100 text-purple-700',
date: 'May 28, 2026',
readTime: '5 min',
author: 'ArcticNewOne Team'
},
'forma-digital-launch': {
id: 'forma-digital-launch',
title: 'Forma Digital Platform Launch',
image: 'https://picsum.photos/id/201/1200/800',
category: 'Projects',
badge: 'bg-blue-100 text-blue-700',
date: 'May 15, 2026',
readTime: '3 min',
author: 'ArcticNewOne Team'
},
'studio-expansion': {
id: 'studio-expansion',
title: 'Studio Expansion Announcement',
image: 'https://picsum.photos/id/164/1200/800',
category: 'Announcements',
badge: 'bg-green-100 text-green-700',
date: 'May 10, 2026',
readTime: '2 min',
author: 'ArcticNewOne Team'
},
'ux-research-methods': {
id: 'ux-research-methods',
title: 'Modern UX Research Methods',
image: 'https://picsum.photos/id/180/1200/800',
category: 'Insights',
badge: 'bg-purple-100 text-purple-700',
date: 'Apr 28, 2026',
readTime: '7 min',
author: 'ArcticNewOne Team'
},
'bold-moves-case-study': {
id: 'bold-moves-case-study',
title: 'Bold Moves: A Case Study',
image: 'https://picsum.photos/id/119/1200/800',
category: 'Projects',
badge: 'bg-blue-100 text-blue-700',
date: 'Apr 20, 2026',
readTime: '6 min',
author: 'ArcticNewOne Team'
},
'new-tools-integration': {
id: 'new-tools-integration',
title: 'New Tools Added to Our Platform',
image: 'https://picsum.photos/id/326/1200/800',
category: 'Announcements',
badge: 'bg-green-100 text-green-700',
date: 'Apr 12, 2026',
readTime: '4 min',
author: 'ArcticNewOne Team'
}
}
const article = newsData[slug]
if (!article) {
throw createError({ statusCode: 404, statusMessage: 'Article not found' })
}
const relatedArticles = computed(() => {
return Object.values(newsData)
.filter(a => a.id !== slug)
.slice(0, 3)
})
useSeoMeta({
title: () => `${article.title} - ${t('news.title')}`,
description: () => article.title,
})
</script>
+19 -82
View File
@@ -3,7 +3,6 @@
<div
ref="headerWrapRef"
class="flex flex-col items-center justify-center text-center mb-10 md:mb-16"
style="opacity: 0; visibility: hidden;"
>
<h1 ref="titleRef" class="text-3xl md:text-5xl font-bold mb-4 md:mb-6 tracking-tight text-black">{{ t('news.title') }}</h1>
<p ref="descRef" class="text-base md:text-lg text-gray-600 max-w-2xl">{{ t('news.description') }}</p>
@@ -12,7 +11,6 @@
<div
ref="filterWrapRef"
class="flex justify-center gap-3 md:gap-4 mb-10 md:mb-14 flex-wrap"
style="opacity: 0; visibility: hidden;"
>
<button
v-for="category in categories"
@@ -30,11 +28,11 @@
<div
ref="articlesWrapRef"
class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 md:gap-8"
style="opacity: 0; visibility: hidden;"
>
<article
<NuxtLink
v-for="article in filteredNewsData"
:key="article.id"
:to="`/news/${article.id}`"
class="news-card group relative flex flex-col rounded-2xl md:rounded-3xl overflow-hidden bg-white border border-gray-100 hover:shadow-xl transition-all duration-500 cursor-pointer hover:-translate-y-2"
>
<div class="relative aspect-[16/10] overflow-hidden bg-gray-100">
@@ -82,13 +80,13 @@
</div>
</div>
</div>
</article>
</NuxtLink>
</div>
</main>
</template>
<script setup lang="ts">
import { nextTick, onBeforeUnmount, onMounted, ref, computed } from 'vue'
import { nextTick, onMounted, ref, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useSeoMeta } from '#imports'
import gsap from 'gsap'
@@ -103,11 +101,9 @@ const descRef = ref<HTMLElement | null>(null)
const filterWrapRef = ref<HTMLElement | null>(null)
const articlesWrapRef = ref<HTMLElement | null>(null)
const activeCategory = ref('all')
let articlesCtx: gsap.Context | null = null
const categories = ['all', 'insights', 'projects', 'announcements']
//
const filteredNewsData = computed(() => {
if (activeCategory.value === 'all') {
return newsData
@@ -124,74 +120,24 @@ const playPageIntro = async () => {
await nextTick()
if (!headerWrapRef.value || !titleRef.value || !descRef.value || !filterWrapRef.value || !articlesWrapRef.value) return
articlesCtx?.revert()
articlesCtx = gsap.context(() => {
const filterButtons = gsap.utils.toArray<HTMLElement>('button', filterWrapRef.value!)
const newsCards = gsap.utils.toArray<HTMLElement>('.news-card', articlesWrapRef.value!)
gsap.delayedCall(0, () => {
requestAnimationFrame(() => {
requestAnimationFrame(() => {
const tl = gsap.timeline({ defaults: { ease: 'power3.out' } })
tl.set(headerWrapRef.value!, { autoAlpha: 1 })
tl.fromTo(titleRef.value!, { autoAlpha: 0, y: 20 }, { autoAlpha: 1, y: 0, duration: 0.85, ease: 'power4.out', clearProps: 'transform' })
tl.fromTo(descRef.value!, { autoAlpha: 0, y: 16 }, { autoAlpha: 1, y: 0, duration: 0.7, ease: 'power4.out', clearProps: 'transform' }, '-=0.45')
tl.fromTo(titleRef.value, { autoAlpha: 0, y: 20 }, { autoAlpha: 1, y: 0, duration: 0.85, ease: 'power4.out', clearProps: 'transform' })
tl.fromTo(descRef.value, { autoAlpha: 0, y: 16 }, { autoAlpha: 1, y: 0, duration: 0.7, ease: 'power4.out', clearProps: 'transform' }, '-=0.45')
tl.set(filterWrapRef.value!, { autoAlpha: 1 }, '-=0.2')
tl.fromTo(
filterButtons,
{ autoAlpha: 0, y: 20 },
{
autoAlpha: 1,
y: 0,
duration: 0.7,
ease: 'power4.out',
stagger: { each: 0.08, from: 'start' },
clearProps: 'transform',
},
'-=0.3'
)
const filterButtons = gsap.utils.toArray<HTMLElement>('button', filterWrapRef.value!)
tl.fromTo(filterButtons, { autoAlpha: 0, y: 20 }, { autoAlpha: 1, y: 0, duration: 0.7, stagger: 0.08, clearProps: 'transform' }, '-=0.3')
tl.set(articlesWrapRef.value!, { autoAlpha: 1 }, '-=0.05')
tl.fromTo(
newsCards,
{ autoAlpha: 0, y: 34, scale: 0.965 },
{
autoAlpha: 1,
y: 0,
scale: 1,
duration: 0.95,
ease: 'power4.out',
stagger: { each: 0.11, from: 'start' },
clearProps: 'transform',
},
'+=0.08'
)
tl.set([headerWrapRef.value!, filterWrapRef.value!, articlesWrapRef.value!], { clearProps: 'opacity,visibility' })
})
})
})
}, headerWrapRef.value)
const newsCards = gsap.utils.toArray<HTMLElement>('.news-card', articlesWrapRef.value!)
tl.fromTo(newsCards, { autoAlpha: 0, y: 34, scale: 0.965 }, { autoAlpha: 1, y: 0, scale: 1, duration: 0.95, stagger: 0.11, clearProps: 'transform' }, '+=0.08')
}
onMounted(() => {
const handleLoadingDone = () => {
playPageIntro()
}
if (!appStore.isAppLoading) {
playPageIntro()
return
} else {
window.addEventListener('app-loading-done', playPageIntro, { once: true })
}
window.addEventListener('app-loading-done', handleLoadingDone, { once: true })
})
onBeforeUnmount(() => {
articlesCtx?.revert()
})
interface NewsItem {
@@ -203,7 +149,6 @@ interface NewsItem {
badge: string
date: string
readTime: string
url: string
}
const newsData: NewsItem[] = [
@@ -215,8 +160,7 @@ const newsData: NewsItem[] = [
category: 'Insights',
badge: 'bg-purple-100 text-purple-700',
date: 'May 28, 2026',
readTime: '5 min',
url: '#'
readTime: '5 min'
},
{
id: 'forma-digital-launch',
@@ -226,8 +170,7 @@ const newsData: NewsItem[] = [
category: 'Projects',
badge: 'bg-blue-100 text-blue-700',
date: 'May 15, 2026',
readTime: '3 min',
url: '#'
readTime: '3 min'
},
{
id: 'studio-expansion',
@@ -237,8 +180,7 @@ const newsData: NewsItem[] = [
category: 'Announcements',
badge: 'bg-green-100 text-green-700',
date: 'May 10, 2026',
readTime: '2 min',
url: '#'
readTime: '2 min'
},
{
id: 'ux-research-methods',
@@ -248,8 +190,7 @@ const newsData: NewsItem[] = [
category: 'Insights',
badge: 'bg-purple-100 text-purple-700',
date: 'Apr 28, 2026',
readTime: '7 min',
url: '#'
readTime: '7 min'
},
{
id: 'bold-moves-case-study',
@@ -259,8 +200,7 @@ const newsData: NewsItem[] = [
category: 'Projects',
badge: 'bg-blue-100 text-blue-700',
date: 'Apr 20, 2026',
readTime: '6 min',
url: '#'
readTime: '6 min'
},
{
id: 'new-tools-integration',
@@ -270,14 +210,11 @@ const newsData: NewsItem[] = [
category: 'Announcements',
badge: 'bg-green-100 text-green-700',
date: 'Apr 12, 2026',
readTime: '4 min',
url: '#'
readTime: '4 min'
}
]
</script>
<style scoped>
p {
word-break: break-word;
}
p { word-break: break-word; }
</style>
+289
View File
@@ -0,0 +1,289 @@
<template>
<main class="min-h-screen">
<!-- 返回按钮 -->
<div class="fixed top-28 left-4 md:left-8 z-30">
<NuxtLink
to="/work"
class="inline-flex items-center gap-2 px-4 py-2.5 rounded-full bg-white/90 backdrop-blur-sm shadow-lg hover:shadow-xl transition-all duration-300 text-sm font-semibold text-black hover:-translate-x-1"
>
<Icon name="ph:arrow-left" class="w-5 h-5" />
{{ t('work.backToList') }}
</NuxtLink>
</div>
<!-- Hero 大图 -->
<section class="relative h-[60vh] md:h-[70vh] overflow-hidden">
<img
:src="project.image"
:alt="project.title"
class="w-full h-full object-cover"
/>
<div class="absolute inset-0 bg-gradient-to-t from-black/80 via-black/40 to-transparent"></div>
<div class="absolute bottom-0 left-0 right-0 p-8 md:p-16">
<div class="max-w-[1200px] mx-auto">
<div class="flex flex-wrap gap-2 mb-4">
<span
v-for="tag in project.tags"
:key="tag"
class="px-3 py-1 text-xs md:text-sm bg-white/20 backdrop-blur-sm text-white rounded-full"
>
{{ tag }}
</span>
</div>
<h1 class="text-4xl md:text-6xl lg:text-7xl font-bold text-white mb-4 tracking-tight">
{{ project.title }}
</h1>
<p class="text-lg md:text-xl text-white/80 max-w-2xl">
{{ project.description }}
</p>
</div>
</div>
</section>
<!-- 项目信息 -->
<section class="max-w-[1200px] mx-auto px-6 md:px-10 py-16 md:py-24">
<div class="grid grid-cols-1 lg:grid-cols-3 gap-12 lg:gap-16">
<!-- 左侧项目详情 -->
<div class="lg:col-span-2 space-y-12">
<div>
<h2 class="text-2xl md:text-3xl font-bold text-black mb-6">{{ t('work.detail.overview') }}</h2>
<p class="text-gray-700 text-base md:text-lg leading-relaxed">
{{ t(`work.detail.items.${slug}.overview`) }}
</p>
</div>
<div>
<h2 class="text-2xl md:text-3xl font-bold text-black mb-6">{{ t('work.detail.challenge') }}</h2>
<p class="text-gray-700 text-base md:text-lg leading-relaxed">
{{ t(`work.detail.items.${slug}.challenge`) }}
</p>
</div>
<div>
<h2 class="text-2xl md:text-3xl font-bold text-black mb-6">{{ t('work.detail.solution') }}</h2>
<p class="text-gray-700 text-base md:text-lg leading-relaxed">
{{ t(`work.detail.items.${slug}.solution`) }}
</p>
</div>
<!-- 项目截图 -->
<div class="space-y-6">
<h2 class="text-2xl md:text-3xl font-bold text-black">{{ t('work.detail.gallery') }}</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div
v-for="(img, index) in project.gallery"
:key="index"
class="rounded-2xl overflow-hidden shadow-lg hover:shadow-2xl transition-shadow duration-300"
>
<img :src="img" :alt="`${project.title} screenshot ${index + 1}`" class="w-full h-auto" />
</div>
</div>
</div>
</div>
<!-- 右侧项目信息卡片 -->
<div class="space-y-8">
<div class="bg-gray-50 rounded-2xl p-6 md:p-8 sticky top-32">
<h3 class="text-lg font-bold text-black mb-6">{{ t('work.detail.projectInfo') }}</h3>
<div class="space-y-5">
<div>
<p class="text-sm text-gray-500 mb-1">{{ t('work.detail.client') }}</p>
<p class="text-base font-semibold text-black">{{ t(`work.detail.items.${slug}.client`) }}</p>
</div>
<div>
<p class="text-sm text-gray-500 mb-1">{{ t('work.detail.year') }}</p>
<p class="text-base font-semibold text-black">{{ project.year }}</p>
</div>
<div>
<p class="text-sm text-gray-500 mb-1">{{ t('work.detail.duration') }}</p>
<p class="text-base font-semibold text-black">{{ t(`work.detail.items.${slug}.duration`) }}</p>
</div>
<div>
<p class="text-sm text-gray-500 mb-1">{{ t('work.detail.services') }}</p>
<div class="flex flex-wrap gap-2 mt-2">
<span
v-for="tag in project.tags"
:key="tag"
class="px-3 py-1 text-xs bg-black text-white rounded-full"
>
{{ tag }}
</span>
</div>
</div>
</div>
<!-- 访问项目按钮 -->
<a
v-if="project.url"
:href="project.url"
target="_blank"
rel="noopener noreferrer"
class="mt-8 w-full inline-flex items-center justify-center gap-2 px-6 py-3.5 rounded-full bg-black text-white font-semibold hover:bg-gray-800 transition-colors duration-300"
>
{{ t('work.detail.visitProject') }}
<Icon name="ph:arrow-up-right" class="w-5 h-5" />
</a>
</div>
</div>
</div>
</section>
<!-- 相关项目 -->
<section class="bg-gray-50 py-16 md:py-24">
<div class="max-w-[1200px] mx-auto px-6 md:px-10">
<h2 class="text-2xl md:text-3xl font-bold text-black mb-10 text-center">{{ t('work.detail.relatedProjects') }}</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<NuxtLink
v-for="related in relatedProjects"
:key="related.id"
:to="`/work/${related.id}`"
class="group block rounded-2xl overflow-hidden bg-white shadow-lg hover:shadow-xl transition-all duration-300 hover:-translate-y-1"
>
<div class="relative aspect-[4/3] overflow-hidden">
<img :src="related.image" :alt="related.title" class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105" />
</div>
<div class="p-5">
<h3 class="text-lg font-bold text-black group-hover:text-gray-600 transition-colors">{{ related.title }}</h3>
<p class="text-sm text-gray-500 mt-1">{{ related.tags[0] }}</p>
</div>
</NuxtLink>
</div>
</div>
</section>
</main>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useRoute } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { useSeoMeta, createError } from '#imports'
const { t } = useI18n()
const route = useRoute()
const slug = route.params.slug as string
interface WorkItem {
id: string
title: string
description: string
image: string
tags: string[]
category: string
year: string
url?: string
gallery: string[]
}
const workData: Record<string, WorkItem> = {
'forma-digital': {
id: 'forma-digital',
title: 'Forma Digital',
description: 'A modern e-commerce platform with seamless user experience and dynamic product showcases.',
image: 'https://picsum.photos/id/201/1200/800',
tags: ['Web Design', 'E-commerce', 'React'],
category: 'webDesign',
year: '2026',
url: '#',
gallery: [
'https://picsum.photos/id/201/800/600',
'https://picsum.photos/id/202/800/600',
'https://picsum.photos/id/203/800/600',
'https://picsum.photos/id/204/800/600',
]
},
'one-step': {
id: 'one-step',
title: 'One Step',
description: 'Brand identity and marketing campaign for a fitness app focused on sustainable habits.',
image: 'https://picsum.photos/id/180/1200/800',
tags: ['Branding', 'Marketing', 'UI/UX'],
category: 'branding',
year: '2024',
gallery: [
'https://picsum.photos/id/180/800/600',
'https://picsum.photos/id/181/800/600',
'https://picsum.photos/id/182/800/600',
'https://picsum.photos/id/183/800/600',
]
},
'nero-vision': {
id: 'nero-vision',
title: 'Nero Vision',
description: 'Full-stack web application for creative professionals to manage their portfolios.',
image: 'https://picsum.photos/id/119/1200/800',
tags: ['Development', 'Vue.js', 'Node.js'],
category: 'development',
year: '2025',
gallery: [
'https://picsum.photos/id/119/800/600',
'https://picsum.photos/id/120/800/600',
'https://picsum.photos/id/121/800/600',
'https://picsum.photos/id/122/800/600',
]
},
'bold-moves': {
id: 'bold-moves',
title: 'Bold Moves',
description: 'Interactive website showcasing innovative architectural designs with 3D visualizations.',
image: 'https://picsum.photos/id/164/1200/800',
tags: ['Web Design', '3D', 'Three.js'],
category: 'webDesign',
year: '2024',
gallery: [
'https://picsum.photos/id/164/800/600',
'https://picsum.photos/id/165/800/600',
'https://picsum.photos/id/166/800/600',
'https://picsum.photos/id/167/800/600',
]
},
'echo-labs': {
id: 'echo-labs',
title: 'Echo Labs',
description: 'Corporate branding and visual identity for a tech startup in the AI space.',
image: 'https://picsum.photos/id/101/1200/800',
tags: ['Branding', 'Visual Identity', 'Corporate'],
category: 'branding',
year: '2025',
gallery: [
'https://picsum.photos/id/101/800/600',
'https://picsum.photos/id/102/800/600',
'https://picsum.photos/id/103/800/600',
'https://picsum.photos/id/104/800/600',
]
},
'flux-api': {
id: 'flux-api',
title: 'Flux API',
description: 'Scalable REST API with comprehensive documentation and developer tools.',
image: 'https://picsum.photos/id/326/1200/800',
tags: ['Development', 'API', 'Python'],
category: 'development',
year: '2025',
gallery: [
'https://picsum.photos/id/326/800/600',
'https://picsum.photos/id/327/800/600',
'https://picsum.photos/id/328/800/600',
'https://picsum.photos/id/329/800/600',
]
}
}
const project = workData[slug]
if (!project) {
throw createError({ statusCode: 404, statusMessage: 'Project not found' })
}
const relatedProjects = computed(() => {
return Object.values(workData)
.filter(p => p.id !== slug)
.slice(0, 3)
})
useSeoMeta({
title: () => `${project.title} - ${t('work.title')}`,
description: () => project.description,
})
</script>
+13 -77
View File
@@ -3,7 +3,6 @@
<div
ref="headerWrapRef"
class="flex flex-col items-center justify-center text-center mb-10 md:mb-16"
style="opacity: 0; visibility: hidden;"
>
<h1 ref="titleRef" class="text-3xl md:text-5xl font-bold mb-4 md:mb-6 tracking-tight text-black">{{ t('work.title') }}</h1>
<p ref="descRef" class="text-base md:text-lg text-gray-600 max-w-2xl">{{ t('work.description') }}</p>
@@ -12,7 +11,6 @@
<div
ref="filterWrapRef"
class="flex justify-center gap-3 md:gap-4 mb-10 md:mb-14 flex-wrap"
style="opacity: 0; visibility: hidden;"
>
<button
v-for="category in categories"
@@ -30,12 +28,11 @@
<div
ref="projectsWrapRef"
class="grid grid-cols-1 md:grid-cols-2 gap-6 md:gap-8"
style="opacity: 0; visibility: hidden;"
>
<a
<NuxtLink
v-for="project in filteredWorkData"
:key="project.id"
:href="project.url"
:to="`/work/${project.id}`"
class="work-card group relative block rounded-2xl md:rounded-3xl overflow-hidden cursor-pointer hover:shadow-2xl transition-all duration-500"
>
<div class="relative aspect-[4/3] overflow-hidden bg-gray-100">
@@ -65,13 +62,13 @@
</span>
</div>
</div>
</a>
</NuxtLink>
</div>
</main>
</template>
<script setup lang="ts">
import { nextTick, onBeforeUnmount, onMounted, ref, computed } from 'vue'
import { nextTick, onMounted, ref, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useSeoMeta } from '#imports'
import gsap from 'gsap'
@@ -86,11 +83,9 @@ const descRef = ref<HTMLElement | null>(null)
const filterWrapRef = ref<HTMLElement | null>(null)
const projectsWrapRef = ref<HTMLElement | null>(null)
const activeCategory = ref('all')
let projectsCtx: gsap.Context | null = null
const categories = ['all', 'webDesign', 'branding', 'development']
//
const filteredWorkData = computed(() => {
if (activeCategory.value === 'all') {
return workData
@@ -107,74 +102,24 @@ const playPageIntro = async () => {
await nextTick()
if (!headerWrapRef.value || !titleRef.value || !descRef.value || !filterWrapRef.value || !projectsWrapRef.value) return
projectsCtx?.revert()
projectsCtx = gsap.context(() => {
const filterButtons = gsap.utils.toArray<HTMLElement>('button', filterWrapRef.value!)
const projectCards = gsap.utils.toArray<HTMLElement>('.work-card', projectsWrapRef.value!)
gsap.delayedCall(0, () => {
requestAnimationFrame(() => {
requestAnimationFrame(() => {
const tl = gsap.timeline({ defaults: { ease: 'power3.out' } })
tl.set(headerWrapRef.value!, { autoAlpha: 1 })
tl.fromTo(titleRef.value!, { autoAlpha: 0, y: 20 }, { autoAlpha: 1, y: 0, duration: 0.85, ease: 'power4.out', clearProps: 'transform' })
tl.fromTo(descRef.value!, { autoAlpha: 0, y: 16 }, { autoAlpha: 1, y: 0, duration: 0.7, ease: 'power4.out', clearProps: 'transform' }, '-=0.45')
tl.fromTo(titleRef.value, { autoAlpha: 0, y: 20 }, { autoAlpha: 1, y: 0, duration: 0.85, ease: 'power4.out', clearProps: 'transform' })
tl.fromTo(descRef.value, { autoAlpha: 0, y: 16 }, { autoAlpha: 1, y: 0, duration: 0.7, ease: 'power4.out', clearProps: 'transform' }, '-=0.45')
tl.set(filterWrapRef.value!, { autoAlpha: 1 }, '-=0.2')
tl.fromTo(
filterButtons,
{ autoAlpha: 0, y: 20 },
{
autoAlpha: 1,
y: 0,
duration: 0.7,
ease: 'power4.out',
stagger: { each: 0.08, from: 'start' },
clearProps: 'transform',
},
'-=0.3'
)
const filterButtons = gsap.utils.toArray<HTMLElement>('button', filterWrapRef.value!)
tl.fromTo(filterButtons, { autoAlpha: 0, y: 20 }, { autoAlpha: 1, y: 0, duration: 0.7, stagger: 0.08, clearProps: 'transform' }, '-=0.3')
tl.set(projectsWrapRef.value!, { autoAlpha: 1 }, '-=0.05')
tl.fromTo(
projectCards,
{ autoAlpha: 0, y: 34, scale: 0.965 },
{
autoAlpha: 1,
y: 0,
scale: 1,
duration: 0.95,
ease: 'power4.out',
stagger: { each: 0.13, from: 'start' },
clearProps: 'transform',
},
'+=0.08'
)
tl.set([headerWrapRef.value!, filterWrapRef.value!, projectsWrapRef.value!], { clearProps: 'opacity,visibility' })
})
})
})
}, headerWrapRef.value)
const projectCards = gsap.utils.toArray<HTMLElement>('.work-card', projectsWrapRef.value!)
tl.fromTo(projectCards, { autoAlpha: 0, y: 34, scale: 0.965 }, { autoAlpha: 1, y: 0, scale: 1, duration: 0.95, stagger: 0.13, clearProps: 'transform' }, '+=0.08')
}
onMounted(() => {
const handleLoadingDone = () => {
playPageIntro()
}
if (!appStore.isAppLoading) {
playPageIntro()
return
} else {
window.addEventListener('app-loading-done', playPageIntro, { once: true })
}
window.addEventListener('app-loading-done', handleLoadingDone, { once: true })
})
onBeforeUnmount(() => {
projectsCtx?.revert()
})
interface WorkItem {
@@ -182,7 +127,6 @@ interface WorkItem {
title: string
description: string
image: string
url: string
tags: string[]
category: string
}
@@ -193,7 +137,6 @@ const workData: WorkItem[] = [
title: 'Forma Digital',
description: 'A modern e-commerce platform with seamless user experience and dynamic product showcases.',
image: 'https://picsum.photos/id/201/800/600',
url: '#',
tags: ['Web Design', 'E-commerce', 'React'],
category: 'webDesign'
},
@@ -202,7 +145,6 @@ const workData: WorkItem[] = [
title: 'One Step',
description: 'Brand identity and marketing campaign for a fitness app focused on sustainable habits.',
image: 'https://picsum.photos/id/180/800/600',
url: '#',
tags: ['Branding', 'Marketing', 'UI/UX'],
category: 'branding'
},
@@ -211,7 +153,6 @@ const workData: WorkItem[] = [
title: 'Nero Vision',
description: 'Full-stack web application for creative professionals to manage their portfolios.',
image: 'https://picsum.photos/id/119/800/600',
url: '#',
tags: ['Development', 'Vue.js', 'Node.js'],
category: 'development'
},
@@ -220,7 +161,6 @@ const workData: WorkItem[] = [
title: 'Bold Moves',
description: 'Interactive website showcasing innovative architectural designs with 3D visualizations.',
image: 'https://picsum.photos/id/164/800/600',
url: '#',
tags: ['Web Design', '3D', 'Three.js'],
category: 'webDesign'
},
@@ -229,7 +169,6 @@ const workData: WorkItem[] = [
title: 'Echo Labs',
description: 'Corporate branding and visual identity for a tech startup in the AI space.',
image: 'https://picsum.photos/id/101/800/600',
url: '#',
tags: ['Branding', 'Visual Identity', 'Corporate'],
category: 'branding'
},
@@ -238,7 +177,6 @@ const workData: WorkItem[] = [
title: 'Flux API',
description: 'Scalable REST API with comprehensive documentation and developer tools.',
image: 'https://picsum.photos/id/326/800/600',
url: '#',
tags: ['Development', 'API', 'Python'],
category: 'development'
}
@@ -246,7 +184,5 @@ const workData: WorkItem[] = [
</script>
<style scoped>
p {
word-break: break-word;
}
p { word-break: break-word; }
</style>
+126 -1
View File
@@ -308,7 +308,65 @@
"branding": "Branding",
"development": "Development"
},
"cta": "View Project"
"cta": "View Project",
"backToList": "Back to Work",
"detail": {
"overview": "Overview",
"challenge": "Challenge",
"solution": "Solution",
"gallery": "Gallery",
"projectInfo": "Project Info",
"client": "Client",
"year": "Year",
"duration": "Duration",
"services": "Services",
"visitProject": "Visit Project",
"relatedProjects": "Related Projects",
"items": {
"forma-digital": {
"overview": "Forma Digital is a modern e-commerce platform designed to provide a seamless shopping experience. We redesigned the entire user interface with a minimalist design approach, focusing on product showcase and conversion optimization.",
"challenge": "The client needed a platform that could both showcase premium products and deliver a smooth shopping experience. The existing website was slow, had poor mobile experience, and low conversion rates.",
"solution": "We built the platform with React + Next.js, implementing server-side rendering and static generation for blazing fast load times. The product pages feature immersive large-format imagery with smooth animation transitions.",
"client": "Forma Digital Inc.",
"duration": "3 months"
},
"one-step": {
"overview": "One Step is a fitness app focused on building healthy habits. We created a complete brand visual identity system including logo design, UI interface, and marketing materials.",
"challenge": "In the competitive fitness app market, how to stand out through brand design and establish unique brand recognition.",
"solution": "With the core concept of 'one step at a time', we designed a clean and powerful brand identity. Using gradient colors and rounded graphic language to convey health, positivity, and progress.",
"client": "One Step Fitness",
"duration": "2 months"
},
"nero-vision": {
"overview": "Nero Vision is a portfolio management platform for creative professionals, helping designers and artists showcase and manage their work.",
"challenge": "Creative professionals need a platform that can perfectly showcase work while being easy to manage. Existing solutions are either too complex or have poor display quality.",
"solution": "We developed a full-stack application with Vue.js + Node.js, designing an intuitive drag-and-drop portfolio management interface with beautiful display templates.",
"client": "Nero Studio",
"duration": "4 months"
},
"bold-moves": {
"overview": "Bold Moves is an interactive website showcasing innovative architectural designs through 3D visualization technology, letting users experience architecture immersively.",
"challenge": "How to present complex architectural designs in an intuitive and engaging way to general users while maintaining professionalism.",
"solution": "We used Three.js for high-quality 3D rendering with smooth interactive design, allowing users to appreciate architectural details from any angle, with lighting effects and material displays.",
"client": "Bold Moves Architecture",
"duration": "5 months"
},
"echo-labs": {
"overview": "Echo Labs is an AI tech startup. We created a complete brand visual identity system and corporate website for them.",
"challenge": "AI brands need to convey both technology and humanity, avoiding being too cold or technical.",
"solution": "With the concept of 'echo', we designed a dynamic brand identity. Using dark themes with gradient colors for a tech feel, while rounded graphic language adds approachability.",
"client": "Echo Labs AI",
"duration": "3 months"
},
"flux-api": {
"overview": "Flux API is a scalable REST API service platform with comprehensive documentation and developer tools to help developers integrate quickly.",
"challenge": "API documentation and developer experience are core competitive advantages. How to make complex APIs easy to understand and use.",
"solution": "We designed interactive API documentation with online testing and code generation. Multi-language SDKs and detailed tutorials significantly reduce the learning curve for developers.",
"client": "Flux Technologies",
"duration": "6 months"
}
}
}
},
"studio": {
"title": "About Studio",
@@ -360,11 +418,78 @@
"title": "News & Updates",
"description": "Stay informed with our latest insights, project updates, and industry trends.",
"readMore": "Read More",
"backToList": "Back to News",
"categories": {
"all": "All Posts",
"insights": "Insights",
"projects": "Projects",
"announcements": "Announcements"
},
"detail": {
"shareArticle": "Share Article",
"relatedArticles": "Related Articles",
"items": {
"design-trends-2026": {
"content": "In 2026, the design industry is undergoing a profound transformation. From the return of minimalism to the rise of bold typography, from the普及 of 3D elements to the maturity of AI-assisted design, these trends are redefining the boundaries of digital experiences.",
"section1Title": "The Return of Minimalism",
"section1Content": "In an age of information overload, users increasingly渴望 clean, clear interfaces. 2026's minimalism isn't just 'less is more' — it's about delivering more value in limited space through careful information architecture and visual hierarchy.",
"quote": "Good design isn't about adding more, it's about removing the unnecessary. In 2026, this matters more than ever.",
"section2Title": "Bold Typography & Dynamic Text",
"section2Content": "Typography is moving from supporting actor to leading role. Large, high-contrast font designs are becoming important brand expression tools. Dynamic text effects are making typography a living, interactive element rather than static decoration.",
"section3Title": "Maturity of AI-Assisted Design",
"section3Content": "AI tools are shifting from 'replacing designers' to 'empowering designers.' Smart layout suggestions, automated color schemes, and real-time design feedback let designers focus on creativity and strategy rather than repetitive execution."
},
"forma-digital-launch": {
"content": "After three months of careful crafting, we're excited to announce the official launch of the Forma Digital e-commerce platform! This project is one of our team's most challenging works to date.",
"section1Title": "Project Background",
"section1Content": "Forma Digital is an e-commerce brand focusing on premium home goods. They needed a platform that could perfectly showcase product quality while delivering a smooth shopping experience.",
"quote": "The ArcticNewOne team not only understood our needs but exceeded our expectations. After the new platform launched, our conversion rate increased by 45%.",
"section2Title": "Technical Highlights",
"section2Content": "We used React + Next.js for server-side rendering and static generation. Through lazy loading, code splitting, and CDN acceleration, we reduced first load time from 4.5s to 1.2s.",
"section3Title": "Results",
"section3Content": "After launch, user停留 time increased by 60%, bounce rate decreased by 35%, and conversion rate improved by 45%."
},
"studio-expansion": {
"content": "With continued business growth and increasing client demand, we're excited to announce the official expansion of ArcticNewOne Studio!",
"section1Title": "Team Growth",
"section1Content": "We're adding 5 senior designers and 3 senior developers covering frontend, backend, UI/UX, and more. All new members have extensive industry experience.",
"quote": "Talent is our most valuable asset. By expanding our team, we can take on more projects while maintaining consistent high-quality delivery.",
"section2Title": "Service Upgrade",
"section2Content": "In addition to existing services, we're adding data visualization, AI application development, AR/VR experience design, and other cutting-edge services.",
"section3Title": "Looking Ahead",
"section3Content": "We plan to complete 50+ projects and serve 30+ new clients in the coming year while continuing to explore new possibilities."
},
"ux-research-methods": {
"content": "UX research is the foundation of design decisions. In 2026, as technology evolves and user behaviors change, UX research methods continue to advance.",
"section1Title": "Remote User Testing",
"section1Content": "Remote user testing has become mainstream. Through professional platforms, we can recruit test users globally and gather broader feedback in less time.",
"quote": "Remote testing not only reduces costs but more importantly lets us access more authentic user scenarios.",
"section2Title": "Behavioral Data Analysis",
"section2Content": "Through heatmaps, scroll depth, click streams, and other behavioral data, we can objectively understand how users interact with products.",
"section3Title": "AI-Assisted Analysis",
"section3Content": "AI tools help us analyze user feedback more efficiently. Sentiment analysis, topic clustering, and trend prediction help extract valuable insights from massive data."
},
"bold-moves-case-study": {
"content": "Bold Moves is an interactive website showcasing innovative architectural designs. This article provides an in-depth look at the design思路, technical implementation, and final results.",
"section1Title": "Design Philosophy",
"section1Content": "Bold Moves wanted to showcase architectural beauty digitally. We decided to use 3D visualization to let users appreciate architectural details from any angle.",
"quote": "We didn't just want a showcase website — we wanted a digital space where users could 'walk into' the architecture.",
"section2Title": "Technical Challenges",
"section2Content": "High-quality 3D rendering requires significant computing power, but web performance is limited. We achieved smooth interactions through model optimization, LOD techniques, and WebGL rendering.",
"section3Title": "Final Results",
"section3Content": "The project received widespread acclaim and won multiple design awards. Average user停留 time exceeded 5 minutes, well above industry average."
},
"new-tools-integration": {
"content": "To better serve our clients, we continuously expand and improve our toolbox. Recently, we've added several practical tools covering design, development, collaboration, and more.",
"section1Title": "Design Tool Upgrades",
"section1Content": "We've引入 the latest design collaboration platform supporting real-time multi-person editing, version management, and design system integration.",
"quote": "Good tools significantly boost team efficiency. The right toolchain is key to delivering quality work.",
"section2Title": "Development Tool Enhancements",
"section2Content": "Added automated testing frameworks, performance monitoring tools, and code quality checks to help identify and resolve issues during development.",
"section3Title": "Collaboration Tool Optimization",
"section3Content": "We upgraded our project management platform with new Kanban views, time tracking, and resource allocation features for better project oversight."
}
}
}
},
"auth": {
+126 -1
View File
@@ -308,7 +308,65 @@
"branding": "品牌设计",
"development": "程序开发"
},
"cta": "查看项目"
"cta": "查看项目",
"backToList": "返回作品列表",
"detail": {
"overview": "项目概述",
"challenge": "项目挑战",
"solution": "解决方案",
"gallery": "项目展示",
"projectInfo": "项目信息",
"client": "客户",
"year": "年份",
"duration": "周期",
"services": "服务内容",
"visitProject": "访问项目",
"relatedProjects": "相关项目",
"items": {
"forma-digital": {
"overview": "Forma Digital 是一个现代化的电商平台,致力于为用户提供无缝的购物体验。我们重新设计了整个用户界面,采用极简主义设计风格,突出产品展示,提升转化率。",
"challenge": "客户需要一个既能展示高端产品,又能提供流畅购物体验的平台。原有的网站加载缓慢,用户体验差,转化率低下。",
"solution": "我们采用了 React + Next.js 技术栈,实现了服务端渲染和静态生成,大幅提升加载速度。同时重新设计了产品展示页面,采用沉浸式大图展示,配合流畅的动画过渡。",
"client": "Forma Digital Inc.",
"duration": "3 个月"
},
"one-step": {
"overview": "One Step 是一款专注于健康习惯养成的健身应用。我们为其打造了完整的品牌视觉识别系统,包括 Logo 设计、UI 界面和营销物料。",
"challenge": "在竞争激烈的健身应用市场中,如何通过品牌设计脱颖而出,建立独特的品牌认知。",
"solution": "我们以「一步一个脚印」为核心理念,设计了简洁有力的品牌标识。采用渐变色彩和圆润的图形语言,传达健康、积极、向上的品牌调性。",
"client": "One Step Fitness",
"duration": "2 个月"
},
"nero-vision": {
"overview": "Nero Vision 是一个面向创意专业人士的作品集管理平台,帮助设计师和艺术家展示和管理他们的创作。",
"challenge": "创意人士需要一个既能完美展示作品,又能方便管理的平台。现有解决方案要么太复杂,要么展示效果不佳。",
"solution": "我们采用 Vue.js + Node.js 全栈开发,设计了直观的拖拽式作品管理界面,配合精美的展示模板,让创意人士轻松打造个人品牌。",
"client": "Nero Studio",
"duration": "4 个月"
},
"bold-moves": {
"overview": "Bold Moves 是一个展示创新建筑设计的交互式网站,通过 3D 可视化技术,让用户身临其境地体验建筑之美。",
"challenge": "如何将复杂的建筑设计以直观、吸引人的方式展示给普通用户,同时保持专业性。",
"solution": "我们使用 Three.js 实现了高质量的 3D 渲染,配合流畅的交互设计,用户可以从任意角度欣赏建筑细节。同时加入了光影效果和材质展示,提升视觉冲击力。",
"client": "Bold Moves Architecture",
"duration": "5 个月"
},
"echo-labs": {
"overview": "Echo Labs 是一家 AI 领域的科技创业公司,我们为其打造了完整的品牌视觉识别系统和企业官网。",
"challenge": "AI 领域的品牌需要既体现科技感,又要有人文温度,避免过于冷冰冰的技术感。",
"solution": "我们以「回声」为概念,设计了富有动感的品牌标识。采用深色主题配合渐变色彩,营造科技感的同时,通过圆润的图形语言增添亲和力。",
"client": "Echo Labs AI",
"duration": "3 个月"
},
"flux-api": {
"overview": "Flux API 是一个可扩展的 REST API 服务平台,提供全面的文档和开发者工具,帮助开发者快速集成。",
"challenge": "API 文档和开发者体验是技术产品的核心竞争力,如何让复杂的 API 变得易于理解和使用。",
"solution": "我们设计了交互式 API 文档,支持在线测试和代码生成。同时提供了多语言 SDK 和详细的教程,大幅降低开发者的学习成本。",
"client": "Flux Technologies",
"duration": "6 个月"
}
}
}
},
"studio": {
"title": "关于工作室",
@@ -360,11 +418,78 @@
"title": "新闻动态",
"description": "获取我们的最新见解、项目更新和行业趋势。",
"readMore": "阅读更多",
"backToList": "返回文章列表",
"categories": {
"all": "全部文章",
"insights": "行业洞察",
"projects": "项目动态",
"announcements": "公告通知"
},
"detail": {
"shareArticle": "分享文章",
"relatedArticles": "相关文章",
"items": {
"design-trends-2026": {
"content": "2026 年,设计行业正在经历一场深刻的变革。从极简主义的回归到大胆排版的兴起,从 3D 元素的普及到 AI 辅助设计的成熟,这些趋势正在重新定义数字体验的边界。作为设计从业者,我们需要紧跟这些变化,才能为客户创造更具竞争力的作品。",
"section1Title": "极简主义的回归",
"section1Content": "在信息过载的时代,用户越来越渴望简洁、清晰的界面。2026 年的极简主义不再是简单的「少即是多」,而是通过精心的信息架构和视觉层次,在有限的空间内传达更多价值。留白不再是空白,而是一种有意为之的设计语言。",
"quote": "好的设计不是添加更多,而是去除不必要的。在 2026 年,这一点比以往任何时候都更加重要。",
"section2Title": "大胆排版与动态文字",
"section2Content": "排版正在从配角变成主角。大尺寸、高对比度的字体设计正在成为品牌表达的重要手段。动态文字效果的普及,让排版不再是静态的装饰,而是能够与用户互动的活元素。",
"section3Title": "AI 辅助设计的成熟",
"section3Content": "AI 工具正在从「替代设计师」转向「增强设计师」。智能布局建议、自动化配色方案、实时设计反馈等功能,让设计师能够专注于创意和策略,而非重复性的执行工作。"
},
"forma-digital-launch": {
"content": "经过三个月的精心打造,我们很高兴地宣布 Forma Digital 电商平台正式上线!这个项目是我们团队迄今为止最具挑战性的作品之一,也是我们技术实力和设计能力的集中体现。",
"section1Title": "项目背景",
"section1Content": "Forma Digital 是一家专注于高端家居用品的电商品牌。他们需要一个能够完美展示产品质感、提供流畅购物体验的平台。原有的网站存在加载缓慢、移动端体验差、转化率低等问题。",
"quote": "北极新一团队不仅理解我们的需求,更超越了我们的期望。新平台上线后,我们的转化率提升了 45%。",
"section2Title": "技术亮点",
"section2Content": "我们采用了 React + Next.js 技术栈,实现了服务端渲染和静态生成。通过图片懒加载、代码分割、CDN 加速等技术手段,将首屏加载时间从 4.5 秒降低到 1.2 秒。",
"section3Title": "成果展示",
"section3Content": "新平台上线后,用户停留时间增加了 60%,跳出率降低了 35%,转化率提升了 45%。客户对新平台的设计和性能都非常满意。"
},
"studio-expansion": {
"content": "随着业务的持续增长和客户需求的不断增加,我们很高兴地宣布 ArcticNewOne 工作室正式扩展!我们将增加新的团队成员,拓展服务能力,为客户提供更优质的数字化解决方案。",
"section1Title": "团队扩展",
"section1Content": "我们将新增 5 名资深设计师和 3 名高级开发工程师,覆盖前端、后端、UI/UX 等多个领域。这些新成员都拥有丰富的行业经验,曾服务于多家知名企业。",
"quote": "人才是我们最宝贵的资产。通过扩展团队,我们能够承接更多项目,同时保持一贯的高品质交付。",
"section2Title": "服务升级",
"section2Content": "除了现有的网页设计、品牌设计、程序开发等服务,我们还将新增数据可视化、AI 应用开发、AR/VR 体验设计等前沿服务。",
"section3Title": "展望未来",
"section3Content": "我们计划在未来一年内完成 50+ 项目,服务 30+ 新客户。同时,我们将继续深耕技术创新,探索更多可能性,为客户创造更大价值。"
},
"ux-research-methods": {
"content": "用户体验研究是设计决策的基础。在 2026 年,随着技术的发展和用户行为的变化,UX 研究方法也在不断演进。本文将介绍几种最有效的现代 UX 研究方法。",
"section1Title": "远程用户测试",
"section1Content": "远程用户测试已经成为 UX 研究的主流方法。通过专业的远程测试平台,我们可以在短时间内招募到全球各地的测试用户,获取更广泛的反馈。",
"quote": "远程测试不仅降低了成本,更重要的是让我们能够接触到更真实的用户场景。",
"section2Title": "行为数据分析",
"section2Content": "通过热力图、滚动深度、点击流等行为数据,我们可以客观地了解用户如何与产品互动。这些数据弥补了传统访谈和问卷的不足,提供了更真实的用户行为洞察。",
"section3Title": "AI 辅助分析",
"section3Content": "AI 工具正在帮助我们更高效地分析用户反馈。情感分析、主题聚类、趋势预测等功能,让我们能够从海量数据中快速提取有价值的洞察。"
},
"bold-moves-case-study": {
"content": "Bold Moves 是一个展示创新建筑设计的交互式网站项目。本文将深入介绍这个项目的设计思路、技术实现和最终成果。",
"section1Title": "设计理念",
"section1Content": "Bold Moves 希望通过数字方式展示建筑设计的魅力。我们决定采用 3D 可视化技术,让用户能够从任意角度欣赏建筑细节,获得沉浸式的体验。",
"quote": "我们想要的不只是一个展示网站,而是一个能够让用户「走进」建筑的数字空间。",
"section2Title": "技术挑战",
"section2Content": "高质量的 3D 渲染需要强大的计算能力,而网页端的性能有限。我们通过模型优化、LOD 技术、WebGL 渲染等手段,在保证视觉质量的同时,实现了流畅的交互体验。",
"section3Title": "最终成果",
"section3Content": "项目上线后获得了广泛好评,赢得了多个设计奖项。用户平均停留时间超过 5 分钟,远高于行业平均水平。"
},
"new-tools-integration": {
"content": "为了更好地服务客户,我们不断扩充和完善我们的工具箱。最近,我们新增了多款实用工具,涵盖设计、开发、协作等多个领域。",
"section1Title": "设计工具升级",
"section1Content": "我们引入了最新的设计协作平台,支持实时多人编辑、版本管理、设计系统集成等功能。设计师和开发者可以在同一个平台上无缝协作。",
"quote": "工欲善其事,必先利其器。好的工具能够大幅提升团队效率。",
"section2Title": "开发工具增强",
"section2Content": "新增了自动化测试框架、性能监控工具、代码质量检查等开发工具。这些工具帮助我们在开发过程中及时发现和解决问题,保证代码质量。",
"section3Title": "协作工具优化",
"section3Content": "我们升级了项目管理平台,新增了看板视图、时间追踪、资源分配等功能。项目经理可以更直观地掌控项目进度,团队成员可以更高效地协作。"
}
}
}
},
"auth": {