Compare commits

..

No commits in common. "v0.2.2" and "v0.2.1" have entirely different histories.

8 changed files with 28 additions and 42 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 358 KiB

View File

@ -35,7 +35,7 @@ export default function HeroBanner({
if (!v || !videoSrc) return;
v.muted = isMuted;
v.play().catch(() => {});
// 仅在 videoSrc 变化时执行 · 不依赖 isMuted(mute 切换由按钮处理)
// 仅在 videoSrc 变化时执行 · 不依赖 isMutedmute 切换由按钮处理)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [videoSrc]);
@ -93,7 +93,7 @@ export default function HeroBanner({
{/* Eyebrow 左上 · 紧贴导航下方 */}
<div className="absolute top-[6.5rem] sm:top-[7.5rem] left-4 sm:left-6 lg:left-8 z-10">
<p className="font-label text-[10px] sm:text-xs tracking-[0.4em] uppercase text-purple-200/90">
Top 12 · Cyber Star Debut Survival
Top 12 · Virtual Idol Debut Project
</p>
</div>

View File

@ -25,10 +25,9 @@ export default function Logo({
// 用原生 <img> 绕开 Next/Image 的格式转换 —— 某些环境下 sharp 把透明 PNG
// 转 webp/avif 时会铺白底,导致 logo 在深色 nav 上出现白色矩形。
// ?v=2 缓存破坏:logo 改版时 +1,浏览器立刻拉新版而不读老缓存。
const inner = (
<img
src="/logo.png?v=3"
src="/logo.png"
alt="CYBER STAR"
decoding="async"
draggable={false}
@ -36,6 +35,8 @@ export default function Logo({
height: `${h}px`,
width: "auto",
background: "transparent",
// 保留紫色辉光,但 drop-shadow 不会引入白底
filter: "drop-shadow(0 0 14px rgba(139,92,246,0.4))",
}}
className={`block select-none ${className}`}
/>

View File

@ -2,6 +2,7 @@
import { useEffect, useState } from "react";
import { usePathname } from "next/navigation";
import Logo from "./Logo";
import NavLinks from "./NavLinks";
import SearchTrigger from "./SearchTrigger";
import AuthMenu from "./auth/AuthMenu";
@ -81,7 +82,9 @@ export default function Navigation() {
)}
/>
<nav className="relative max-w-[1500px] mx-auto h-20 px-4 sm:px-6 lg:px-8 flex items-center gap-8">
{/* 左侧:首页 / 排行榜 / 我的(logo 已移除) */}
<Logo size="md" />
{/* 中部:首页 / 排行榜 / 我的 */}
<NavLinks className="hidden md:flex" />
{/* 右侧:搜索 + 今日余票 + 登录/注册 (或 头像+下拉) */}

View File

@ -40,8 +40,8 @@ export default function ArtistCard({
className="block"
aria-label={`查看 ${artist.name} 详情`}
>
{/* 立绘区 · Top12 区分仅靠紫色边框 + 辉光,不再降低非 Top12 卡片亮度 */}
<div className="relative aspect-[4/5]">
{/* 立绘区13+ 卡片轻度暗化) */}
<div className={cn("relative aspect-[4/5]", !inTop12 && "opacity-[0.78]")}>
<ArtistPortrait
artist={artist}
rounded="rounded-none"
@ -59,6 +59,9 @@ export default function ArtistCard({
>
{artist.rank}
</div>
{/* 顶部轻微渐变蒙层 */}
<div className="absolute inset-x-0 top-0 h-12 bg-gradient-to-b from-black/40 to-transparent pointer-events-none" />
</div>
{/* 信息区(黑色背景明显分隔) */}

View File

@ -324,7 +324,7 @@ export const ARTIST_SEEDS: ArtistSeed[] = [
{
no: `021`,
name: `温景然`,
enName: `KINGSTON`,
enName: `RYAN`,
age: 27,
gender: `M`,
height: 178,

View File

@ -11,34 +11,22 @@ import { tosUrl } from "./tos";
* / store
*/
/** solo.mp4 (docx "")
003/010/017/027 v2 ,033 , */
const MISSING_VIDEO: ReadonlySet<string> = new Set<string>();
/** 没有 solo.mp4 的艺人编号docx 标注"缺视频" */
const MISSING_VIDEO: ReadonlySet<string> = new Set(["003", "010", "017", "027"]);
/**
* 自定义封面:这些艺人的卡片/ cover ,
* 11/2/3
* (.xlsx "封面图用氛围图N" webp
* portraits/{no}-cover.webp, portrait )
*/
const CUSTOM_COVERS: ReadonlySet<string> = new Set([
"002",
"003",
"005",
"012",
"013",
"014",
"019",
"025",
]);
/** 缺氛围图3 的艺人编号资料文件夹里实际只到氛围图2 */
const MISSING_ATMOSPHERE_3: ReadonlySet<string> = new Set(["036"]);
/** 画廊 = 三张氛围图1/2/3。不包含三视图因为长宽比与卡片不一致。 */
function buildGallery(no: string): string[] {
return [
const items = [
tosUrl(`portraits/${no}.webp`),
tosUrl(`portraits/${no}-2.webp`),
tosUrl(`portraits/${no}-3.webp`),
];
if (!MISSING_ATMOSPHERE_3.has(no)) {
items.push(tosUrl(`portraits/${no}-3.webp`));
}
return items;
}
function buildArtists(): Artist[] {
@ -51,11 +39,7 @@ function buildArtists(): Artist[] {
age: seed.age,
gender: seed.gender,
bio: seed.bio,
portrait: tosUrl(
CUSTOM_COVERS.has(seed.no)
? `portraits/${seed.no}-cover.webp`
: `portraits/${seed.no}.webp`,
),
portrait: tosUrl(`portraits/${seed.no}.webp`),
avatar: "",
gallery: buildGallery(seed.no),
videoUrl: MISSING_VIDEO.has(seed.no)

View File

@ -3,21 +3,16 @@
*
* :
* tosUrl("portraits/001.webp")
* https://cyberstar.tos-cn-shanghai.volces.com/cyber-star/portraits/001.webp?v=2
* https://cyberstar.tos-cn-shanghai.volces.com/cyber-star/portraits/001.webp
*
* NEXT_PUBLIC_TOS_DOMAIN :
* .env.local / .env.production + ( scheme, /)
* fallback (/path/...), public/
*
* TOS_VERSION:每次有 TOS (/),
* +1 CDN URL ,
* , TTL invalidate
*/
const TOS_BASE = (process.env.NEXT_PUBLIC_TOS_DOMAIN ?? "").replace(/\/+$/, "");
const TOS_VERSION = "7";
export function tosUrl(path: string): string {
const clean = path.replace(/^\/+/, "");
const base = TOS_BASE ? `${TOS_BASE}/${clean}` : `/${clean}`;
return `${base}?v=${TOS_VERSION}`;
if (!TOS_BASE) return `/${clean}`;
return `${TOS_BASE}/${clean}`;
}