fix: refine glass workbench rail and theme colors

This commit is contained in:
2026-05-21 12:37:27 +08:00
parent a48c2965d9
commit 36da23beb2
3 changed files with 284 additions and 73 deletions

View File

@@ -2515,11 +2515,11 @@ export function AdRecreationBoard({
<p className="mt-2 truncate text-[12px] text-white/42"></p>
</div>
<div className="grid min-w-[440px] grid-cols-5 gap-2 text-[11px]">
<Metric label="素材" value={`${jobs.length}`} />
<Metric label="当前" value={shortId(activeJobId)} />
<Metric label="视频" value={job?.video_url ? "ready" : "-"} />
<Metric label="文案段" value={`${transcriptCount}`} />
<Metric label="背景音" value={backgroundReady ? "ready" : "-"} />
<Metric label="素材" value={`${jobs.length}`} variant="violet" />
<Metric label="当前" value={shortId(activeJobId)} variant="lime" />
<Metric label="视频" value={job?.video_url ? "ready" : "-"} variant="gold" />
<Metric label="文案段" value={`${transcriptCount}`} variant="teal" />
<Metric label="背景音" value={backgroundReady ? "ready" : "-"} variant="green" />
</div>
</header>
@@ -2599,27 +2599,38 @@ function WorkbenchRail({
boardTheme: BoardThemeMode
materialPanel: ReactNode
}) {
const [hoverOpen, setHoverOpen] = useState(false)
const railOpen = materialOpen || hoverOpen
return (
<aside className={`skg-board-rail sticky top-4 flex shrink-0 items-stretch ${materialOpen ? "is-open" : ""}`} aria-label="工作台工具栏">
<aside
className={`skg-board-rail sticky flex shrink-0 items-stretch ${railOpen ? "is-open" : ""}`}
aria-label="工作台工具栏"
onMouseEnter={() => setHoverOpen(true)}
onMouseLeave={() => setHoverOpen(false)}
onFocus={() => setHoverOpen(true)}
onBlur={(event) => {
const nextTarget = event.relatedTarget
if (!(nextTarget instanceof Node) || !event.currentTarget.contains(nextTarget)) setHoverOpen(false)
}}
>
<div className="skg-board-rail__strip flex shrink-0 items-stretch gap-3" aria-label="工作台导航与素材输入">
<div className="skg-board-rail__iconbar flex shrink-0 flex-col items-center py-5" aria-label="工作台导航">
<div className="skg-board-rail__logo mb-8 flex h-9 w-9 items-center justify-center rounded-full text-[12px] font-semibold" title="SKG Marketing Studio">
S
</div>
<nav className="flex flex-1 flex-col items-center gap-4">
<nav className="flex flex-col items-center gap-4">
<button
type="button"
onClick={onToggleMaterial}
className={`skg-board-rail__button inline-flex h-9 w-9 items-center justify-center rounded-full ${materialOpen ? "is-active" : ""}`}
className={`skg-board-rail__button inline-flex h-9 w-9 items-center justify-center rounded-full ${railOpen ? "is-active" : ""}`}
title={jobsCount ? `素材任务 · ${jobsCount}` : "素材任务"}
aria-label="素材任务"
aria-expanded={materialOpen}
aria-expanded={railOpen}
aria-controls="skg-material-rail-panel"
>
<Link2 className="h-[18px] w-[18px]" />
</button>
</nav>
<div className="mt-8 flex flex-col items-center gap-3">
<button
type="button"
onClick={onOpenLibrary}
@@ -2638,10 +2649,10 @@ function WorkbenchRail({
>
{boardTheme === "dark" ? <Sun className="h-[18px] w-[18px]" /> : <Moon className="h-[18px] w-[18px]" />}
</button>
</div>
</nav>
</div>
{materialOpen ? (
{railOpen ? (
<div id="skg-material-rail-panel" className="skg-board-rail__drawer w-[320px] shrink-0">
{materialPanel}
</div>
@@ -7330,7 +7341,7 @@ function AudioWaveform({
}, [features])
return (
<div
className="relative h-24 cursor-pointer overflow-hidden rounded-md border border-white/10 bg-black/35 px-2"
className="skg-audio-waveform relative h-24 cursor-pointer overflow-hidden rounded-md border px-2"
aria-label="音频响度波形"
onClick={(event) => {
const rect = event.currentTarget.getBoundingClientRect()
@@ -7348,24 +7359,24 @@ function AudioWaveform({
{status === "failed" ? "audio.wav 解码失败" : status === "loading" ? "正在解码 audio.wav" : "等待音频文件"}
</div>
)}
<div className="absolute inset-x-0 top-1/2 h-px bg-white/14" />
<div className="skg-audio-waveform__center absolute inset-x-0 top-1/2 h-px" />
{hasFeatures && (
<svg className="pointer-events-none absolute inset-0 h-full w-full overflow-visible" viewBox="0 0 100 100" preserveAspectRatio="none">
<polygon
points={envelopePoints}
fill="rgba(209,213,219,0.74)"
fill="var(--skg-wave-fill)"
/>
<polyline
points={topPoints}
fill="none"
stroke="rgba(229,231,235,0.7)"
stroke="var(--skg-wave-stroke-1)"
strokeWidth="0.55"
vectorEffect="non-scaling-stroke"
/>
<polyline
points={bottomPoints}
fill="none"
stroke="rgba(229,231,235,0.52)"
stroke="var(--skg-wave-stroke-2)"
strokeWidth="0.55"
vectorEffect="non-scaling-stroke"
/>
@@ -7375,18 +7386,18 @@ function AudioWaveform({
{segments.map((segment, index) => (
<div
key={`${segment.start}-${index}`}
className="absolute inset-y-0 w-px bg-white/12"
className="skg-audio-waveform__segment absolute inset-y-0 w-px"
style={{ left: `${clampNumber((segment.start / Math.max(duration, 1)) * 100, 0, 100)}%` }}
/>
))}
{hoverPct !== null && (
<div
className="pointer-events-none absolute inset-y-0 w-px bg-cyan-100/70"
className="skg-audio-waveform__hover pointer-events-none absolute inset-y-0 w-px"
style={{ left: `${hoverPct}%` }}
/>
)}
<div
className="pointer-events-none absolute inset-y-0 w-[2px] bg-emerald-200 shadow-[0_0_16px_rgba(110,231,183,0.85)] will-change-[left]"
className="skg-audio-waveform__playhead pointer-events-none absolute inset-y-0 w-[2px] will-change-[left]"
style={{ left: `${pointerPct}%` }}
/>
</div>
@@ -7990,9 +8001,11 @@ function MaterialCard({
)
}
function Metric({ label, value, compact }: { label: string; value: string; compact?: boolean }) {
type MetricVariant = "violet" | "lime" | "gold" | "teal" | "green"
function Metric({ label, value, compact, variant }: { label: string; value: string; compact?: boolean; variant?: MetricVariant }) {
return (
<div className={`skg-stat-card ${compact ? "px-2 py-1" : "px-2.5 py-1.5"}`}>
<div className={`skg-stat-card ${variant ? `skg-stat-card--${variant}` : ""} ${compact ? "px-2 py-1" : "px-2.5 py-1.5"}`}>
<div className="skg-stat-card__label">{label}</div>
<div className="skg-stat-card__value mt-0.5 truncate font-mono text-[13px] font-semibold">{value}</div>
</div>