feat(theme): apply CYBER STAR design system (purple palette + Megrim/Audiowide/Cinzel/Inter fonts + ambient bg)
This commit is contained in:
parent
8a83815f1c
commit
ba5287add8
@ -1,26 +1,266 @@
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
|
|
||||||
:root {
|
/* ════════════════════════════════════════════════════════════
|
||||||
--background: #ffffff;
|
CYBER STAR · 设计令牌(Tailwind v4 @theme)
|
||||||
--foreground: #171717;
|
将所有 token 暴露为 Tailwind 工具类
|
||||||
|
════════════════════════════════════════════════════════════ */
|
||||||
|
@theme {
|
||||||
|
/* ── 背景层级(偏紫调深色) ── */
|
||||||
|
--color-deepest: #08051a;
|
||||||
|
--color-deep: #0d0a24;
|
||||||
|
--color-base: #13102e;
|
||||||
|
--color-surface: #1a1638;
|
||||||
|
--color-elevated: #221d4a;
|
||||||
|
--color-card: #1e1840;
|
||||||
|
|
||||||
|
/* ── 主调紫 · Royal Violet ── */
|
||||||
|
--color-purple-100: #ede9fe;
|
||||||
|
--color-purple-200: #ddd6fe;
|
||||||
|
--color-purple-300: #c4b5fd;
|
||||||
|
--color-purple-400: #a78bfa;
|
||||||
|
--color-purple-500: #8b5cf6;
|
||||||
|
--color-purple-600: #7c3aed;
|
||||||
|
--color-purple-700: #6d28d9;
|
||||||
|
--color-purple-800: #5b21b6;
|
||||||
|
|
||||||
|
/* ── 辅助蓝青(仅用于点缀光效) ── */
|
||||||
|
--color-blue-300: #93b8ff;
|
||||||
|
--color-blue-500: #2d7fff;
|
||||||
|
--color-cyan-400: #38d9f5;
|
||||||
|
|
||||||
|
/* ── 强调色 ── */
|
||||||
|
--color-magenta: #d946ef;
|
||||||
|
--color-pink-400: #f472b6;
|
||||||
|
--color-pink-500: #ec4899;
|
||||||
|
--color-gold-400: #fcd34d;
|
||||||
|
--color-silver: #c4ccd8;
|
||||||
|
--color-bronze: #cd7f32;
|
||||||
|
|
||||||
|
/* ── 字体(变量注入自 next/font) ── */
|
||||||
|
--font-logo: var(--font-megrim), "Cinzel", serif;
|
||||||
|
--font-display: var(--font-audiowide), "Audiowide", sans-serif;
|
||||||
|
--font-label: var(--font-cinzel), "Cinzel", serif;
|
||||||
|
--font-body: var(--font-inter), -apple-system, "Source Han Sans SC",
|
||||||
|
"PingFang SC", "Microsoft YaHei", sans-serif;
|
||||||
|
|
||||||
|
/* ── 自定义动画 ── */
|
||||||
|
--animate-pulse-glow: pulse-glow 2.4s ease-in-out infinite;
|
||||||
|
--animate-float: float 3s ease-in-out infinite;
|
||||||
|
--animate-spin-slow: spin-slow 20s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@theme inline {
|
/* ════════════════════════════════════════════════════════════
|
||||||
--color-background: var(--background);
|
非 Tailwind 化的 CSS 变量(复杂值 / 渐变 / 阴影)
|
||||||
--color-foreground: var(--foreground);
|
════════════════════════════════════════════════════════════ */
|
||||||
--font-sans: var(--font-geist-sans);
|
:root {
|
||||||
--font-mono: var(--font-geist-mono);
|
--grad-hero: radial-gradient(
|
||||||
|
ellipse at 70% 40%,
|
||||||
|
#2a1f5c 0%,
|
||||||
|
#13102e 45%,
|
||||||
|
#08051a 100%
|
||||||
|
);
|
||||||
|
--grad-purple: linear-gradient(
|
||||||
|
135deg,
|
||||||
|
#6d28d9 0%,
|
||||||
|
#8b5cf6 55%,
|
||||||
|
#a78bfa 100%
|
||||||
|
);
|
||||||
|
--grad-purple-deep: linear-gradient(160deg, #5b21b6 0%, #7c3aed 100%);
|
||||||
|
--grad-violet-glow: radial-gradient(
|
||||||
|
circle,
|
||||||
|
rgba(139, 92, 246, 0.4) 0%,
|
||||||
|
transparent 65%
|
||||||
|
);
|
||||||
|
--grad-card: linear-gradient(155deg, #221d4a 0%, #1a1638 100%);
|
||||||
|
--grad-shine: linear-gradient(
|
||||||
|
105deg,
|
||||||
|
transparent 40%,
|
||||||
|
rgba(255, 255, 255, 0.06) 50%,
|
||||||
|
transparent 60%
|
||||||
|
);
|
||||||
|
|
||||||
|
--shadow-purple: 0 0 24px rgba(139, 92, 246, 0.5),
|
||||||
|
0 0 60px rgba(139, 92, 246, 0.18);
|
||||||
|
--shadow-card: 0 8px 32px rgba(0, 0, 0, 0.65),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.06);
|
||||||
|
--shadow-glow: 0 0 40px rgba(196, 181, 253, 0.25);
|
||||||
|
|
||||||
|
--border-subtle: rgba(255, 255, 255, 0.08);
|
||||||
|
--border-default: rgba(255, 255, 255, 0.14);
|
||||||
|
--border-purple: rgba(139, 92, 246, 0.55);
|
||||||
|
--border-glow: rgba(196, 181, 253, 0.65);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
/* ════════════════════════════════════════════════════════════
|
||||||
:root {
|
全局基础样式
|
||||||
--background: #0a0a0a;
|
════════════════════════════════════════════════════════════ */
|
||||||
--foreground: #ededed;
|
html {
|
||||||
}
|
background: var(--color-deepest);
|
||||||
|
color: #fff;
|
||||||
|
font-family: var(--font-body);
|
||||||
|
line-height: 1.6;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background: var(--background);
|
background: var(--color-deepest);
|
||||||
color: var(--foreground);
|
min-height: 100vh;
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
position: relative;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── 氛围装饰层 1 · 紫雾环境光 ── */
|
||||||
|
body::before {
|
||||||
|
content: "";
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
background:
|
||||||
|
radial-gradient(
|
||||||
|
ellipse at 20% 10%,
|
||||||
|
rgba(139, 92, 246, 0.12) 0%,
|
||||||
|
transparent 40%
|
||||||
|
),
|
||||||
|
radial-gradient(
|
||||||
|
ellipse at 80% 70%,
|
||||||
|
rgba(217, 70, 239, 0.08) 0%,
|
||||||
|
transparent 45%
|
||||||
|
);
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── 氛围装饰层 2 · 星点粒子背景 ── */
|
||||||
|
body::after {
|
||||||
|
content: "";
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
background-image:
|
||||||
|
radial-gradient(1px 1px at 23% 17%, rgba(255, 255, 255, 0.6), transparent),
|
||||||
|
radial-gradient(1px 1px at 67% 41%, rgba(196, 181, 253, 0.5), transparent),
|
||||||
|
radial-gradient(1.5px 1.5px at 89% 23%, rgba(255, 255, 255, 0.4), transparent),
|
||||||
|
radial-gradient(1px 1px at 12% 78%, rgba(196, 181, 253, 0.4), transparent),
|
||||||
|
radial-gradient(1px 1px at 45% 89%, rgba(255, 255, 255, 0.5), transparent),
|
||||||
|
radial-gradient(1.5px 1.5px at 78% 11%, rgba(255, 255, 255, 0.3), transparent),
|
||||||
|
radial-gradient(1px 1px at 33% 53%, rgba(196, 181, 253, 0.35), transparent),
|
||||||
|
radial-gradient(1px 1px at 91% 88%, rgba(255, 255, 255, 0.4), transparent);
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 页面内容须高于装饰层 */
|
||||||
|
body > * {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── 选中文字 ── */
|
||||||
|
::selection {
|
||||||
|
background: rgba(139, 92, 246, 0.4);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── 自定义滚动条 ── */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: var(--color-deep);
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--color-elevated);
|
||||||
|
border-radius: 5px;
|
||||||
|
border: 2px solid var(--color-deep);
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: var(--color-purple-700);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ════════════════════════════════════════════════════════════
|
||||||
|
动画 keyframes
|
||||||
|
════════════════════════════════════════════════════════════ */
|
||||||
|
@keyframes pulse-glow {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
box-shadow: 0 0 12px rgba(139, 92, 246, 0.45);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
box-shadow:
|
||||||
|
0 0 32px rgba(139, 92, 246, 0.85),
|
||||||
|
0 0 64px rgba(139, 92, 246, 0.35);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: translateY(-6px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin-slow {
|
||||||
|
from {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in-up {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(20px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shine-sweep {
|
||||||
|
0% {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ════════════════════════════════════════════════════════════
|
||||||
|
工具类(在 Tailwind 之外的、需要特殊渲染的)
|
||||||
|
════════════════════════════════════════════════════════════ */
|
||||||
|
.glow-text-purple {
|
||||||
|
text-shadow:
|
||||||
|
0 0 16px rgba(196, 181, 253, 0.55),
|
||||||
|
0 0 32px rgba(139, 92, 246, 0.35);
|
||||||
|
}
|
||||||
|
.glow-text-cyan {
|
||||||
|
text-shadow:
|
||||||
|
0 0 12px rgba(56, 217, 245, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-grad-hero {
|
||||||
|
background: var(--grad-hero);
|
||||||
|
}
|
||||||
|
.bg-grad-purple {
|
||||||
|
background: var(--grad-purple);
|
||||||
|
}
|
||||||
|
.bg-grad-card {
|
||||||
|
background: var(--grad-card);
|
||||||
|
}
|
||||||
|
|
||||||
|
.shadow-purple-glow {
|
||||||
|
box-shadow: var(--shadow-purple);
|
||||||
|
}
|
||||||
|
.shadow-card {
|
||||||
|
box-shadow: var(--shadow-card);
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-purple-glow {
|
||||||
|
border-color: var(--border-purple);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,44 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import { Geist, Geist_Mono } from "next/font/google";
|
import { Megrim, Audiowide, Cinzel, Inter } from "next/font/google";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
|
|
||||||
const geistSans = Geist({
|
const megrim = Megrim({
|
||||||
variable: "--font-geist-sans",
|
weight: "400",
|
||||||
subsets: ["latin"],
|
subsets: ["latin"],
|
||||||
|
variable: "--font-megrim",
|
||||||
|
display: "swap",
|
||||||
});
|
});
|
||||||
|
|
||||||
const geistMono = Geist_Mono({
|
const audiowide = Audiowide({
|
||||||
variable: "--font-geist-mono",
|
weight: "400",
|
||||||
subsets: ["latin"],
|
subsets: ["latin"],
|
||||||
|
variable: "--font-audiowide",
|
||||||
|
display: "swap",
|
||||||
|
});
|
||||||
|
|
||||||
|
const cinzel = Cinzel({
|
||||||
|
weight: ["400", "500", "600", "700"],
|
||||||
|
subsets: ["latin"],
|
||||||
|
variable: "--font-cinzel",
|
||||||
|
display: "swap",
|
||||||
|
});
|
||||||
|
|
||||||
|
const inter = Inter({
|
||||||
|
subsets: ["latin"],
|
||||||
|
variable: "--font-inter",
|
||||||
|
display: "swap",
|
||||||
});
|
});
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Create Next App",
|
title: "CYBER ✦ STAR · 虚拟偶像 Top12 出道企划",
|
||||||
description: "Generated by create next app",
|
description:
|
||||||
|
"35 位虚拟偶像候选人,由你投票决出最终出道 Top12。Cyber Star · Virtual Idol Debut Project.",
|
||||||
|
keywords: ["虚拟偶像", "出道", "投票", "Top12", "Cyber Star", "Virtual Idol"],
|
||||||
|
openGraph: {
|
||||||
|
title: "CYBER ✦ STAR",
|
||||||
|
description: "虚拟偶像 Top12 出道企划",
|
||||||
|
type: "website",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
@ -24,10 +48,10 @@ export default function RootLayout({
|
|||||||
}>) {
|
}>) {
|
||||||
return (
|
return (
|
||||||
<html
|
<html
|
||||||
lang="en"
|
lang="zh-CN"
|
||||||
className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
|
className={`${megrim.variable} ${audiowide.variable} ${cinzel.variable} ${inter.variable} h-full antialiased`}
|
||||||
>
|
>
|
||||||
<body className="min-h-full flex flex-col">{children}</body>
|
<body className="min-h-full">{children}</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
133
src/app/page.tsx
133
src/app/page.tsx
@ -1,65 +1,86 @@
|
|||||||
import Image from "next/image";
|
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col flex-1 items-center justify-center bg-zinc-50 font-sans dark:bg-black">
|
<main className="min-h-screen flex flex-col items-center justify-center px-6 py-16">
|
||||||
<main className="flex flex-1 w-full max-w-3xl flex-col items-center justify-between py-32 px-16 bg-white dark:bg-black sm:items-start">
|
{/* Logo */}
|
||||||
<Image
|
<h1
|
||||||
className="dark:invert"
|
className="font-logo text-7xl sm:text-8xl tracking-[0.5em] uppercase glow-text-purple text-center mb-4"
|
||||||
src="/next.svg"
|
style={{ paddingLeft: "0.5em" }}
|
||||||
alt="Next.js logo"
|
>
|
||||||
width={100}
|
Cyber
|
||||||
height={20}
|
<span className="text-purple-300 mx-3 text-5xl sm:text-6xl align-middle">
|
||||||
priority
|
✦
|
||||||
/>
|
</span>
|
||||||
<div className="flex flex-col items-center gap-6 text-center sm:items-start sm:text-left">
|
Star
|
||||||
<h1 className="max-w-xs text-3xl font-semibold leading-10 tracking-tight text-black dark:text-zinc-50">
|
|
||||||
To get started, edit the page.tsx file.
|
|
||||||
</h1>
|
</h1>
|
||||||
<p className="max-w-md text-lg leading-8 text-zinc-600 dark:text-zinc-400">
|
|
||||||
Looking for a starting point or more instructions? Head over to{" "}
|
{/* Subtitle */}
|
||||||
<a
|
<p className="font-label text-sm tracking-[0.4em] uppercase text-purple-300 mb-2">
|
||||||
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
Virtual Idol Debut Project
|
||||||
className="font-medium text-zinc-950 dark:text-zinc-50"
|
</p>
|
||||||
>
|
<p className="text-white/60 text-sm mb-12">
|
||||||
Templates
|
虚拟偶像 Top12 出道企划
|
||||||
</a>{" "}
|
</p>
|
||||||
or the{" "}
|
|
||||||
<a
|
{/* Status badge */}
|
||||||
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-purple-500/10 border border-purple-500/30 mb-12">
|
||||||
className="font-medium text-zinc-950 dark:text-zinc-50"
|
<span className="w-2 h-2 rounded-full bg-purple-400 animate-pulse-glow"></span>
|
||||||
>
|
<span className="font-label text-xs tracking-widest text-purple-300 uppercase">
|
||||||
Learning
|
Phase 2 · Theme Ready
|
||||||
</a>{" "}
|
</span>
|
||||||
center.
|
</div>
|
||||||
|
|
||||||
|
{/* Theme verification swatches */}
|
||||||
|
<div className="grid grid-cols-3 sm:grid-cols-6 gap-3 max-w-2xl">
|
||||||
|
{[
|
||||||
|
{ name: "purple-300", className: "bg-purple-300" },
|
||||||
|
{ name: "purple-500", className: "bg-purple-500" },
|
||||||
|
{ name: "purple-700", className: "bg-purple-700" },
|
||||||
|
{ name: "magenta", className: "bg-magenta" },
|
||||||
|
{ name: "pink-400", className: "bg-pink-400" },
|
||||||
|
{ name: "cyan-400", className: "bg-cyan-400" },
|
||||||
|
].map((c) => (
|
||||||
|
<div key={c.name} className="text-center">
|
||||||
|
<div
|
||||||
|
className={`${c.className} h-16 rounded-lg border border-white/10`}
|
||||||
|
/>
|
||||||
|
<p className="text-[10px] text-white/40 mt-1 font-mono">{c.name}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Font verification */}
|
||||||
|
<div className="mt-12 grid grid-cols-1 sm:grid-cols-2 gap-4 max-w-2xl w-full">
|
||||||
|
<div className="bg-surface border border-white/10 rounded-xl p-5">
|
||||||
|
<p className="font-label text-[10px] tracking-widest text-purple-300 uppercase mb-2">
|
||||||
|
Logo Font · Megrim
|
||||||
|
</p>
|
||||||
|
<p className="font-logo text-3xl tracking-widest">Cyber Star</p>
|
||||||
|
</div>
|
||||||
|
<div className="bg-surface border border-white/10 rounded-xl p-5">
|
||||||
|
<p className="font-label text-[10px] tracking-widest text-purple-300 uppercase mb-2">
|
||||||
|
Display Font · Audiowide
|
||||||
|
</p>
|
||||||
|
<p className="font-display text-3xl tracking-wider">VOTE 2026</p>
|
||||||
|
</div>
|
||||||
|
<div className="bg-surface border border-white/10 rounded-xl p-5">
|
||||||
|
<p className="font-label text-[10px] tracking-widest text-purple-300 uppercase mb-2">
|
||||||
|
Label Font · Cinzel
|
||||||
|
</p>
|
||||||
|
<p className="font-label text-xl tracking-widest font-semibold">
|
||||||
|
DEBUT PROJECT
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-4 text-base font-medium sm:flex-row">
|
<div className="bg-surface border border-white/10 rounded-xl p-5">
|
||||||
<a
|
<p className="font-label text-[10px] tracking-widest text-purple-300 uppercase mb-2">
|
||||||
className="flex h-12 w-full items-center justify-center gap-2 rounded-full bg-foreground px-5 text-background transition-colors hover:bg-[#383838] dark:hover:bg-[#ccc] md:w-[158px]"
|
Body Font · Inter
|
||||||
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
</p>
|
||||||
target="_blank"
|
<p className="font-body text-lg">虚拟偶像出道企划 · Aria</p>
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
<Image
|
|
||||||
className="dark:invert"
|
|
||||||
src="/vercel.svg"
|
|
||||||
alt="Vercel logomark"
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
/>
|
|
||||||
Deploy Now
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
className="flex h-12 w-full items-center justify-center rounded-full border border-solid border-black/[.08] px-5 transition-colors hover:border-transparent hover:bg-black/[.04] dark:border-white/[.145] dark:hover:bg-[#1a1a1a] md:w-[158px]"
|
|
||||||
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
Documentation
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p className="mt-16 text-white/40 text-xs font-mono">
|
||||||
|
Phase 3 → Layout + Navigation 即将开始
|
||||||
|
</p>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user