feat: 首页

This commit is contained in:
2026-05-15 10:29:21 +08:00
parent 3edda93691
commit e797612de6
11 changed files with 554 additions and 87 deletions

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
<path fill="#666" d="M464 0H112c-4 0-7.8 2-10 5.4L2 152.6c-2.9 4.4-2.6 10.2.7 14.2l276 340.8c4.8 5.9 13.8 5.9 18.6 0l276-340.8c3.3-4.1 3.6-9.8.7-14.2L474.1 5.4C471.8 2 468.1 0 464 0zm-19.3 48l63.3 96h-68.4l-51.7-96h56.8zm-202.1 0h90.7l51.7 96H191l51.6-96zm-111.3 0h56.8l-51.7 96H68l63.3-96zm-43 144h51.4L208 352 88.3 192zm102.9 0h193.6L288 435.3 191.2 192zM368 352l68.2-160h51.4L368 352z"/>
</svg>

After

Width:  |  Height:  |  Size: 462 B

View File

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
<g transform="translate(1024 0) scale(-1 1)">
<path
fill="#666"
d="M512 64C264.96 64 64 264.96 64 512s200.96 448 448 448 448-200.96 448-448S759.04 64 512 64zM512 895.712c-211.584 0-383.712-172.16-383.712-383.712C128.288 300.416 300.416 128.288 512 128.288c211.552 0 383.712 172.128 383.712 383.712C895.712 723.552 723.552 895.712 512 895.712zM671.968 512 512 512 512 288.064c0-17.76-14.24-32.128-32-32.128s-32 14.4-32 32.128L448 544c0 17.76 14.272 32 32 32l191.968 0c17.76 0 32.128-14.24 32.128-32S689.728 512 671.968 512z"
/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 627 B

View File

@@ -9,8 +9,8 @@ export const createApp = ViteSSG(App, {
routes,
base: import.meta.env.BASE_URL,
},
({ app, router, routes, isClient, initialState }) => {
({ app }) => {
// 注册全局指令
app.use(directives)
}
)
)

0
src/pages/aida/index.vue Normal file
View File

View File

