style(theme): 深色模式配色由 slate 换成 zinc,去掉整页蓝调

slate 色阶带明显蓝调(页面底 B-R=+22、列底 +26),整页发蓝,与目标的中性灰
相差很远。换成 Tailwind 的 zinc 色阶做 1:1 映射,保持原有明暗层次不变
(卡片仍比列背景更亮),只去色偏:改后页面底 B-R=+2、列底 +2。

只替换带 dark: 前缀的类(16 个文件、182 处),外加 style.css 里三处
html.dark 基底色;浅色模式一字未动(页面底仍为 slate-100 #f1f5f9)。
This commit is contained in:
chenshoulin
2026-10-18 19:45:23 +08:00
parent b27fefb965
commit 85b2d8a30f
17 changed files with 103 additions and 99 deletions
+8 -8
View File
@@ -45,7 +45,7 @@ useKeyboardShortcuts({
</script> </script>
<template> <template>
<div class="flex h-full min-h-0 flex-col bg-slate-100 dark:bg-slate-950"> <div class="flex h-full min-h-0 flex-col bg-slate-100 dark:bg-zinc-950">
<AppNav /> <AppNav />
<main class="flex min-h-0 flex-1 flex-col"> <main class="flex min-h-0 flex-1 flex-col">
@@ -56,37 +56,37 @@ useKeyboardShortcuts({
<BackupPanel :open="ui.backupOpen" @close="ui.closeBackup()" /> <BackupPanel :open="ui.backupOpen" @close="ui.closeBackup()" />
<SideDrawer :open="ui.helpOpen" title="快捷键" @close="ui.closeHelp()"> <SideDrawer :open="ui.helpOpen" title="快捷键" @close="ui.closeHelp()">
<h3 class="mb-2 text-xs font-medium tracking-wide text-slate-400 uppercase dark:text-slate-500"> <h3 class="mb-2 text-xs font-medium tracking-wide text-slate-400 uppercase dark:text-zinc-500">
全局 全局
</h3> </h3>
<dl class="flex flex-col gap-3 text-sm"> <dl class="flex flex-col gap-3 text-sm">
<div v-for="item in SHORTCUTS" :key="item.keys" class="flex items-center gap-3"> <div v-for="item in SHORTCUTS" :key="item.keys" class="flex items-center gap-3">
<dt <dt
class="w-14 shrink-0 rounded-md border border-slate-200 bg-slate-50 px-2 py-0.5 text-center font-mono text-xs text-slate-600 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-300" class="w-14 shrink-0 rounded-md border border-slate-200 bg-slate-50 px-2 py-0.5 text-center font-mono text-xs text-slate-600 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-300"
> >
{{ item.keys }} {{ item.keys }}
</dt> </dt>
<dd class="text-slate-600 dark:text-slate-300">{{ item.description }}</dd> <dd class="text-slate-600 dark:text-zinc-300">{{ item.description }}</dd>
</div> </div>
</dl> </dl>
<h3 <h3
class="mt-6 mb-2 text-xs font-medium tracking-wide text-slate-400 uppercase dark:text-slate-500" class="mt-6 mb-2 text-xs font-medium tracking-wide text-slate-400 uppercase dark:text-zinc-500"
> >
卡片聚焦后 卡片聚焦后
</h3> </h3>
<dl class="flex flex-col gap-3 text-sm"> <dl class="flex flex-col gap-3 text-sm">
<div v-for="item in CARD_SHORTCUTS" :key="item.keys" class="flex items-center gap-3"> <div v-for="item in CARD_SHORTCUTS" :key="item.keys" class="flex items-center gap-3">
<dt <dt
class="w-14 shrink-0 rounded-md border border-slate-200 bg-slate-50 px-2 py-0.5 text-center font-mono text-xs text-slate-600 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-300" class="w-14 shrink-0 rounded-md border border-slate-200 bg-slate-50 px-2 py-0.5 text-center font-mono text-xs text-slate-600 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-300"
> >
{{ item.keys }} {{ item.keys }}
</dt> </dt>
<dd class="text-slate-600 dark:text-slate-300">{{ item.description }}</dd> <dd class="text-slate-600 dark:text-zinc-300">{{ item.description }}</dd>
</div> </div>
</dl> </dl>
<p class="mt-4 text-xs text-slate-400 dark:text-slate-500"> <p class="mt-4 text-xs text-slate-400 dark:text-zinc-500">
在输入框内输入时不会触发快捷键。 在输入框内输入时不会触发快捷键。
</p> </p>
</SideDrawer> </SideDrawer>
+9 -9
View File
@@ -15,11 +15,11 @@ const LINKS = [
<template> <template>
<header <header
class="flex items-center gap-3 border-b border-slate-200 bg-white/85 px-4 py-2.5 backdrop-blur-sm md:px-6 dark:border-slate-800 dark:bg-slate-900/85" class="flex items-center gap-3 border-b border-slate-200 bg-white/85 px-4 py-2.5 backdrop-blur-sm md:px-6 dark:border-zinc-800 dark:bg-zinc-900/85"
> >
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<span <span
class="flex size-6 shrink-0 items-center justify-center rounded-md bg-slate-900 text-white dark:bg-slate-100 dark:text-slate-900" class="flex size-6 shrink-0 items-center justify-center rounded-md bg-slate-900 text-white dark:bg-zinc-100 dark:text-zinc-900"
> >
<svg viewBox="0 0 16 16" class="size-3.5" aria-hidden="true"> <svg viewBox="0 0 16 16" class="size-3.5" aria-hidden="true">
<rect x="1" y="2" width="3.4" height="12" rx="1.2" fill="currentColor" opacity="0.5" /> <rect x="1" y="2" width="3.4" height="12" rx="1.2" fill="currentColor" opacity="0.5" />
@@ -28,13 +28,13 @@ const LINKS = [
</svg> </svg>
</span> </span>
<span <span
class="hidden text-sm font-semibold tracking-tight text-slate-900 sm:inline dark:text-slate-100" class="hidden text-sm font-semibold tracking-tight text-slate-900 sm:inline dark:text-zinc-100"
> >
看板 看板
</span> </span>
</div> </div>
<span class="h-5 w-px bg-slate-200 dark:bg-slate-800" aria-hidden="true" /> <span class="h-5 w-px bg-slate-200 dark:bg-zinc-800" aria-hidden="true" />
<nav class="flex items-center gap-0.5" aria-label="主导航"> <nav class="flex items-center gap-0.5" aria-label="主导航">
<RouterLink <RouterLink
@@ -49,8 +49,8 @@ const LINKS = [
class="rounded-md px-3 py-1.5 text-sm transition" class="rounded-md px-3 py-1.5 text-sm transition"
:class=" :class="
isExactActive isExactActive
? 'bg-slate-900 font-medium text-white shadow-sm dark:bg-slate-100 dark:text-slate-900' ? 'bg-slate-900 font-medium text-white shadow-sm dark:bg-zinc-100 dark:text-zinc-900'
: 'text-slate-600 hover:bg-slate-100 hover:text-slate-900 dark:text-slate-400 dark:hover:bg-slate-800 dark:hover:text-slate-100' : 'text-slate-600 hover:bg-slate-100 hover:text-slate-900 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-100'
" "
:aria-current="isExactActive ? 'page' : undefined" :aria-current="isExactActive ? 'page' : undefined"
@click="navigate" @click="navigate"
@@ -63,7 +63,7 @@ const LINKS = [
<div class="ml-auto flex items-center gap-1.5"> <div class="ml-auto flex items-center gap-1.5">
<button <button
type="button" type="button"
class="flex size-8 items-center justify-center rounded-md text-slate-400 transition hover:bg-slate-100 hover:text-slate-700 dark:text-slate-500 dark:hover:bg-slate-800 dark:hover:text-slate-200" class="flex size-8 items-center justify-center rounded-md text-slate-400 transition hover:bg-slate-100 hover:text-slate-700 dark:text-zinc-500 dark:hover:bg-zinc-800 dark:hover:text-zinc-200"
:aria-label="`主题:${THEME_LABELS[theme.mode]},点击切换`" :aria-label="`主题:${THEME_LABELS[theme.mode]},点击切换`"
:title="`主题:${THEME_LABELS[theme.mode]}`" :title="`主题:${THEME_LABELS[theme.mode]}`"
@click="theme.cycle()" @click="theme.cycle()"
@@ -118,7 +118,7 @@ const LINKS = [
<button <button
type="button" type="button"
class="flex size-8 items-center justify-center rounded-md text-slate-400 transition hover:bg-slate-100 hover:text-slate-700 dark:text-slate-500 dark:hover:bg-slate-800 dark:hover:text-slate-200" class="flex size-8 items-center justify-center rounded-md text-slate-400 transition hover:bg-slate-100 hover:text-slate-700 dark:text-zinc-500 dark:hover:bg-zinc-800 dark:hover:text-zinc-200"
aria-label="快捷键帮助" aria-label="快捷键帮助"
@click="ui.openHelp()" @click="ui.openHelp()"
> >
@@ -136,7 +136,7 @@ const LINKS = [
<button <button
type="button" type="button"
class="flex items-center gap-1.5 rounded-md border border-slate-200 px-2.5 py-1.5 text-sm text-slate-600 transition hover:border-slate-300 hover:bg-slate-50 hover:text-slate-900 dark:border-slate-700 dark:text-slate-300 dark:hover:border-slate-600 dark:hover:bg-slate-800" class="flex items-center gap-1.5 rounded-md border border-slate-200 px-2.5 py-1.5 text-sm text-slate-600 transition hover:border-slate-300 hover:bg-slate-50 hover:text-slate-900 dark:border-zinc-700 dark:text-zinc-300 dark:hover:border-zinc-600 dark:hover:bg-zinc-800"
@click="ui.openBackup()" @click="ui.openBackup()"
> >
<svg viewBox="0 0 20 20" class="size-3.5" fill="none" aria-hidden="true"> <svg viewBox="0 0 20 20" class="size-3.5" fill="none" aria-hidden="true">
+9 -9
View File
@@ -110,7 +110,7 @@ function formatTime(iso: string): string {
</p> </p>
<section class="flex flex-col gap-2"> <section class="flex flex-col gap-2">
<h3 class="text-sm font-medium text-slate-700 dark:text-slate-300">导出</h3> <h3 class="text-sm font-medium text-slate-700 dark:text-zinc-300">导出</h3>
<button <button
type="button" type="button"
class="self-start rounded-md bg-sky-600 px-3 py-1.5 text-sm font-medium text-white transition hover:bg-sky-700 dark:hover:bg-sky-500" class="self-start rounded-md bg-sky-600 px-3 py-1.5 text-sm font-medium text-white transition hover:bg-sky-700 dark:hover:bg-sky-500"
@@ -121,12 +121,12 @@ function formatTime(iso: string): string {
</section> </section>
<section class="flex flex-col gap-2"> <section class="flex flex-col gap-2">
<h3 class="text-sm font-medium text-slate-700 dark:text-slate-300">导入</h3> <h3 class="text-sm font-medium text-slate-700 dark:text-zinc-300">导入</h3>
<input <input
type="file" type="file"
accept="application/json,.json" accept="application/json,.json"
class="block w-full text-sm text-slate-600 file:mr-3 file:rounded-md file:border file:border-slate-300 file:bg-white file:px-3 file:py-1.5 file:text-sm file:text-slate-600 dark:text-slate-400 dark:file:border-slate-600 dark:file:bg-slate-800 dark:file:text-slate-300" class="block w-full text-sm text-slate-600 file:mr-3 file:rounded-md file:border file:border-slate-300 file:bg-white file:px-3 file:py-1.5 file:text-sm file:text-slate-600 dark:text-zinc-400 dark:file:border-zinc-600 dark:file:bg-zinc-800 dark:file:text-zinc-300"
aria-label="选择导入文件" aria-label="选择导入文件"
@change="onFileChange" @change="onFileChange"
/> />
@@ -149,7 +149,7 @@ function formatTime(iso: string): string {
</button> </button>
<button <button
type="button" type="button"
class="rounded-md border border-slate-300 px-3 py-1 text-sm text-slate-600 transition hover:bg-white dark:border-slate-600 dark:text-slate-300 dark:hover:bg-slate-800" class="rounded-md border border-slate-300 px-3 py-1 text-sm text-slate-600 transition hover:bg-white dark:border-zinc-600 dark:text-zinc-300 dark:hover:bg-zinc-800"
@click="pending = null" @click="pending = null"
> >
取消 取消
@@ -159,8 +159,8 @@ function formatTime(iso: string): string {
</section> </section>
<section class="flex flex-col gap-2"> <section class="flex flex-col gap-2">
<h3 class="text-sm font-medium text-slate-700 dark:text-slate-300">自动备份</h3> <h3 class="text-sm font-medium text-slate-700 dark:text-zinc-300">自动备份</h3>
<p class="text-xs text-slate-500 dark:text-slate-400"> <p class="text-xs text-slate-500 dark:text-zinc-400">
每次打开看板时自动留一份,最多保留 3 份。 每次打开看板时自动留一份,最多保留 3 份。
</p> </p>
@@ -168,9 +168,9 @@ function formatTime(iso: string): string {
<li <li
v-for="item in snapshots" v-for="item in snapshots"
:key="item.key" :key="item.key"
class="flex items-center justify-between rounded-md border border-slate-200 px-3 py-2 dark:border-slate-700" class="flex items-center justify-between rounded-md border border-slate-200 px-3 py-2 dark:border-zinc-700"
> >
<span class="text-sm text-slate-600 dark:text-slate-300"> <span class="text-sm text-slate-600 dark:text-zinc-300">
{{ formatTime(item.savedAt) }} {{ formatTime(item.savedAt) }}
</span> </span>
<button <button
@@ -182,7 +182,7 @@ function formatTime(iso: string): string {
</button> </button>
</li> </li>
</ul> </ul>
<p v-else class="text-sm text-slate-400 dark:text-slate-500">暂无自动备份</p> <p v-else class="text-sm text-slate-400 dark:text-zinc-500">暂无自动备份</p>
</section> </section>
</div> </div>
</SideDrawer> </SideDrawer>
+5 -5
View File
@@ -19,7 +19,7 @@ const emit = defineEmits<{
/** 每列一个色点:三列在余光里也能区分开 */ /** 每列一个色点:三列在余光里也能区分开 */
const COLUMN_DOT: Record<ColumnId, string> = { const COLUMN_DOT: Record<ColumnId, string> = {
todo: 'bg-slate-400 dark:bg-slate-500', todo: 'bg-slate-400 dark:bg-zinc-500',
doing: 'bg-sky-500 dark:bg-sky-400', doing: 'bg-sky-500 dark:bg-sky-400',
done: 'bg-emerald-500 dark:bg-emerald-400', done: 'bg-emerald-500 dark:bg-emerald-400',
} }
@@ -57,14 +57,14 @@ useDraggable(listRef, {
<template> <template>
<section <section
class="flex flex-col rounded-xl border border-slate-200 bg-slate-100/70 md:min-h-0 dark:border-slate-800 dark:bg-slate-900/60" class="flex flex-col rounded-xl border border-slate-200 bg-slate-100/70 md:min-h-0 dark:border-zinc-800 dark:bg-zinc-900/60"
> >
<header class="flex items-center gap-2 px-3 pt-3 pb-2"> <header class="flex items-center gap-2 px-3 pt-3 pb-2">
<span class="size-1.5 shrink-0 rounded-full" :class="dotClass" aria-hidden="true" /> <span class="size-1.5 shrink-0 rounded-full" :class="dotClass" aria-hidden="true" />
<h2 class="text-sm font-medium text-slate-700 dark:text-slate-300">{{ column.title }}</h2> <h2 class="text-sm font-medium text-slate-700 dark:text-zinc-300">{{ column.title }}</h2>
<span <span
data-role="column-count" data-role="column-count"
class="ml-auto rounded-full border border-slate-200 bg-white px-2 py-0.5 text-xs font-medium text-slate-500 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-400" class="ml-auto rounded-full border border-slate-200 bg-white px-2 py-0.5 text-xs font-medium text-slate-500 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-400"
> >
{{ tasks.length }} {{ tasks.length }}
</span> </span>
@@ -88,7 +88,7 @@ useDraggable(listRef, {
<p <p
v-if="tasks.length === 0" v-if="tasks.length === 0"
class="rounded-lg border border-dashed border-slate-300/70 px-3 py-10 text-center text-xs text-slate-400 dark:border-slate-700 dark:text-slate-500" class="rounded-lg border border-dashed border-slate-300/70 px-3 py-10 text-center text-xs text-slate-400 dark:border-zinc-700 dark:text-zinc-500"
> >
暂无任务 暂无任务
</p> </p>
+13 -13
View File
@@ -56,7 +56,7 @@ defineExpose({ focusSearch })
<div class="relative min-w-56 flex-1 sm:max-w-xs"> <div class="relative min-w-56 flex-1 sm:max-w-xs">
<svg <svg
viewBox="0 0 20 20" viewBox="0 0 20 20"
class="pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-slate-400 dark:text-slate-500" class="pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-slate-400 dark:text-zinc-500"
fill="none" fill="none"
aria-hidden="true" aria-hidden="true"
> >
@@ -67,14 +67,14 @@ defineExpose({ focusSearch })
ref="searchRef" ref="searchRef"
v-model="keyword" v-model="keyword"
type="search" type="search"
class="h-9 w-full rounded-md border border-slate-200 bg-white pr-2.5 pl-8 text-sm text-slate-700 outline-none transition placeholder:text-slate-400 focus:border-sky-400 focus:ring-2 focus:ring-sky-100 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-200 dark:placeholder:text-slate-500 dark:focus:border-sky-600 dark:focus:ring-sky-950" class="h-9 w-full rounded-md border border-slate-200 bg-white pr-2.5 pl-8 text-sm text-slate-700 outline-none transition placeholder:text-slate-400 focus:border-sky-400 focus:ring-2 focus:ring-sky-100 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-200 dark:placeholder:text-zinc-500 dark:focus:border-sky-600 dark:focus:ring-sky-950"
placeholder="搜索标题或描述" placeholder="搜索标题或描述"
aria-label="搜索任务" aria-label="搜索任务"
/> />
</div> </div>
<div <div
class="flex h-9 items-center gap-0.5 rounded-md border border-slate-200 bg-white p-0.5 dark:border-slate-700 dark:bg-slate-900" class="flex h-9 items-center gap-0.5 rounded-md border border-slate-200 bg-white p-0.5 dark:border-zinc-700 dark:bg-zinc-900"
role="group" role="group"
aria-label="按优先级筛选" aria-label="按优先级筛选"
> >
@@ -85,8 +85,8 @@ defineExpose({ focusSearch })
class="flex h-full items-center rounded px-2.5 text-xs transition" class="flex h-full items-center rounded px-2.5 text-xs transition"
:class=" :class="
priorities.includes(value) priorities.includes(value)
? 'bg-slate-900 font-medium text-white dark:bg-slate-100 dark:text-slate-900' ? 'bg-slate-900 font-medium text-white dark:bg-zinc-100 dark:text-zinc-900'
: 'text-slate-600 hover:bg-slate-100 dark:text-slate-400 dark:hover:bg-slate-800' : 'text-slate-600 hover:bg-slate-100 dark:text-zinc-400 dark:hover:bg-zinc-800'
" "
:aria-pressed="priorities.includes(value)" :aria-pressed="priorities.includes(value)"
@click="filters.togglePriority(value)" @click="filters.togglePriority(value)"
@@ -109,7 +109,7 @@ defineExpose({ focusSearch })
:class=" :class="
due === 'today' due === 'today'
? 'border-amber-300 bg-amber-50 text-amber-800 dark:border-amber-700 dark:bg-amber-950 dark:text-amber-300' ? 'border-amber-300 bg-amber-50 text-amber-800 dark:border-amber-700 dark:bg-amber-950 dark:text-amber-300'
: 'border-slate-200 bg-white text-slate-600 hover:border-slate-300 hover:bg-slate-50 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-300 dark:hover:border-slate-600 dark:hover:bg-slate-800' : 'border-slate-200 bg-white text-slate-600 hover:border-slate-300 hover:bg-slate-50 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-300 dark:hover:border-zinc-600 dark:hover:bg-zinc-800'
" "
:aria-pressed="due === 'today'" :aria-pressed="due === 'today'"
@click="filters.toggleDue('today')" @click="filters.toggleDue('today')"
@@ -125,8 +125,8 @@ defineExpose({ focusSearch })
due === 'overdue' due === 'overdue'
? 'border-rose-300 bg-rose-50 text-rose-700 dark:border-rose-700 dark:bg-rose-950 dark:text-rose-300' ? 'border-rose-300 bg-rose-50 text-rose-700 dark:border-rose-700 dark:bg-rose-950 dark:text-rose-300'
: overdueCount > 0 : overdueCount > 0
? 'border-slate-200 bg-white text-rose-600 hover:border-rose-200 hover:bg-rose-50 dark:border-slate-700 dark:bg-slate-900 dark:text-rose-400 dark:hover:border-rose-800 dark:hover:bg-rose-950' ? 'border-slate-200 bg-white text-rose-600 hover:border-rose-200 hover:bg-rose-50 dark:border-zinc-700 dark:bg-zinc-900 dark:text-rose-400 dark:hover:border-rose-800 dark:hover:bg-rose-950'
: 'border-slate-200 bg-white text-slate-600 hover:border-slate-300 hover:bg-slate-50 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-300 dark:hover:border-slate-600 dark:hover:bg-slate-800' : 'border-slate-200 bg-white text-slate-600 hover:border-slate-300 hover:bg-slate-50 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-300 dark:hover:border-zinc-600 dark:hover:bg-zinc-800'
" "
:aria-pressed="due === 'overdue'" :aria-pressed="due === 'overdue'"
@click="filters.toggleDue('overdue')" @click="filters.toggleDue('overdue')"
@@ -137,15 +137,15 @@ defineExpose({ focusSearch })
</div> </div>
</div> </div>
<div class="flex flex-wrap items-center gap-x-2 gap-y-1.5 text-xs text-slate-500 dark:text-slate-400"> <div class="flex flex-wrap items-center gap-x-2 gap-y-1.5 text-xs text-slate-500 dark:text-zinc-400">
<span>共 {{ store.tasks.length }} 个任务</span> <span>共 {{ store.tasks.length }} 个任务</span>
<span v-if="hiddenNote" class="text-slate-400 dark:text-slate-500">{{ hiddenNote }}</span> <span v-if="hiddenNote" class="text-slate-400 dark:text-zinc-500">{{ hiddenNote }}</span>
<div class="ml-auto flex items-center gap-1.5"> <div class="ml-auto flex items-center gap-1.5">
<button <button
v-if="archivableCount > 0" v-if="archivableCount > 0"
type="button" type="button"
class="flex h-8 items-center rounded-md border border-slate-200 bg-white px-2.5 text-xs text-slate-600 transition hover:border-slate-300 hover:bg-slate-50 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-300 dark:hover:border-slate-600 dark:hover:bg-slate-800" class="flex h-8 items-center rounded-md border border-slate-200 bg-white px-2.5 text-xs text-slate-600 transition hover:border-slate-300 hover:bg-slate-50 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-300 dark:hover:border-zinc-600 dark:hover:bg-zinc-800"
@click="emit('archive')" @click="emit('archive')"
> >
归档 {{ archivableCount }} 个已完成 归档 {{ archivableCount }} 个已完成
@@ -157,7 +157,7 @@ defineExpose({ focusSearch })
:class=" :class="
includeArchived includeArchived
? 'border-sky-300 bg-sky-50 text-sky-700 dark:border-sky-700 dark:bg-sky-950 dark:text-sky-300' ? 'border-sky-300 bg-sky-50 text-sky-700 dark:border-sky-700 dark:bg-sky-950 dark:text-sky-300'
: 'border-slate-200 bg-white text-slate-600 hover:border-slate-300 hover:bg-slate-50 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-300 dark:hover:border-slate-600 dark:hover:bg-slate-800' : 'border-slate-200 bg-white text-slate-600 hover:border-slate-300 hover:bg-slate-50 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-300 dark:hover:border-zinc-600 dark:hover:bg-zinc-800'
" "
:aria-pressed="includeArchived" :aria-pressed="includeArchived"
@click="filters.toggleArchived()" @click="filters.toggleArchived()"
@@ -168,7 +168,7 @@ defineExpose({ focusSearch })
<button <button
v-if="active" v-if="active"
type="button" type="button"
class="flex h-8 items-center rounded-md px-2.5 text-xs text-slate-500 underline-offset-2 transition hover:text-slate-800 hover:underline dark:text-slate-400 dark:hover:text-slate-200" class="flex h-8 items-center rounded-md px-2.5 text-xs text-slate-500 underline-offset-2 transition hover:text-slate-800 hover:underline dark:text-zinc-400 dark:hover:text-zinc-200"
@click="filters.clear()" @click="filters.clear()"
> >
清空筛选 清空筛选
+2 -2
View File
@@ -100,8 +100,8 @@ describe('DatePicker 空值占位', () => {
it('占位层带不透明背景,且与输入框配色一致', () => { it('占位层带不透明背景,且与输入框配色一致', () => {
const classes = placeholderOf(mountPicker(null)).classes() const classes = placeholderOf(mountPicker(null)).classes()
expect(classes).toContain('bg-white') expect(classes).toContain('bg-white')
expect(classes).toContain('dark:bg-slate-800') expect(classes).toContain('dark:bg-zinc-800')
expect(mountPicker(null).find('input').classes()).toContain('dark:bg-slate-800') expect(mountPicker(null).find('input').classes()).toContain('dark:bg-zinc-800')
}) })
it('占位层只覆盖左侧,给日历图标留出位置', () => { it('占位层只覆盖左侧,给日历图标留出位置', () => {
+3 -3
View File
@@ -63,7 +63,7 @@ function openPicker(): void {
<input <input
ref="inputRef" ref="inputRef"
type="date" type="date"
class="w-full rounded-md border border-slate-300 bg-white px-2.5 py-1.5 text-sm text-slate-700 outline-none focus:border-sky-400 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:focus:border-sky-600" class="w-full rounded-md border border-slate-300 bg-white px-2.5 py-1.5 text-sm text-slate-700 outline-none focus:border-sky-400 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-200 dark:focus:border-sky-600"
:value="modelValue ?? ''" :value="modelValue ?? ''"
:aria-label="label ?? '截止日期'" :aria-label="label ?? '截止日期'"
@change="onChange" @change="onChange"
@@ -79,7 +79,7 @@ function openPicker(): void {
<span <span
v-if="showPlaceholder" v-if="showPlaceholder"
data-role="date-placeholder" data-role="date-placeholder"
class="absolute inset-y-px left-px right-9 flex cursor-pointer items-center rounded-l-md bg-white pl-2 text-sm text-slate-400 dark:bg-slate-800 dark:text-slate-500" class="absolute inset-y-px left-px right-9 flex cursor-pointer items-center rounded-l-md bg-white pl-2 text-sm text-slate-400 dark:bg-zinc-800 dark:text-zinc-500"
@click="openPicker" @click="openPicker"
> >
选择日期 选择日期
@@ -89,7 +89,7 @@ function openPicker(): void {
<button <button
v-if="modelValue" v-if="modelValue"
type="button" type="button"
class="shrink-0 rounded px-2 py-1 text-xs text-slate-500 transition hover:bg-slate-100 dark:text-slate-400 dark:hover:bg-slate-800" class="shrink-0 rounded px-2 py-1 text-xs text-slate-500 transition hover:bg-slate-100 dark:text-zinc-400 dark:hover:bg-zinc-800"
@click="emit('update:modelValue', null)" @click="emit('update:modelValue', null)"
> >
清除 清除
+3 -3
View File
@@ -26,14 +26,14 @@ function reload(): void {
<div v-if="visible" class="fixed inset-x-0 bottom-4 z-50 flex justify-center px-4"> <div v-if="visible" class="fixed inset-x-0 bottom-4 z-50 flex justify-center px-4">
<div <div
role="status" role="status"
class="flex items-center gap-3 rounded-md bg-slate-800 px-3 py-2 text-sm text-white shadow-panel dark:bg-slate-100 dark:text-slate-900" class="flex items-center gap-3 rounded-md bg-slate-800 px-3 py-2 text-sm text-white shadow-panel dark:bg-zinc-100 dark:text-zinc-900"
> >
<span>{{ needRefresh ? '有新版本可用' : '已缓存,可离线使用' }}</span> <span>{{ needRefresh ? '有新版本可用' : '已缓存,可离线使用' }}</span>
<button <button
v-if="needRefresh" v-if="needRefresh"
type="button" type="button"
class="shrink-0 rounded px-2 py-0.5 font-medium text-sky-300 transition hover:bg-white/10 dark:text-sky-700 dark:hover:bg-slate-900/10" class="shrink-0 rounded px-2 py-0.5 font-medium text-sky-300 transition hover:bg-white/10 dark:text-sky-700 dark:hover:bg-zinc-900/10"
@click="reload" @click="reload"
> >
立即更新 立即更新
@@ -41,7 +41,7 @@ function reload(): void {
<button <button
type="button" type="button"
class="shrink-0 rounded px-1.5 text-slate-400 transition hover:text-white dark:text-slate-500 dark:hover:text-slate-900" class="shrink-0 rounded px-1.5 text-slate-400 transition hover:text-white dark:text-zinc-500 dark:hover:text-zinc-900"
aria-label="关闭提示" aria-label="关闭提示"
@click="dismiss" @click="dismiss"
> >
+1 -1
View File
@@ -37,7 +37,7 @@ defineExpose({ focusInput })
ref="inputRef" ref="inputRef"
v-model="title" v-model="title"
type="text" type="text"
class="w-full rounded-lg border border-transparent bg-white/60 px-3 py-2 text-sm text-slate-700 transition outline-none placeholder:text-slate-400 hover:bg-white focus:border-sky-300 focus:bg-white focus:ring-2 focus:ring-sky-100 dark:bg-slate-800/60 dark:text-slate-200 dark:placeholder:text-slate-500 dark:hover:bg-slate-800 dark:focus:border-sky-700 dark:focus:bg-slate-800 dark:focus:ring-sky-950" class="w-full rounded-lg border border-transparent bg-white/60 px-3 py-2 text-sm text-slate-700 transition outline-none placeholder:text-slate-400 hover:bg-white focus:border-sky-300 focus:bg-white focus:ring-2 focus:ring-sky-100 dark:bg-zinc-800/60 dark:text-zinc-200 dark:placeholder:text-zinc-500 dark:hover:bg-zinc-800 dark:focus:border-sky-700 dark:focus:bg-zinc-800 dark:focus:ring-sky-950"
placeholder="+ 添加任务" placeholder="+ 添加任务"
aria-label="添加任务" aria-label="添加任务"
@compositionstart="composing = true" @compositionstart="composing = true"
+5 -5
View File
@@ -89,19 +89,19 @@ onBeforeUnmount(stopListening)
<aside <aside
ref="panelRef" ref="panelRef"
class="absolute inset-y-0 right-0 flex w-full max-w-md flex-col bg-white shadow-panel outline-none dark:bg-slate-900" class="absolute inset-y-0 right-0 flex w-full max-w-md flex-col bg-white shadow-panel outline-none dark:bg-zinc-900"
role="dialog" role="dialog"
aria-modal="true" aria-modal="true"
:aria-label="title" :aria-label="title"
tabindex="-1" tabindex="-1"
> >
<header <header
class="flex items-center justify-between border-b border-slate-200 px-4 py-3 dark:border-slate-800" class="flex items-center justify-between border-b border-slate-200 px-4 py-3 dark:border-zinc-800"
> >
<h2 class="text-base font-medium text-slate-800 dark:text-slate-100">{{ title }}</h2> <h2 class="text-base font-medium text-slate-800 dark:text-zinc-100">{{ title }}</h2>
<button <button
type="button" type="button"
class="rounded px-2 py-1 text-slate-400 transition hover:bg-slate-100 hover:text-slate-600 dark:hover:bg-slate-800 dark:hover:text-slate-200" class="rounded px-2 py-1 text-slate-400 transition hover:bg-slate-100 hover:text-slate-600 dark:hover:bg-zinc-800 dark:hover:text-zinc-200"
aria-label="关闭" aria-label="关闭"
@click="emit('close')" @click="emit('close')"
> >
@@ -115,7 +115,7 @@ onBeforeUnmount(stopListening)
<footer <footer
v-if="$slots.footer" v-if="$slots.footer"
class="border-t border-slate-200 px-4 py-3 dark:border-slate-800" class="border-t border-slate-200 px-4 py-3 dark:border-zinc-800"
> >
<slot name="footer" /> <slot name="footer" />
</footer> </footer>
+5 -5
View File
@@ -48,7 +48,7 @@ onBeforeUnmount(() => {
:class=" :class="
selected.length > 0 selected.length > 0
? 'border-sky-300 bg-sky-50 text-sky-700 dark:border-sky-700 dark:bg-sky-950 dark:text-sky-300' ? 'border-sky-300 bg-sky-50 text-sky-700 dark:border-sky-700 dark:bg-sky-950 dark:text-sky-300'
: 'border-slate-200 bg-white text-slate-600 hover:border-slate-300 hover:bg-slate-50 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-300 dark:hover:border-slate-600 dark:hover:bg-slate-800' : 'border-slate-200 bg-white text-slate-600 hover:border-slate-300 hover:bg-slate-50 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-300 dark:hover:border-zinc-600 dark:hover:bg-zinc-800'
" "
:aria-expanded="open" :aria-expanded="open"
aria-haspopup="true" aria-haspopup="true"
@@ -80,16 +80,16 @@ onBeforeUnmount(() => {
<div <div
v-if="open" v-if="open"
class="absolute top-full left-0 z-20 mt-1.5 w-56 rounded-lg border border-slate-200 bg-white p-1.5 shadow-pop dark:border-slate-700 dark:bg-slate-900" class="absolute top-full left-0 z-20 mt-1.5 w-56 rounded-lg border border-slate-200 bg-white p-1.5 shadow-pop dark:border-zinc-700 dark:bg-zinc-900"
> >
<p v-if="tags.length === 0" class="px-2 py-3 text-center text-xs text-slate-400 dark:text-slate-500"> <p v-if="tags.length === 0" class="px-2 py-3 text-center text-xs text-slate-400 dark:text-zinc-500">
还没有任何标签 还没有任何标签
</p> </p>
<ul v-else class="max-h-64 overflow-y-auto"> <ul v-else class="max-h-64 overflow-y-auto">
<li v-for="tag in tags" :key="tag"> <li v-for="tag in tags" :key="tag">
<label <label
class="flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-sm text-slate-700 transition hover:bg-slate-50 dark:text-slate-300 dark:hover:bg-slate-800" class="flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-sm text-slate-700 transition hover:bg-slate-50 dark:text-zinc-300 dark:hover:bg-zinc-800"
> >
<input <input
type="checkbox" type="checkbox"
@@ -105,7 +105,7 @@ onBeforeUnmount(() => {
<button <button
v-if="selected.length > 0" v-if="selected.length > 0"
type="button" type="button"
class="mt-1 w-full rounded-md px-2 py-1.5 text-xs text-slate-500 transition hover:bg-slate-50 hover:text-slate-700 dark:text-slate-400 dark:hover:bg-slate-800 dark:hover:text-slate-200" class="mt-1 w-full rounded-md px-2 py-1.5 text-xs text-slate-500 transition hover:bg-slate-50 hover:text-slate-700 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-200"
@click="emit('clear')" @click="emit('clear')"
> >
清除标签筛选 清除标签筛选
+2 -2
View File
@@ -36,7 +36,7 @@ function onBackspace(): void {
<template> <template>
<div <div
class="flex flex-wrap items-center gap-1.5 rounded-md border border-slate-300 px-2 py-1.5 focus-within:border-sky-400 dark:border-slate-700 dark:bg-slate-800 dark:focus-within:border-sky-600" class="flex flex-wrap items-center gap-1.5 rounded-md border border-slate-300 px-2 py-1.5 focus-within:border-sky-400 dark:border-zinc-700 dark:bg-zinc-800 dark:focus-within:border-sky-600"
> >
<span <span
v-for="tag in modelValue" v-for="tag in modelValue"
@@ -57,7 +57,7 @@ function onBackspace(): void {
<input <input
v-model="draft" v-model="draft"
type="text" type="text"
class="min-w-24 flex-1 border-none bg-transparent px-1 py-0.5 text-sm text-slate-700 outline-none placeholder:text-slate-400 dark:text-slate-200 dark:placeholder:text-slate-500" class="min-w-24 flex-1 border-none bg-transparent px-1 py-0.5 text-sm text-slate-700 outline-none placeholder:text-slate-400 dark:text-zinc-200 dark:placeholder:text-zinc-500"
:placeholder="modelValue.length === 0 ? (placeholder ?? '回车添加标签') : ''" :placeholder="modelValue.length === 0 ? (placeholder ?? '回车添加标签') : ''"
aria-label="添加标签" aria-label="添加标签"
@keydown.enter.prevent="composing ? undefined : commit()" @keydown.enter.prevent="composing ? undefined : commit()"
+10 -10
View File
@@ -56,7 +56,7 @@ const priorityBarClass = computed(() => {
case 2: case 2:
return 'bg-amber-400' return 'bg-amber-400'
default: default:
return 'bg-slate-300 dark:bg-slate-600' return 'bg-slate-300 dark:bg-zinc-600'
} }
}) })
@@ -67,18 +67,18 @@ const priorityTextClass = computed(() => {
case 2: case 2:
return 'text-amber-700 dark:text-amber-400' return 'text-amber-700 dark:text-amber-400'
default: default:
return 'text-slate-400 dark:text-slate-500' return 'text-slate-400 dark:text-zinc-500'
} }
}) })
</script> </script>
<template> <template>
<article <article
class="relative shrink-0 cursor-pointer overflow-hidden rounded-lg border border-slate-200 bg-white shadow-card transition duration-150 dark:border-slate-800 dark:bg-slate-900" class="relative shrink-0 cursor-pointer overflow-hidden rounded-lg border border-slate-200 bg-white shadow-card transition duration-150 dark:border-zinc-800 dark:bg-zinc-900"
:class=" :class="
isDone isDone
? 'opacity-60' ? 'opacity-60'
: 'hover:-translate-y-px hover:border-slate-300 hover:shadow-card-hover dark:hover:border-slate-700' : 'hover:-translate-y-px hover:border-slate-300 hover:shadow-card-hover dark:hover:border-zinc-700'
" "
:data-task-id="task.id" :data-task-id="task.id"
tabindex="0" tabindex="0"
@@ -95,7 +95,7 @@ const priorityTextClass = computed(() => {
:class=" :class="
isDone isDone
? 'border-emerald-500 bg-emerald-500 text-white' ? 'border-emerald-500 bg-emerald-500 text-white'
: 'border-slate-300 hover:border-emerald-500 hover:bg-emerald-50 dark:border-slate-600 dark:hover:border-emerald-500 dark:hover:bg-emerald-950' : 'border-slate-300 hover:border-emerald-500 hover:bg-emerald-50 dark:border-zinc-600 dark:hover:border-emerald-500 dark:hover:bg-emerald-950'
" "
:aria-label="isDone ? '标记为未完成' : '标记为已完成'" :aria-label="isDone ? '标记为未完成' : '标记为已完成'"
:aria-pressed="isDone" :aria-pressed="isDone"
@@ -116,8 +116,8 @@ const priorityTextClass = computed(() => {
class="min-w-0 flex-1 text-sm leading-snug wrap-break-word" class="min-w-0 flex-1 text-sm leading-snug wrap-break-word"
:class=" :class="
isDone isDone
? 'text-slate-400 line-through dark:text-slate-500' ? 'text-slate-400 line-through dark:text-zinc-500'
: 'text-slate-800 dark:text-slate-100' : 'text-slate-800 dark:text-zinc-100'
" "
> >
{{ task.title }} {{ task.title }}
@@ -134,16 +134,16 @@ const priorityTextClass = computed(() => {
:class=" :class="
overdue overdue
? 'font-medium text-rose-600 dark:text-rose-400' ? 'font-medium text-rose-600 dark:text-rose-400'
: 'text-slate-500 dark:text-slate-400' : 'text-slate-500 dark:text-zinc-400'
" "
> >
{{ formatDueDate(task.dueDate) }} {{ formatDueDate(task.dueDate) }}
</span> </span>
<span v-for="tag in visibleTags" :key="tag" class="text-slate-400 dark:text-slate-500"> <span v-for="tag in visibleTags" :key="tag" class="text-slate-400 dark:text-zinc-500">
#{{ tag }} #{{ tag }}
</span> </span>
<span v-if="hiddenTagCount > 0" class="text-slate-400 dark:text-slate-500"> <span v-if="hiddenTagCount > 0" class="text-slate-400 dark:text-zinc-500">
+{{ hiddenTagCount }} +{{ hiddenTagCount }}
</span> </span>
</div> </div>
+9 -9
View File
@@ -82,11 +82,11 @@ function remove(): void {
<SideDrawer :open="task !== null" title="任务详情" @close="emit('close')"> <SideDrawer :open="task !== null" title="任务详情" @close="emit('close')">
<form v-if="task" class="flex flex-col gap-4" @submit.prevent="save"> <form v-if="task" class="flex flex-col gap-4" @submit.prevent="save">
<label class="flex flex-col gap-1.5"> <label class="flex flex-col gap-1.5">
<span class="text-sm font-medium text-slate-600 dark:text-slate-400">标题</span> <span class="text-sm font-medium text-slate-600 dark:text-zinc-400">标题</span>
<input <input
v-model="title" v-model="title"
type="text" type="text"
class="rounded-md border border-slate-300 px-2.5 py-1.5 text-sm text-slate-700 outline-none focus:border-sky-400 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:focus:border-sky-600" class="rounded-md border border-slate-300 px-2.5 py-1.5 text-sm text-slate-700 outline-none focus:border-sky-400 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-200 dark:focus:border-sky-600"
aria-label="标题" aria-label="标题"
@input="titleError = null" @input="titleError = null"
/> />
@@ -94,17 +94,17 @@ function remove(): void {
</label> </label>
<label class="flex flex-col gap-1.5"> <label class="flex flex-col gap-1.5">
<span class="text-sm font-medium text-slate-600 dark:text-slate-400">描述</span> <span class="text-sm font-medium text-slate-600 dark:text-zinc-400">描述</span>
<textarea <textarea
v-model="description" v-model="description"
rows="4" rows="4"
class="resize-y rounded-md border border-slate-300 px-2.5 py-1.5 text-sm text-slate-700 outline-none focus:border-sky-400 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:focus:border-sky-600" class="resize-y rounded-md border border-slate-300 px-2.5 py-1.5 text-sm text-slate-700 outline-none focus:border-sky-400 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-200 dark:focus:border-sky-600"
aria-label="描述" aria-label="描述"
/> />
</label> </label>
<fieldset class="flex flex-col gap-1.5"> <fieldset class="flex flex-col gap-1.5">
<legend class="mb-1.5 text-sm font-medium text-slate-600 dark:text-slate-400">优先级</legend> <legend class="mb-1.5 text-sm font-medium text-slate-600 dark:text-zinc-400">优先级</legend>
<div class="flex gap-2"> <div class="flex gap-2">
<button <button
v-for="value in PRIORITIES" v-for="value in PRIORITIES"
@@ -114,7 +114,7 @@ function remove(): void {
:class=" :class="
priority === value priority === value
? 'border-sky-400 bg-sky-50 text-sky-700 dark:border-sky-600 dark:bg-sky-950 dark:text-sky-300' ? 'border-sky-400 bg-sky-50 text-sky-700 dark:border-sky-600 dark:bg-sky-950 dark:text-sky-300'
: 'border-slate-300 text-slate-600 hover:bg-slate-50 dark:border-slate-600 dark:text-slate-400 dark:hover:bg-slate-800' : 'border-slate-300 text-slate-600 hover:bg-slate-50 dark:border-zinc-600 dark:text-zinc-400 dark:hover:bg-zinc-800'
" "
:aria-pressed="priority === value" :aria-pressed="priority === value"
@click="priority = value" @click="priority = value"
@@ -125,12 +125,12 @@ function remove(): void {
</fieldset> </fieldset>
<div class="flex flex-col gap-1.5"> <div class="flex flex-col gap-1.5">
<span class="text-sm font-medium text-slate-600 dark:text-slate-400">截止日期</span> <span class="text-sm font-medium text-slate-600 dark:text-zinc-400">截止日期</span>
<DatePicker v-model="dueDate" /> <DatePicker v-model="dueDate" />
</div> </div>
<div class="flex flex-col gap-1.5"> <div class="flex flex-col gap-1.5">
<span class="text-sm font-medium text-slate-600 dark:text-slate-400">标签</span> <span class="text-sm font-medium text-slate-600 dark:text-zinc-400">标签</span>
<TagInput v-model="tags" /> <TagInput v-model="tags" />
</div> </div>
</form> </form>
@@ -148,7 +148,7 @@ function remove(): void {
<div class="flex gap-2"> <div class="flex gap-2">
<button <button
type="button" type="button"
class="rounded-md border border-slate-300 px-3 py-1.5 text-sm text-slate-600 transition hover:bg-slate-50 dark:border-slate-600 dark:text-slate-300 dark:hover:bg-slate-800" class="rounded-md border border-slate-300 px-3 py-1.5 text-sm text-slate-600 transition hover:bg-slate-50 dark:border-zinc-600 dark:text-zinc-300 dark:hover:bg-zinc-800"
@click="emit('close')" @click="emit('close')"
> >
取消 取消
+3 -3
View File
@@ -15,14 +15,14 @@ const { toasts } = storeToRefs(store)
v-for="toast in toasts" v-for="toast in toasts"
:key="toast.id" :key="toast.id"
role="status" role="status"
class="pointer-events-auto flex w-full max-w-sm items-center gap-3 rounded-md bg-slate-800 px-3 py-2 text-sm text-white shadow-panel dark:bg-slate-100 dark:text-slate-900" class="pointer-events-auto flex w-full max-w-sm items-center gap-3 rounded-md bg-slate-800 px-3 py-2 text-sm text-white shadow-panel dark:bg-zinc-100 dark:text-zinc-900"
> >
<span class="min-w-0 flex-1 wrap-break-word">{{ toast.message }}</span> <span class="min-w-0 flex-1 wrap-break-word">{{ toast.message }}</span>
<button <button
v-if="toast.action" v-if="toast.action"
type="button" type="button"
class="shrink-0 rounded px-2 py-0.5 text-sm font-medium text-sky-300 transition hover:bg-white/10 dark:text-sky-700 dark:hover:bg-slate-900/10" class="shrink-0 rounded px-2 py-0.5 text-sm font-medium text-sky-300 transition hover:bg-white/10 dark:text-sky-700 dark:hover:bg-zinc-900/10"
@click="store.runAction(toast.id)" @click="store.runAction(toast.id)"
> >
{{ toast.action.label }} {{ toast.action.label }}
@@ -30,7 +30,7 @@ const { toasts } = storeToRefs(store)
<button <button
type="button" type="button"
class="shrink-0 rounded px-1.5 text-slate-400 transition hover:text-white dark:text-slate-500 dark:hover:text-slate-900" class="shrink-0 rounded px-1.5 text-slate-400 transition hover:text-white dark:text-zinc-500 dark:hover:text-zinc-900"
aria-label="关闭提示" aria-label="关闭提示"
@click="store.dismiss(toast.id)" @click="store.dismiss(toast.id)"
> >
+7 -3
View File
@@ -41,9 +41,13 @@
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
} }
/*
* 深色用 zinc(中性灰)而不是 slate:slate 带明显蓝调,
* 整页会发蓝,和「中性灰」的目标色差得很远。
*/
html.dark body { html.dark body {
background: var(--color-slate-950); background: var(--color-zinc-950);
color: var(--color-slate-100); color: var(--color-zinc-100);
} }
/* 统一的键盘焦点样式,鼠标点击不显示 */ /* 统一的键盘焦点样式,鼠标点击不显示 */
@@ -68,7 +72,7 @@
} }
html.dark * { html.dark * {
scrollbar-color: var(--color-slate-700) transparent; scrollbar-color: var(--color-zinc-700) transparent;
} }
} }
+9 -9
View File
@@ -32,7 +32,7 @@ const TONES = {
slate: { slate: {
dot: 'bg-slate-400', dot: 'bg-slate-400',
badge: badge:
'border-slate-200 bg-slate-50 text-slate-600 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-300', 'border-slate-200 bg-slate-50 text-slate-600 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-300',
}, },
} as const } as const
@@ -123,23 +123,23 @@ function handleKeyMove(payload: { id: string; direction: MoveDirection }): void
<!-- 限宽居中:否则 1440px 下卡片会被拉满整屏,标题与元信息之间出现大片空白 --> <!-- 限宽居中:否则 1440px 下卡片会被拉满整屏,标题与元信息之间出现大片空白 -->
<div class="mx-auto flex w-full max-w-3xl flex-col gap-5 p-4 md:p-6"> <div class="mx-auto flex w-full max-w-3xl flex-col gap-5 p-4 md:p-6">
<header class="flex flex-col gap-0.5"> <header class="flex flex-col gap-0.5">
<h1 class="text-xl font-semibold tracking-tight text-slate-900 md:text-2xl dark:text-slate-100"> <h1 class="text-xl font-semibold tracking-tight text-slate-900 md:text-2xl dark:text-zinc-100">
今日 今日
</h1> </h1>
<p class="text-sm text-slate-500 dark:text-slate-400">{{ todayLabel }}</p> <p class="text-sm text-slate-500 dark:text-zinc-400">{{ todayLabel }}</p>
</header> </header>
<dl class="grid grid-cols-2 gap-3 md:grid-cols-4"> <dl class="grid grid-cols-2 gap-3 md:grid-cols-4">
<div <div
v-for="card in statCards" v-for="card in statCards"
:key="card.label" :key="card.label"
class="rounded-xl border border-slate-200 bg-white px-4 py-3.5 shadow-card dark:border-slate-800 dark:bg-slate-900" class="rounded-xl border border-slate-200 bg-white px-4 py-3.5 shadow-card dark:border-zinc-800 dark:bg-zinc-900"
> >
<dt class="flex items-center gap-1.5 text-xs text-slate-500 dark:text-slate-400"> <dt class="flex items-center gap-1.5 text-xs text-slate-500 dark:text-zinc-400">
<span class="size-1.5 rounded-full" :class="card.dot" aria-hidden="true" /> <span class="size-1.5 rounded-full" :class="card.dot" aria-hidden="true" />
{{ card.label }} {{ card.label }}
</dt> </dt>
<dd class="mt-1.5 text-2xl font-semibold tracking-tight text-slate-900 dark:text-slate-100"> <dd class="mt-1.5 text-2xl font-semibold tracking-tight text-slate-900 dark:text-zinc-100">
{{ card.value }} {{ card.value }}
</dd> </dd>
</div> </div>
@@ -147,14 +147,14 @@ function handleKeyMove(payload: { id: string; direction: MoveDirection }): void
<p <p
v-if="todayCount === 0" v-if="todayCount === 0"
class="rounded-xl border border-dashed border-slate-300 bg-white/60 px-4 py-16 text-center text-sm text-slate-400 dark:border-slate-700 dark:bg-slate-900/40 dark:text-slate-500" class="rounded-xl border border-dashed border-slate-300 bg-white/60 px-4 py-16 text-center text-sm text-slate-400 dark:border-zinc-700 dark:bg-zinc-900/40 dark:text-zinc-500"
> >
今天没有待办事项 今天没有待办事项
</p> </p>
<section v-for="section in sections" :key="section.key" class="flex flex-col gap-2"> <section v-for="section in sections" :key="section.key" class="flex flex-col gap-2">
<h2 <h2
class="flex flex-wrap items-center gap-2 text-sm font-medium text-slate-700 dark:text-slate-300" class="flex flex-wrap items-center gap-2 text-sm font-medium text-slate-700 dark:text-zinc-300"
> >
<span class="size-1.5 rounded-full" :class="TONES[section.tone].dot" aria-hidden="true" /> <span class="size-1.5 rounded-full" :class="TONES[section.tone].dot" aria-hidden="true" />
{{ section.title }} {{ section.title }}
@@ -165,7 +165,7 @@ function handleKeyMove(payload: { id: string; direction: MoveDirection }): void
> >
{{ section.items.length }} {{ section.items.length }}
</span> </span>
<span class="text-xs font-normal text-slate-400 dark:text-slate-500"> <span class="text-xs font-normal text-slate-400 dark:text-zinc-500">
{{ section.hint }} {{ section.hint }}
</span> </span>
</h2> </h2>