fix(*): 质量检查与版本发布 - 修复格式门禁和创作灵感兼容导出并发布 v1.6.2
This commit is contained in:
1 parent
04689257d2
commit
9174aae013
86 files changed
+22711
-634
No files matched your search
@@ -90,13 +90,21 @@ export default function InspirationsPage() {
|
||||
let cancelled = false;
|
||||
setLoadError("");
|
||||
loadInspirationCatalog()
|
||||
.then((loaded) => { if (!cancelled) setCatalog(loaded); })
|
||||
.catch((error) => { if (!cancelled) setLoadError(error instanceof Error ? error.message : "灵感目录加载失败"); });
|
||||
return () => { cancelled = true; };
|
||||
.then((loaded) => {
|
||||
if (!cancelled) setCatalog(loaded);
|
||||
})
|
||||
.catch((error) => {
|
||||
if (!cancelled) setLoadError(error instanceof Error ? error.message : "灵感目录加载失败");
|
||||
});
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [reloadKey]);
|
||||
|
||||
// 筛选条件一变就回第一页,否则会停在一个已经不存在的位置上。
|
||||
useEffect(() => { setPage(1); }, [source, modeFilter, category, view, sort, debouncedSearch, pageSize]);
|
||||
useEffect(() => {
|
||||
setPage(1);
|
||||
}, [source, modeFilter, category, view, sort, debouncedSearch, pageSize]);
|
||||
|
||||
const overlay = useMemo(() => ({ custom, overrides, hidden }), [custom, hidden, overrides]);
|
||||
const resolved = useMemo(() => (catalog ? resolveInspirations(catalog.entries, overlay) : []), [catalog, overlay]);
|
||||
@@ -136,9 +144,7 @@ export default function InspirationsPage() {
|
||||
merged.set(option.id, { label: option.label, count: (current?.count ?? 0) + option.count });
|
||||
}
|
||||
}
|
||||
return [...merged.entries()]
|
||||
.sort((left, right) => right[1].count - left[1].count || left[1].label.localeCompare(right[1].label, "zh-Hans-CN"))
|
||||
.map(([value, { label, count }]) => ({ value, label, count }));
|
||||
return [...merged.entries()].sort((left, right) => right[1].count - left[1].count || left[1].label.localeCompare(right[1].label, "zh-Hans-CN")).map(([value, { label, count }]) => ({ value, label, count }));
|
||||
}, [catalog, source]);
|
||||
|
||||
const sourceCounts = useMemo(() => {
|
||||
@@ -194,75 +200,101 @@ export default function InspirationsPage() {
|
||||
|
||||
const paged = useMemo(() => visible.slice((page - 1) * pageSize, page * pageSize), [visible, page, pageSize]);
|
||||
|
||||
const handleUse = useCallback((item: CreationInspiration) => {
|
||||
navigate("/create", { state: { inspirationPrompt: fillablePrompt(item), inspirationMode: item.mode } });
|
||||
}, [navigate]);
|
||||
const handleUse = useCallback(
|
||||
(item: CreationInspiration) => {
|
||||
navigate("/create", { state: { inspirationPrompt: fillablePrompt(item), inspirationMode: item.mode } });
|
||||
},
|
||||
[navigate],
|
||||
);
|
||||
|
||||
const handleCopy = useCallback((text: string, label: string) => {
|
||||
void navigator.clipboard.writeText(text).then(
|
||||
() => message.success(`${label}已复制`),
|
||||
() => message.error("复制失败,请手动选中文本"),
|
||||
);
|
||||
}, [message]);
|
||||
const handleCopy = useCallback(
|
||||
(text: string, label: string) => {
|
||||
void navigator.clipboard.writeText(text).then(
|
||||
() => message.success(`${label}已复制`),
|
||||
() => message.error("复制失败,请手动选中文本"),
|
||||
);
|
||||
},
|
||||
[message],
|
||||
);
|
||||
|
||||
const handleDelete = useCallback((item: CreationInspiration) => {
|
||||
const id = catalogIdOf(item);
|
||||
const isCustom = isCustomInspiration(id);
|
||||
modal.confirm({
|
||||
className: "workspace-modal workspace-modal-compact",
|
||||
title: isCustom ? "删除这条灵感?" : "从库中隐藏这条灵感?",
|
||||
content: isCustom
|
||||
? `「${item.title}」会从本地灵感库移除,此操作不可撤销。`
|
||||
: `「${item.title}」来自外部目录,不能真正删除;隐藏后可用「已隐藏」视图恢复,重新导入外部目录也不会让它复现。`,
|
||||
okText: isCustom ? "删除" : "隐藏",
|
||||
okButtonProps: { danger: true },
|
||||
cancelText: "保留",
|
||||
onOk: () => {
|
||||
removeEntry(id);
|
||||
if (detail && catalogIdOf(detail) === id) setDetail(null);
|
||||
message.success(isCustom ? "已删除" : "已隐藏");
|
||||
},
|
||||
});
|
||||
}, [detail, message, modal, removeEntry]);
|
||||
const handleDelete = useCallback(
|
||||
(item: CreationInspiration) => {
|
||||
const id = catalogIdOf(item);
|
||||
const isCustom = isCustomInspiration(id);
|
||||
modal.confirm({
|
||||
className: "workspace-modal workspace-modal-compact",
|
||||
title: isCustom ? "删除这条灵感?" : "从库中隐藏这条灵感?",
|
||||
content: isCustom ? `「${item.title}」会从本地灵感库移除,此操作不可撤销。` : `「${item.title}」来自外部目录,不能真正删除;隐藏后可用「已隐藏」视图恢复,重新导入外部目录也不会让它复现。`,
|
||||
okText: isCustom ? "删除" : "隐藏",
|
||||
okButtonProps: { danger: true },
|
||||
cancelText: "保留",
|
||||
onOk: () => {
|
||||
removeEntry(id);
|
||||
if (detail && catalogIdOf(detail) === id) setDetail(null);
|
||||
message.success(isCustom ? "已删除" : "已隐藏");
|
||||
},
|
||||
});
|
||||
},
|
||||
[detail, message, modal, removeEntry],
|
||||
);
|
||||
|
||||
const handleSubmit = useCallback((draft: Parameters<typeof createEntry>[0]) => {
|
||||
if (editing) {
|
||||
updateEntry(catalogIdOf(editing), draft);
|
||||
message.success("已保存修改");
|
||||
setDetail((current) => (current && catalogIdOf(current) === catalogIdOf(editing) ? { ...current, ...draft } : current));
|
||||
setEditing(null);
|
||||
return;
|
||||
}
|
||||
createEntry(draft);
|
||||
// 新建后把筛选整体清掉:自建条目的来源固定是「原创」、分类也常和当前筛选不符,
|
||||
// 不清的话用户刚点完"创建"却看不到自己建的东西。
|
||||
setSource("all");
|
||||
setModeFilter("all");
|
||||
setCategory("all");
|
||||
setView("all");
|
||||
setSearch("");
|
||||
message.success("灵感已创建");
|
||||
}, [createEntry, editing, message, updateEntry]);
|
||||
const handleSubmit = useCallback(
|
||||
(draft: Parameters<typeof createEntry>[0]) => {
|
||||
if (editing) {
|
||||
updateEntry(catalogIdOf(editing), draft);
|
||||
message.success("已保存修改");
|
||||
setDetail((current) => (current && catalogIdOf(current) === catalogIdOf(editing) ? { ...current, ...draft } : current));
|
||||
setEditing(null);
|
||||
return;
|
||||
}
|
||||
createEntry(draft);
|
||||
// 新建后把筛选整体清掉:自建条目的来源固定是「原创」、分类也常和当前筛选不符,
|
||||
// 不清的话用户刚点完"创建"却看不到自己建的东西。
|
||||
setSource("all");
|
||||
setModeFilter("all");
|
||||
setCategory("all");
|
||||
setView("all");
|
||||
setSearch("");
|
||||
message.success("灵感已创建");
|
||||
},
|
||||
[createEntry, editing, message, updateEntry],
|
||||
);
|
||||
|
||||
const handleExport = useCallback(() => {
|
||||
downloadText(exportPayload(), exportFileName());
|
||||
message.success("已导出本地改动(自建条目 / 改写 / 隐藏 / 收藏)");
|
||||
}, [exportPayload, message]);
|
||||
|
||||
const handleImportFile = useCallback(async (file: File) => {
|
||||
try {
|
||||
const result = importPayload(await file.text());
|
||||
message.success(`导入完成:新增 ${result.created},覆盖 ${result.updated}${result.skipped ? `,跳过 ${result.skipped} 条无效数据` : ""}`);
|
||||
} catch (error) {
|
||||
message.error(error instanceof Error ? error.message : "导入失败");
|
||||
}
|
||||
}, [importPayload, message]);
|
||||
const handleImportFile = useCallback(
|
||||
async (file: File) => {
|
||||
try {
|
||||
const result = importPayload(await file.text());
|
||||
message.success(`导入完成:新增 ${result.created},覆盖 ${result.updated}${result.skipped ? `,跳过 ${result.skipped} 条无效数据` : ""}`);
|
||||
} catch (error) {
|
||||
message.error(error instanceof Error ? error.message : "导入失败");
|
||||
}
|
||||
},
|
||||
[importPayload, message],
|
||||
);
|
||||
|
||||
const headerActions = (
|
||||
<>
|
||||
<Button icon={<Import className="size-4" />} onClick={() => importRef.current?.click()}>导入</Button>
|
||||
<Button icon={<Download className="size-4" />} onClick={handleExport}>导出</Button>
|
||||
<Button type="primary" icon={<Plus className="size-4" />} onClick={() => { setEditing(null); setEditorOpen(true); }}>新建灵感</Button>
|
||||
<Button icon={<Import className="size-4" />} onClick={() => importRef.current?.click()}>
|
||||
导入
|
||||
</Button>
|
||||
<Button icon={<Download className="size-4" />} onClick={handleExport}>
|
||||
导出
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<Plus className="size-4" />}
|
||||
onClick={() => {
|
||||
setEditing(null);
|
||||
setEditorOpen(true);
|
||||
}}
|
||||
>
|
||||
新建灵感
|
||||
</Button>
|
||||
<input
|
||||
ref={importRef}
|
||||
type="file"
|
||||
@@ -282,11 +314,7 @@ export default function InspirationsPage() {
|
||||
|
||||
return (
|
||||
<WorkspacePage>
|
||||
<PageHeader
|
||||
title="灵感库"
|
||||
description={`${total} 条提示词,按来源、分类和创作类型挑,点开可以一键带去创作页`}
|
||||
actions={headerActions}
|
||||
/>
|
||||
<PageHeader title="灵感库" description={`${total} 条提示词,按来源、分类和创作类型挑,点开可以一键带去创作页`} actions={headerActions} />
|
||||
|
||||
{loadError ? (
|
||||
<WorkspaceErrorState title="灵感目录加载失败" description={loadError} onRetry={() => setReloadKey((key) => key + 1)} />
|
||||
@@ -307,13 +335,7 @@ export default function InspirationsPage() {
|
||||
<span className="inspiration-chip-count">{source === "all" ? resolved.length : (sourceCounts.get(source) ?? 0)}</span>
|
||||
</button>
|
||||
{categoryChoices.slice(0, 16).map((choice) => (
|
||||
<button
|
||||
key={choice.value}
|
||||
type="button"
|
||||
className="inspiration-chip"
|
||||
aria-pressed={category === choice.value}
|
||||
onClick={() => setCategory(category === choice.value ? "all" : choice.value)}
|
||||
>
|
||||
<button key={choice.value} type="button" className="inspiration-chip" aria-pressed={category === choice.value} onClick={() => setCategory(category === choice.value ? "all" : choice.value)}>
|
||||
{choice.label}
|
||||
<span className="inspiration-chip-count">{choice.count}</span>
|
||||
</button>
|
||||
@@ -321,14 +343,7 @@ export default function InspirationsPage() {
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<Input
|
||||
allowClear
|
||||
prefix={<Search className="size-4 text-foreground/40" />}
|
||||
placeholder="搜标题、描述或标签"
|
||||
value={search}
|
||||
onChange={(event) => setSearch(event.target.value)}
|
||||
className="max-w-xs"
|
||||
/>
|
||||
<Input allowClear prefix={<Search className="size-4 text-foreground/40" />} placeholder="搜标题、描述或标签" value={search} onChange={(event) => setSearch(event.target.value)} className="max-w-xs" />
|
||||
<SegmentedControl options={VIEW_OPTIONS} value={view} onChange={(value) => setView(value as ViewFilter)} />
|
||||
<Select
|
||||
options={[
|
||||
@@ -339,7 +354,10 @@ export default function InspirationsPage() {
|
||||
})),
|
||||
]}
|
||||
value={source}
|
||||
onChange={(value) => { setSource(value as SourceFilter); setCategory("all"); }}
|
||||
onChange={(value) => {
|
||||
setSource(value as SourceFilter);
|
||||
setCategory("all");
|
||||
}}
|
||||
className="w-52"
|
||||
/>
|
||||
<Select options={SORT_OPTIONS} value={sort} onChange={(value) => setSort(value as SortKey)} className="w-32" />
|
||||
@@ -370,13 +388,28 @@ export default function InspirationsPage() {
|
||||
<span className="inspiration-card-source">{inspirationSourceOf(item).label}</span>
|
||||
<div className="inspiration-card-actions">
|
||||
<Tooltip title={favorite ? "取消收藏" : "收藏"}>
|
||||
<button type="button" className="inspiration-card-action" aria-pressed={favorite} onClick={(event) => { event.stopPropagation(); toggleFavorite(id); }}>
|
||||
<button
|
||||
type="button"
|
||||
className="inspiration-card-action"
|
||||
aria-pressed={favorite}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
toggleFavorite(id);
|
||||
}}
|
||||
>
|
||||
<Heart className="size-3.5" fill={favorite ? "currentColor" : "none"} />
|
||||
</button>
|
||||
</Tooltip>
|
||||
{view === "hidden" ? (
|
||||
<Tooltip title="恢复显示">
|
||||
<button type="button" className="inspiration-card-action" onClick={(event) => { event.stopPropagation(); restoreEntry(id); }}>
|
||||
<button
|
||||
type="button"
|
||||
className="inspiration-card-action"
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
restoreEntry(id);
|
||||
}}
|
||||
>
|
||||
<RotateCcw className="size-3.5" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
@@ -390,7 +423,10 @@ export default function InspirationsPage() {
|
||||
],
|
||||
onClick: ({ key, domEvent }) => {
|
||||
domEvent.stopPropagation();
|
||||
if (key === "edit") { setEditing(item); setEditorOpen(true); }
|
||||
if (key === "edit") {
|
||||
setEditing(item);
|
||||
setEditorOpen(true);
|
||||
}
|
||||
if (key === "delete") handleDelete(item);
|
||||
},
|
||||
}}
|
||||
@@ -423,7 +459,15 @@ export default function InspirationsPage() {
|
||||
/>
|
||||
)}
|
||||
|
||||
<PaginationBar current={page} pageSize={pageSize} total={visible.length} onChange={(next, size) => { setPage(next); setPageSize(size); }} />
|
||||
<PaginationBar
|
||||
current={page}
|
||||
pageSize={pageSize}
|
||||
total={visible.length}
|
||||
onChange={(next, size) => {
|
||||
setPage(next);
|
||||
setPageSize(size);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -435,7 +479,11 @@ export default function InspirationsPage() {
|
||||
onUse={handleUse}
|
||||
onCopy={handleCopy}
|
||||
onToggleFavorite={(item) => toggleFavorite(catalogIdOf(item))}
|
||||
onEdit={(item) => { setDetail(null); setEditing(item); setEditorOpen(true); }}
|
||||
onEdit={(item) => {
|
||||
setDetail(null);
|
||||
setEditing(item);
|
||||
setEditorOpen(true);
|
||||
}}
|
||||
onDelete={handleDelete}
|
||||
/>
|
||||
|
||||
@@ -443,7 +491,10 @@ export default function InspirationsPage() {
|
||||
open={editorOpen}
|
||||
item={editing}
|
||||
categoryOptions={categoryChoices}
|
||||
onClose={() => { setEditorOpen(false); setEditing(null); }}
|
||||
onClose={() => {
|
||||
setEditorOpen(false);
|
||||
setEditing(null);
|
||||
}}
|
||||
onSubmit={handleSubmit}
|
||||
/>
|
||||
</WorkspacePage>
|
||||
|
||||
@@ -41,14 +41,7 @@ export function InspirationDetailModal({
|
||||
const custom = item ? isCustomInspiration(catalogIdOf(item)) : false;
|
||||
|
||||
return (
|
||||
<AppModal
|
||||
open={Boolean(item)}
|
||||
onCancel={onClose}
|
||||
width={880}
|
||||
title={null}
|
||||
footer={null}
|
||||
styles={{ body: { padding: 0 } }}
|
||||
>
|
||||
<AppModal open={Boolean(item)} onCancel={onClose} width={880} title={null} footer={null}>
|
||||
{item ? (
|
||||
<div className="flex max-h-[76vh] flex-col">
|
||||
<div className="relative shrink-0 overflow-hidden" style={{ borderRadius: "var(--r-xl, 14px)" }}>
|
||||
@@ -68,22 +61,36 @@ export function InspirationDetailModal({
|
||||
</button>
|
||||
</Tooltip>
|
||||
<Tooltip title="编辑">
|
||||
<button type="button" className="inspiration-icon-button" onClick={() => onEdit(item)}><Pencil className="size-4" /></button>
|
||||
<button type="button" className="inspiration-icon-button" onClick={() => onEdit(item)}>
|
||||
<Pencil className="size-4" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
<Tooltip title={custom ? "删除" : "从库中隐藏"}>
|
||||
<button type="button" className="inspiration-icon-button" onClick={() => onDelete(item)}><Trash2 className="size-4" /></button>
|
||||
<button type="button" className="inspiration-icon-button" onClick={() => onDelete(item)}>
|
||||
<Trash2 className="size-4" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<MetaRow label="来源">{source?.name ?? "原创"}{item.credit ? ` · ${item.credit}` : ""}</MetaRow>
|
||||
<MetaRow label="来源">
|
||||
{source?.name ?? "原创"}
|
||||
{item.credit ? ` · ${item.credit}` : ""}
|
||||
</MetaRow>
|
||||
<MetaRow label="分类">{categoryLabel(item)}</MetaRow>
|
||||
<MetaRow label="类型">{modeLabels[item.mode]}{item.ratio ? ` · ${item.ratio}` : ""}</MetaRow>
|
||||
<MetaRow label="类型">
|
||||
{modeLabels[item.mode]}
|
||||
{item.ratio ? ` · ${item.ratio}` : ""}
|
||||
</MetaRow>
|
||||
{item.tags?.length ? (
|
||||
<MetaRow label="标签">
|
||||
<span className="flex flex-wrap gap-1.5">
|
||||
{item.tags.map((tag) => <span key={tag} className="inspiration-chip">{tag}</span>)}
|
||||
{item.tags.map((tag) => (
|
||||
<span key={tag} className="inspiration-chip">
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
</span>
|
||||
</MetaRow>
|
||||
) : null}
|
||||
@@ -102,7 +109,9 @@ export function InspirationDetailModal({
|
||||
|
||||
<div className="flex shrink-0 items-center justify-end gap-2 border-t border-foreground/8 px-5 py-3">
|
||||
<Button onClick={onClose}>关闭</Button>
|
||||
<Button type="primary" icon={<Wand2 className="size-4" />} onClick={() => onUse(item)}>用这个创意创作</Button>
|
||||
<Button type="primary" icon={<Wand2 className="size-4" />} onClick={() => onUse(item)}>
|
||||
用这个创意创作
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
@@ -115,7 +124,9 @@ function PromptSection({ label, text, onCopy }: { label: string; text: string; o
|
||||
<section className="flex flex-col gap-2">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<h3 className="text-xs font-medium text-foreground/58">{label}</h3>
|
||||
<Button size="small" icon={<Copy className="size-3.5" />} onClick={() => onCopy(text, label)}>复制</Button>
|
||||
<Button size="small" icon={<Copy className="size-3.5" />} onClick={() => onCopy(text, label)}>
|
||||
复制
|
||||
</Button>
|
||||
</div>
|
||||
<div className="inspiration-prompt-block">{text}</div>
|
||||
</section>
|
||||
|
||||
@@ -77,12 +77,26 @@ export function InspirationEditorModal({
|
||||
open={open}
|
||||
title={item ? "编辑灵感" : "新建灵感"}
|
||||
width={720}
|
||||
onCancel={() => { form.resetFields(); onClose(); }}
|
||||
afterOpenChange={(visible) => { if (visible) form.setFieldsValue(toFormValues(item)); }}
|
||||
onCancel={() => {
|
||||
form.resetFields();
|
||||
onClose();
|
||||
}}
|
||||
afterOpenChange={(visible) => {
|
||||
if (visible) form.setFieldsValue(toFormValues(item));
|
||||
}}
|
||||
footer={
|
||||
<div className="flex justify-end gap-2">
|
||||
<Button onClick={() => { form.resetFields(); onClose(); }}>取消</Button>
|
||||
<Button type="primary" onClick={() => void handleOk()}>{item ? "保存" : "创建"}</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
form.resetFields();
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
取消
|
||||
</Button>
|
||||
<Button type="primary" onClick={() => void handleOk()}>
|
||||
{item ? "保存" : "创建"}
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
transform var(--user-motion, 180ms) cubic-bezier(.2, .8, .3, 1),
|
||||
transform var(--user-motion, 180ms) cubic-bezier(0.2, 0.8, 0.3, 1),
|
||||
box-shadow var(--user-motion, 180ms) ease,
|
||||
border-color var(--user-motion, 180ms) ease;
|
||||
}
|
||||
@@ -49,7 +49,7 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
transition: transform 420ms cubic-bezier(.2, .8, .3, 1);
|
||||
transition: transform 420ms cubic-bezier(0.2, 0.8, 0.3, 1);
|
||||
}
|
||||
|
||||
.inspiration-card:hover .inspiration-card-cover img {
|
||||
@@ -62,7 +62,7 @@
|
||||
position: absolute;
|
||||
inset: auto 0 0;
|
||||
height: 46%;
|
||||
background: linear-gradient(transparent, rgba(0, 0, 0, .58));
|
||||
background: linear-gradient(transparent, rgba(0, 0, 0, 0.58));
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
z-index: 1;
|
||||
padding: 3px var(--space-2, 8px);
|
||||
border-radius: var(--r-full, 999px);
|
||||
background: rgba(20, 22, 26, .48);
|
||||
background: rgba(20, 22, 26, 0.48);
|
||||
color: #fff;
|
||||
font-size: var(--fs-tiny, 10px);
|
||||
line-height: 1.6;
|
||||
@@ -104,8 +104,8 @@
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
color: #fff;
|
||||
background: rgba(20, 22, 26, .5);
|
||||
border: 1px solid rgba(255, 255, 255, .18);
|
||||
background: rgba(20, 22, 26, 0.5);
|
||||
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||
border-radius: var(--r-full, 999px);
|
||||
cursor: pointer;
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
@@ -114,7 +114,7 @@
|
||||
}
|
||||
|
||||
.inspiration-card-action:hover {
|
||||
background: rgba(20, 22, 26, .72);
|
||||
background: rgba(20, 22, 26, 0.72);
|
||||
}
|
||||
|
||||
.inspiration-card-action.is-on {
|
||||
@@ -197,7 +197,7 @@
|
||||
/* 标签里的计数:比正文弱一档,但仍要在两种底色上都读得出来。 */
|
||||
.inspiration-chip-count {
|
||||
font-variant-numeric: tabular-nums;
|
||||
opacity: .58;
|
||||
opacity: 0.58;
|
||||
}
|
||||
|
||||
/* 卡片上的分类/署名标签是纯展示,不参与点击,去掉指针与悬停反馈。 */
|
||||
|
||||
Reference in new issue
Block a user