@@ -0,0 +1,249 @@
<script setup lang="ts">
import { RouterLink } from 'vue-router'
withDefaults(
defineProps<{
name: string
title: string
backgroundImage: string
backgroundAlt: string
panelImage: string
panelAlt: string
reversed?: boolean
}>(),
{
reversed: false
}
)
</script>
<template>
<section class="product-feature" :class="{ 'product-feature-reversed': reversed }">
<div class="product-feature-art">
<img
class="product-feature-bg"
:src="backgroundImage"
:alt="backgroundAlt"
loading="lazy"
/>
<img class="product-feature-panel" :src="panelImage" :alt="panelAlt" loading="lazy" />
</div>
<div class="product-feature-copy">
<p class="product-feature-name">{{ name }}</p>
<h2 class="product-feature-title">{{ title }}</h2>
<RouterLink class="product-feature-link" to="/products"> View More </RouterLink>
</div>
</section>
</template>
<style scoped lang="less">
.product-feature {
display: flex;
align-items: center;
gap: clamp(48px, 5.5vw, 76px);
width: 1440px;
min-width: 0;
min-height: 690px;
margin: 0 auto;
& > div {
width: 50%;
}
}
.product-feature-reversed {
grid-template-columns: minmax(420px, 0.95fr) minmax(0, 1.05fr);
}
.product-feature-reversed .product-feature-art {
order: 2;
justify-self: end;
}
.product-feature-reversed .product-feature-copy {
order: 1;
justify-self: start;
max-width: 510px;
}
.product-feature-art {
position: relative;
width: min(100%, 560px);
min-width: 0;
min-height: 560px;
justify-self: start;
}
.product-feature-bg {
display: block;
width: min(100%, 480px);
max-width: 100%;
height: auto;
user-select: none;
}
.product-feature-panel {
position: absolute;
right: 0;
bottom: 94px;
width: min(72%, 380px);
max-width: 100%;
height: auto;
user-select: none;
}
.product-feature-reversed .product-feature-bg {
width: min(100%, 460px);
margin-left: auto;
}
.product-feature-reversed .product-feature-panel {
right: auto;
left: -88px;
bottom: 70px;
width: min(78%, 430px);
}
.product-feature-copy {
position: relative;
z-index: 1;
max-width: 590px;
min-width: 0;
justify-self: start;
padding-bottom: 18px;
}
.product-feature-name {
margin: 0 0 20px;
color: #6e6e6e;
font-family: Poppins, sans-serif;
font-size: 18px;
font-weight: 700;
line-height: 1;
letter-spacing: 2px;
}
.product-feature-title {
margin: 0 0 28px;
color: #252525;
font-family: Poppins, sans-serif;
font-size: clamp(30px, 2.8vw, 38px);
font-weight: 700;
line-height: 1.16;
letter-spacing: 2px;
text-transform: none;
overflow-wrap: break-word;
}
.product-feature-link {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 152px;
min-height: 48px;
padding: 0 28px;
border-radius: 999px;
color: #ffffff;
background: #a72125;
font-family: Poppins, sans-serif;
font-size: 10px;
font-weight: 700;
line-height: 1;
letter-spacing: 2px;
text-decoration: none;
text-transform: uppercase;
transition:
background-color 0.2s ease,
transform 0.2s ease;
}
.product-feature-link:hover,
.product-feature-link:focus-visible {
background: #8e171b;
transform: translateY(-1px);
}
.product-feature-link:focus-visible {
outline: 2px solid #a72125;
outline-offset: 4px;
}
@media (max-width: 980px) {
.product-feature,
.product-feature-reversed {
grid-template-columns: 1fr;
gap: 24px;
width: min(680px, calc(100% - 40px));
min-height: 0;
padding: 70px 0;
}
.product-feature-reversed .product-feature-art,
.product-feature-reversed .product-feature-copy {
order: initial;
justify-self: start;
}
.product-feature-art {
width: 100%;
max-width: 100%;
min-height: clamp(390px, 82vw, 560px);
justify-self: stretch;
}
.product-feature-copy {
width: 100%;
max-width: 640px;
justify-self: stretch;
padding-bottom: 0;
}
.product-feature-reversed .product-feature-panel {
left: 0;
}
}
@media (max-width: 640px) {
.product-feature,
.product-feature-reversed {
width: calc(100% - 32px);
padding: 52px 0;
}
.product-feature-art {
min-height: clamp(300px, 82vw, 430px);
}
.product-feature-copy,
.product-feature-reversed .product-feature-copy {
width: 100% !important;
max-width: 100% !important;
justify-self: stretch !important;
}
.product-feature-bg {
width: 78%;
}
.product-feature-panel,
.product-feature-reversed .product-feature-panel {
left: auto;
right: 0;
bottom: 42px;
width: 68%;
}
.product-feature-reversed .product-feature-bg {
width: 72%;
}
.product-feature-title {
width: 100%;
max-width: 100%;
font-size: clamp(26px, 7.2vw, 30px);
line-height: 1.2;
letter-spacing: 1.2px;
overflow-wrap: anywhere;
}
}
</style>

View File

@@ -0,0 +1,83 @@
<script setup lang="ts">
import { RouterLink } from 'vue-router'
</script>
<template>
<section class="project-cta">
<div class="project-cta-inner">
<h2 class="project-cta-title">Talk To Us About Your Next Project</h2>
<RouterLink class="project-cta-link" to="/contact">
Contact Us
</RouterLink>
</div>
</section>
</template>
<style scoped lang="less">
.project-cta {
display: flex;
align-items: center;
justify-content: center;
min-height: 435px;
padding: 72px 20px;
background: #473935;
}
.project-cta-inner {
display: flex;
flex-direction: column;
align-items: center;
gap: 38px;
text-align: center;
}
.project-cta-title {
margin: 0;
color: #ffffff;
font-family: Poppins, sans-serif;
font-size: clamp(22px, 2vw, 27px);
font-weight: 700;
line-height: 1.35;
letter-spacing: 2px;
text-transform: capitalize;
}
.project-cta-link {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 158px;
min-height: 48px;
padding: 0 28px;
border-radius: 999px;
color: #ffffff;
background: #ad2228;
font-family: Poppins, sans-serif;
font-size: 10px;
font-weight: 700;
line-height: 1;
letter-spacing: 2px;
text-decoration: none;
text-transform: uppercase;
transition:
background-color 0.2s ease,
transform 0.2s ease;
}
.project-cta-link:hover,
.project-cta-link:focus-visible {
background: #93191f;
transform: translateY(-1px);
}
.project-cta-link:focus-visible {
outline: 2px solid #ffffff;
outline-offset: 4px;
}
@media (max-width: 640px) {
.project-cta {
min-height: 340px;
}
}
</style>

