feat(ui): content-first shelf redesign — responsive cover grid, hover overlays, format badges, skeletons, sticky blurred top bar, brand login, SVG icon set, animated toasts
This commit is contained in:
@@ -1,7 +1,38 @@
|
||||
import type { Format } from "../api/types";
|
||||
|
||||
export const btn =
|
||||
"rounded-lg bg-stone-800 px-3 py-1.5 text-sm transition-colors hover:bg-stone-700 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-amber-500 active:bg-stone-600 disabled:cursor-not-allowed disabled:opacity-50";
|
||||
"inline-flex items-center gap-1.5 rounded-lg bg-white/[0.06] px-3 py-1.5 text-sm ring-1 ring-white/10 transition-colors hover:bg-white/[0.11] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-amber-500 active:bg-white/[0.15] disabled:cursor-not-allowed disabled:opacity-50";
|
||||
export const btnPrimary =
|
||||
"rounded-lg bg-amber-600 px-3 py-1.5 text-sm text-stone-950 transition-colors hover:bg-amber-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-amber-500 active:bg-amber-400 disabled:cursor-not-allowed disabled:opacity-50";
|
||||
"inline-flex items-center gap-1.5 rounded-lg bg-amber-500 px-3 py-1.5 text-sm font-medium text-stone-950 shadow-md shadow-amber-500/20 transition-colors hover:bg-amber-400 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-amber-500 active:bg-amber-300 disabled:cursor-not-allowed disabled:opacity-50";
|
||||
export const btnGhost =
|
||||
"inline-flex items-center gap-1.5 rounded-lg px-2.5 py-1.5 text-sm text-stone-400 transition-colors hover:bg-white/[0.07] hover:text-stone-100 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-amber-500";
|
||||
export const input =
|
||||
"rounded-lg border border-stone-700 bg-stone-900 px-3 py-1.5 text-sm outline-none transition-colors placeholder:text-stone-500 focus:border-amber-500/70";
|
||||
export const card = "rounded-xl border border-stone-800 bg-stone-900";
|
||||
"rounded-lg bg-white/[0.04] px-3 py-1.5 text-sm ring-1 ring-white/10 outline-none transition placeholder:text-stone-500 focus:bg-white/[0.06] focus:ring-2 focus:ring-amber-500/60";
|
||||
export const card = "rounded-xl bg-stone-900/70 ring-1 ring-white/[0.07]";
|
||||
|
||||
// 库/筛选分段 pill
|
||||
export const pill =
|
||||
"rounded-full px-3.5 py-1.5 text-sm text-stone-400 ring-1 ring-transparent transition-colors hover:bg-white/[0.07] hover:text-stone-100 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-amber-500";
|
||||
export const pillActive = "bg-amber-500/15 text-amber-300 ring-amber-500/30 hover:bg-amber-500/20 hover:text-amber-200";
|
||||
|
||||
// 格式徽章:按类型着色,色彩之外始终伴随文字,不依赖颜色单独传义
|
||||
export const FORMAT_BADGE: Record<Format, string> = {
|
||||
cbz: "bg-orange-500/15 text-orange-300 ring-orange-500/25",
|
||||
pdf: "bg-rose-500/15 text-rose-300 ring-rose-500/25",
|
||||
epub: "bg-sky-500/15 text-sky-300 ring-sky-500/25",
|
||||
txt: "bg-emerald-500/15 text-emerald-300 ring-emerald-500/25",
|
||||
md: "bg-teal-500/15 text-teal-300 ring-teal-500/25",
|
||||
};
|
||||
|
||||
export function formatBadge(fmt: Format, extra = ""): string {
|
||||
return `rounded px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide ring-1 ${FORMAT_BADGE[fmt]} ${extra}`;
|
||||
}
|
||||
|
||||
export function formatSize(bytes: number): string {
|
||||
if (bytes <= 0) return "";
|
||||
const units = ["B", "KB", "MB", "GB"];
|
||||
let i = 0;
|
||||
let n = bytes;
|
||||
for (; n >= 1024 && i < units.length - 1; i++) n /= 1024;
|
||||
return `${n >= 10 || i === 0 ? Math.round(n) : n.toFixed(1)} ${units[i]}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user