diff --git a/.agents/skills/opencloud-color-system/SKILL.md b/.agents/skills/opencloud-color-system/SKILL.md new file mode 100644 index 0000000..4b46ffa --- /dev/null +++ b/.agents/skills/opencloud-color-system/SKILL.md @@ -0,0 +1,74 @@ +--- +name: opencloud-color-system +description: "Use when modifying OpenCloud UI colors, visual hierarchy, Tailwind classes, buttons, cards, headers, gradients, status chips, or page-level visual design. Ensures the project keeps its current fresh sky/teal/white visual language and avoids inconsistent dark or purple defaults." +--- + +# OpenCloud Color System + +Use this skill whenever changing OpenCloud visual design, component styling, or Tailwind color classes. + +## Visual Direction + +OpenCloud should feel like a clean sky atlas: airy, fresh, bright, and observational. + +- Base surfaces: `white`, `slate-50`, `sky-50`, soft translucent white (`bg-white/80`, `bg-white/88`). +- Main accent: teal/cyan for navigation, identity, account surfaces. +- Secondary accent: sky blue for upload and action highlights. +- Supporting accent: amber only for rarity, badges, pending/review states. +- Danger accent: rose/red only for destructive or rejected states. +- Avoid purple as a default accent. +- Avoid black selected states except for text or rare high-contrast badges. + +## Core Palette + +Use these Tailwind families first: + +- `slate`: text, borders, neutral panels. +- `sky`: page gradients, upload/action emphasis, map/cloud atmosphere. +- `teal`: navigation selected states, account identity, calm success-adjacent UI. +- `cyan`: subtle sky gradients and avatar/logo surfaces. +- `emerald`: explicit success/approved state only. +- `amber`: pending/review/uncommon rarity. +- `rose`: rejected/destructive/rare rarity. + +Preferred combinations: + +- Page hero: `bg-[linear-gradient(180deg,#e0f2fe_0%,#f8fafc_100%)]` +- Soft app page: `bg-[linear-gradient(180deg,#f0fdfa_0%,#f8fafc_100%)]` +- Brand chip/avatar: `bg-[linear-gradient(135deg,#ecfeff_0%,#ccfbf1_100%)]` +- Selected nav: `bg-teal-100 text-teal-800 ring-1 ring-teal-200` +- Upload button: `border-sky-200 bg-sky-100 text-sky-800 shadow-[4px_4px_0_0_rgba(14,165,233,0.14)]` + +## Component Rules + +- Header navigation selected state should stay teal, not black. +- Upload action should stay visually distinct from nav, preferably sky blue. +- Username/account entry should be light and calm: white/teal, subtle border, subtle shadow. +- Cards should generally use `bg-white`, `border-slate-200`, and light offset shadows. +- Use gradients for page introductions instead of generic rounded white rectangles. +- When adding hover states, prefer light fills (`hover:bg-teal-50`, `hover:bg-sky-50`) over dark inversion. + +## Status Colors + +- Approved/success: `emerald-100`, `emerald-700`. +- Pending/review: `amber-100`, `amber-700`. +- Rejected/destructive: `rose-100`, `rose-700` or Naive UI `type="error"`. +- Hidden/private/neutral: `slate-100`, `slate-600`. + +## Anti-Patterns + +- Do not use purple as a fallback visual direction. +- Do not use `bg-slate-900 text-white` for ordinary selected navigation. +- Do not introduce dark-mode-heavy sections unless the surrounding page already uses that language. +- Do not overuse rounded rectangles; the project has been intentionally moving toward sharper, atlas-like panels. +- Do not mix random accent colors within the same feature. Pick one accent family and keep it consistent. + +## Validation + +After color/style changes, run: + +```bash +npx vue-tsc -b +``` + +Run `npm run build` if the change touches routes, imported components, or package dependencies. diff --git a/src/components/layout/AppHeader.vue b/src/components/layout/AppHeader.vue index bab738b..f50bbce 100644 --- a/src/components/layout/AppHeader.vue +++ b/src/components/layout/AppHeader.vue @@ -1,6 +1,6 @@ diff --git a/src/views/auth/LoginView.vue b/src/views/auth/LoginView.vue index ea671d9..f8efd66 100644 --- a/src/views/auth/LoginView.vue +++ b/src/views/auth/LoginView.vue @@ -11,7 +11,10 @@ const route = useRoute() const email = ref('') const password = ref('') const error = ref('') +const resetMessage = ref('') +const resetMode = ref(false) const loading = ref(false) +const resetLoading = ref(false) async function handleLogin() { error.value = '' @@ -26,6 +29,26 @@ async function handleLogin() { loading.value = false } } + +async function handleSendResetEmail() { + error.value = '' + resetMessage.value = '' + + if (!email.value) { + error.value = '请输入需要重置密码的邮箱。' + return + } + + resetLoading.value = true + try { + await authStore.sendPasswordReset(email.value) + resetMessage.value = '重置密码邮件已发送,请查收邮箱。' + } catch (e: unknown) { + error.value = e instanceof Error ? e.message : '重置邮件发送失败,请稍后重试' + } finally { + resetLoading.value = false + } +}