View File

@@ -1,95 +1,215 @@
<template>
<main class="home-page">
<HomeCarousel />
<section class="home-links" aria-label="Site pages">
<RouterLink
v-for="page in pageLinks"
:key="page.to"
class="home-link"
:to="page.to"
>
{{ page.label }}
</RouterLink>
</section>
</main>
</template>
<script setup lang="ts">
import { useHead } from '@unhead/vue'
import { RouterLink } from 'vue-router'
import aidaIntroBg from '@/assets/images/home/aida-intro-bg.png'
import aidaPanel from '@/assets/images/home/aida-panel.png'
import homeAiLogo from '@/assets/images/home/home-ai-logo.png'
import mixiIntroBg from '@/assets/images/home/mixi-intro-bg.png'
import mixiPanel from '@/assets/images/home/mixi-panel.png'
import HomeCarousel from './components/Carousel.vue'
import ProductFeature from './components/ProductFeature.vue'
import ProjectCta from './components/ProjectCta.vue'
const pageLinks = [
{ label: 'About', to: '/about' },
{ label: 'Products', to: '/products' },
{ label: 'Contact', to: '/contact' },
const productFeatures = [
{
name: 'AiDA 3.1',
title:
'Empowers fashion designers to create a collection with just a few clicks based on their creative inspirations.',
backgroundImage: aidaIntroBg,
backgroundAlt: 'Fashion design sketches on paper',
panelImage: aidaPanel,
panelAlt: 'AiDA design workspace preview',
reversed: false
},
{
name: 'Mixi',
title:
"Drives sales by improving shoppers' experience through precise and fast search.",
backgroundImage: mixiIntroBg,
backgroundAlt: 'Layered fabric texture',
panelImage: mixiPanel,
panelAlt: 'Mixi visual search interface preview',
reversed: true
}
] as const
useHead({
title: 'Home | Code Create',
meta: [
{
name: 'description',
content: 'Code Create home page rendered with Vite SSG.',
},
],
title: 'Home | Code Create',
meta: [
{
name: 'description',
content:
'Code Create revitalises the fashion ecosystem through artificial intelligence.'
}
]
})
</script>
<style scoped>
.home-page {
/* width: 100%; */
/* min-height: 100svh; */
/* background: #ffffff; */
}
<template>
<main class="home-page">
<HomeCarousel />
.home-links {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 12px;
padding: 32px 20px 48px;
}
<div class="home-content">
<section class="ecosystem-intro" aria-labelledby="ecosystem-title">
<img
class="ecosystem-logo"
:src="homeAiLogo"
alt="Code Create"
loading="lazy"
/>
<h1 id="ecosystem-title" class="ecosystem-title">
Revitalise The Fashion Ecosystem
</h1>
<p class="ecosystem-subtitle">Through Artificial Intelligence (AI)</p>
</section>
.home-link {
min-width: 112px;
padding: 10px 16px;
border: 1px solid #d9dde6;
border-radius: 6px;
color: #1d2430;
background: #ffffff;
font-size: 15px;
line-height: 1.2;
text-align: center;
text-decoration: none;
box-sizing: border-box;
transition:
border-color 0.2s,
color 0.2s,
box-shadow 0.2s;
}
<ProductFeature
v-for="feature in productFeatures"
:key="feature.name"
:name="feature.name"
:title="feature.title"
:background-image="feature.backgroundImage"
:background-alt="feature.backgroundAlt"
:panel-image="feature.panelImage"
:panel-alt="feature.panelAlt"
:reversed="feature.reversed"
/>
</div>
.home-link:hover,
.home-link:focus-visible,
.home-link.router-link-active {
border-color: #2f6df6;
color: #2f6df6;
box-shadow: 0 8px 24px rgba(36, 55, 92, 0.12);
}
<ProjectCta />
.home-link:focus-visible {
outline: 2px solid #2f6df6;
outline-offset: 2px;
}
<section class="home-next" aria-labelledby="home-next-title">
<p class="home-next-kicker">Subheading Text</p>
<h2 id="home-next-title" class="home-next-title">Headline</h2>
<p class="home-next-copy">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit
tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.
</p>
</section>
</main>
</template>
@media (max-width: 640px) {
.home-links {
padding: 24px 16px 40px;
}
<style scoped lang="less">
.home-page {
width: 100%;
overflow: hidden;
background: #ffffff;
}
.home-link {
flex: 1 1 calc(50% - 12px);
}
}
.home-content {
padding: clamp(116px, 10vw, 172px) 0 clamp(92px, 8vw, 126px);
background: #ffffff;
}
.ecosystem-intro {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 0 20px clamp(92px, 10vw, 150px);
text-align: center;
}
.ecosystem-logo {
display: block;
width: clamp(146px, 15vw, 184px);
height: auto;
margin-bottom: 30px;
user-select: none;
}
.ecosystem-title {
width: 100%;
max-width: 100%;
margin: 0 0 9px;
color: #101010;
font-family: Poppins, sans-serif;
font-size: clamp(18px, 1.65vw, 22px);
font-weight: 700;
line-height: 1.25;
letter-spacing: 4px;
text-transform: uppercase;
overflow-wrap: break-word;
}
.ecosystem-subtitle {
width: 100%;
margin: 0;
color: #101010;
font-family: Poppins, sans-serif;
font-size: clamp(13px, 1.2vw, 16px);
font-weight: 600;
line-height: 1.35;
letter-spacing: 2.5px;
}
.home-next {
padding: 18px 20px 34px;
background: #ffffff;
text-align: center;
}
.home-next-kicker {
margin: 0 0 2px;
color: #222222;
font-family: Poppins, sans-serif;
font-size: 12px;
font-weight: 400;
line-height: 1.4;
}
.home-next-title {
margin: 0 0 12px;
color: #1455ff;
font-family: Poppins, sans-serif;
font-size: 30px;
font-weight: 700;
line-height: 1.1;
letter-spacing: 0;
text-transform: none;
}
.home-next-copy {
max-width: 720px;
margin: 0 auto;
color: #202020;
font-family: Poppins, sans-serif;
font-size: 12px;
font-weight: 400;
line-height: 1.55;
}
@media (max-width: 980px) {
.home-content {
padding: 96px 0 64px;
}
.ecosystem-intro {
padding-bottom: 50px;
}
}
@media (max-width: 640px) {
.home-content {
padding: 72px 0 36px;
}
.ecosystem-logo {
width: 138px;
margin-bottom: 22px;
}
.ecosystem-title {
width: min(100%, 330px);
max-width: none;
font-size: 14px;
letter-spacing: 1.5px;
line-height: 1.45;
overflow-wrap: anywhere;
}
.ecosystem-subtitle {
font-size: 12px;
letter-spacing: 1.5px;
}
}
</style>

View File

@@ -11,23 +11,27 @@ export const routes: RouteRecordRaw[] = [
{
path: '',
component: HomeView,
alias: ['/:lang?', '/:lang?/home'],
alias: ['/:lang?', '/:lang?/home']
},
{
path: 'about',
component: AboutView,
component: AboutView
},
{
path: 'products',
name: 'products',
component: ProductsView,
component: ProductsView
},
{
path: 'contact',
name: 'contact',
component: ContactView,
component: ContactView
},
],
},
{
path: 'aida',
name: 'Aida',
component: () => import('./pages/aida/index.vue')
}
]
}
]