-
-
-
-
-
-
-
- {{ history.ip }}
- {{ history.location }}
-
-
- {{ history.username }}
- {{ history.loginTime }}
-
-
-
-
+
+
+
+
+
{{ history.ip || '未知 IP' }}{{ history.location || history.username || '未知位置' }}
+
+
暂无登录记录
-
+
-
-
-
+
+
diff --git a/src/components/Home.vue b/src/components/Home.vue
index 09e8147..be4c3ba 100644
--- a/src/components/Home.vue
+++ b/src/components/Home.vue
@@ -1,528 +1,360 @@
-
-
-
-
-
![头像]()
-
-
-
-
Hi,
- I'm {{ userName }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
![QR Code]()
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
Hi,
+ I'm {{ userName }}
+
+
+
+
+
+
+
+ 当前展示本地备用内容
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![联系方式二维码]()
+
+
+
+
+
+
+
+
+
diff --git a/src/components/IconSelector.vue b/src/components/IconSelector.vue
index a5cfc25..dfe3832 100644
--- a/src/components/IconSelector.vue
+++ b/src/components/IconSelector.vue
@@ -1,517 +1,525 @@
-
-
-
-
-
-
-
-
-
-
-
-
![默认图标]()
-
使用默认本地图标:{{ defaultIconPath }}
-
-
-
-
-
-
-
-
-
-
点击选择图标文件
-
支持 jpg、png、jpeg、webp、avif、svg、ico 等格式
-
-
-
![上传的图标]()
-
已上传的图标
-
-
-
上传中...
-
-
-
-
-
-
-
-
![URL图标]()
-
URL图标预览(支持重定向)
-
-
-
-
-
-
-
当前图标:
-
![当前图标]()
-
{{ currentIcon }}
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
![默认图标]()
+
使用默认本地图标:{{ defaultIconPath }}
+
+
+
+
+
+
+
+
+
+
点击选择图标文件
+
支持 jpg、png、jpeg、webp、avif、svg、ico 等格式
+
+
+
![上传的图标]()
+
已上传的图标
+
+
+
上传中...
+
+
+
+
+
+
+
+
![URL图标]()
+
URL图标预览(支持重定向)
+
+
+
+
+
+
+
当前图标:
+
![当前图标]()
+
{{ currentIcon }}
+
+
+
+
+
+
+
diff --git a/src/components/Login.vue b/src/components/Login.vue
index 4969631..f610ae5 100644
--- a/src/components/Login.vue
+++ b/src/components/Login.vue
@@ -1,403 +1,210 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/Website.vue b/src/components/Website.vue
index f916e44..a32b8a5 100644
--- a/src/components/Website.vue
+++ b/src/components/Website.vue
@@ -1,158 +1,105 @@
-
-
-
-
-
-
-
-
-
- {{ site.name }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
diff --git a/src/components/admin/AdminCollection.vue b/src/components/admin/AdminCollection.vue
new file mode 100644
index 0000000..f9e98dd
--- /dev/null
+++ b/src/components/admin/AdminCollection.vue
@@ -0,0 +1,122 @@
+
+
+
+ {{ kind === 'sites' ? '站点' : '联系方式' }}
+ {{ items.length }}
+
+
+
+
+ | 名称 | 地址 | 图标 | 排序 | 操作 |
+
+
+ | {{ item.name }} |
+ {{ item.url }} |
+ {{ item.icon }} |
+ {{ item.sortOrder }} |
+ |
+
+
+
+
+ | 类型 | 图标 | 链接或二维码 | 悬停颜色 | 排序 | 操作 |
+
+
+ | {{ item.type }} |
+ |
+ {{ item.url }} 二维码 |
+ {{ item.hoverColor }} |
+ {{ item.sortOrder }} |
+ |
+
+
+
+
+
+
+
+
+
+ {{ kind === 'sites' ? item.name : item.type }}
+ {{ item.url || '二维码联系方式' }}
+ 排序 {{ item.sortOrder }}
+
+
+
+
+
+
+
+
暂无{{ kind === 'sites' ? '站点' : '联系方式' }}
+
使用页面右上角的添加按钮创建第一条记录。
+
+
+
+
+
+
+
diff --git a/src/components/admin/AdminConfig.vue b/src/components/admin/AdminConfig.vue
new file mode 100644
index 0000000..722e8a0
--- /dev/null
+++ b/src/components/admin/AdminConfig.vue
@@ -0,0 +1,213 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/AdminModal.vue b/src/components/admin/AdminModal.vue
new file mode 100644
index 0000000..d1ffdac
--- /dev/null
+++ b/src/components/admin/AdminModal.vue
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/composables/useTheme.js b/src/composables/useTheme.js
new file mode 100644
index 0000000..607c2f4
--- /dev/null
+++ b/src/composables/useTheme.js
@@ -0,0 +1,36 @@
+import { computed, ref } from 'vue'
+
+const isDarkMode = ref(false)
+let initialized = false
+
+const applyTheme = (dark) => {
+ isDarkMode.value = Boolean(dark)
+ document.documentElement.classList.toggle('dark-mode', isDarkMode.value)
+ document.body.classList.toggle('dark-mode', isDarkMode.value)
+ document.documentElement.style.colorScheme = isDarkMode.value ? 'dark' : 'light'
+}
+
+export const initializeTheme = () => {
+ if (initialized || typeof window === 'undefined') return
+
+ const savedTheme = localStorage.getItem('darkMode')
+ const prefersDark = window.matchMedia?.('(prefers-color-scheme: dark)').matches
+ applyTheme(savedTheme === null ? prefersDark : savedTheme === 'true')
+ initialized = true
+}
+
+export const useTheme = () => {
+ initializeTheme()
+
+ const toggleTheme = () => {
+ applyTheme(!isDarkMode.value)
+ localStorage.setItem('darkMode', String(isDarkMode.value))
+ }
+
+ return {
+ isDarkMode,
+ themeIcon: computed(() => (isDarkMode.value ? 'fas fa-sun' : 'fas fa-moon')),
+ themeLabel: computed(() => (isDarkMode.value ? '切换到浅色模式' : '切换到深色模式')),
+ toggleTheme,
+ }
+}
diff --git a/src/main.js b/src/main.js
index 37563ae..c6d85bc 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,16 +1,17 @@
-import { createApp } from 'vue';
-import App from './App.vue';
-import './style.less';
-import { MotionPlugin } from '@vueuse/motion';
-import router from './router';
-import { loadAndApplyFrontendConfig } from './utils/frontendConfig';
-
-// 加载前端配置
-loadAndApplyFrontendConfig();
-
-const app = createApp(App);
-
-app.use(MotionPlugin);
-app.use(router);
-
-app.mount('#app');
\ No newline at end of file
+import { createApp } from 'vue';
+import App from './App.vue';
+import './style.less';
+import { MotionPlugin } from '@vueuse/motion';
+import router from './router';
+import { loadAndApplyFrontendConfig } from './utils/frontendConfig';
+import { initializeTheme } from './composables/useTheme';
+
+initializeTheme();
+loadAndApplyFrontendConfig();
+
+const app = createApp(App);
+
+app.use(MotionPlugin);
+app.use(router);
+
+app.mount('#app');
diff --git a/src/router/index.js b/src/router/index.js
index 2ef95a4..4e678e9 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -1,34 +1,46 @@
-import { createRouter, createWebHistory } from 'vue-router'
-import Home from '../components/Home.vue'
-import Admin from '../components/Admin.vue'
-import Login from '../components/Login.vue'
-
-const routes = [
- {
- path: '/',
- component: Home,
- },
- {
- path: '/admin',
- component: Admin,
- beforeEnter: (to, from, next) => {
- const token = localStorage.getItem('token')
- if (!token) {
- next('/login')
- } else {
- next()
- }
- },
- },
- {
- path: '/login',
- component: Login,
- },
-]
-
-const router = createRouter({
- history: createWebHistory(),
- routes,
-})
-
-export default router
+import { createRouter, createWebHistory } from 'vue-router'
+import Home from '../components/Home.vue'
+import Admin from '../components/Admin.vue'
+import Login from '../components/Login.vue'
+
+const routes = [
+ {
+ path: '/',
+ name: 'home',
+ component: Home,
+ },
+ {
+ path: '/admin',
+ name: 'admin',
+ component: Admin,
+ beforeEnter: (to, from, next) => {
+ const token = localStorage.getItem('token')
+ if (!token) {
+ next('/login')
+ } else {
+ next()
+ }
+ },
+ },
+ {
+ path: '/login',
+ name: 'login',
+ component: Login,
+ beforeEnter: (to) => {
+ if (localStorage.getItem('token')) {
+ const redirect = typeof to.query.redirect === 'string' && to.query.redirect.startsWith('/')
+ ? to.query.redirect
+ : '/admin'
+ return redirect
+ }
+ return true
+ },
+ },
+]
+
+const router = createRouter({
+ history: createWebHistory(),
+ routes,
+})
+
+export default router
diff --git a/src/style.less b/src/style.less
index bdaf968..ec77c82 100644
--- a/src/style.less
+++ b/src/style.less
@@ -1,155 +1,167 @@
-:root {
- --border-radius: 10px;
- --text-size: 16px;
- --icon-size: 20px;
- --text-color: #333;
- --background-color: #eee;
- --background-color-rgb: 238, 238, 238;
- --shadow-color: rgba(0, 0, 0, 0.2);
- --border-color: rgb(193 193 193 / 50%);
- --hover-link-color: #ffcc00;
- --hover-other-color: #555;
- --background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxOTInIGhlaWdodD0nMTkyJyB2aWV3Qm94PScwIDAgMTkyIDE5Mic+PHBhdGggZmlsbD0nI2QzZDNkMycgZmlsbC1vcGFjaXR5PScwLjUnIGQ9J00xOTIgMTV2MmExMSAxMSAwIDAgMC0xMSAxMWMwIDEuOTQgMS4xNiA0Ljc1IDIuNTMgNi4xMWwyLjM2IDIuMzZhNi45MyA2LjkzIDAgMCAxIDEuMjIgNy41NmwtLjQzLjg0YTguMDggOC4wOCAwIDAgMS02LjY2IDQuMTNIMTQ1djM1LjAyYTYuMSA2LjEgMCAwIDAgMy4wMyA0Ljg3bC44NC40M2MxLjU4Ljc5IDQgLjQgNS4yNC0uODVsMi4zNi0yLjM2YTEyLjA0IDEyLjA0IDAgMCAxIDcuNTEtMy4xMSAxMyAxMyAwIDEgMSAuMDIgMjYgMTIgMTIgMCAwIDEtNy41My0zLjExbC0yLjM2LTIuMzZhNC45MyA0LjkzIDAgMCAwLTUuMjQtLjg1bC0uODQuNDNhNi4xIDYuMSAwIDAgMC0zLjAzIDQuODdWMTQzaDM1LjAyYTguMDggOC4wOCAwIDAgMSA2LjY2IDQuMTNsLjQzLjg0YTYuOTEgNi45MSAwIDAgMS0xLjIyIDcuNTZsLTIuMzYgMi4zNkExMC4wNiAxMC4wNiAwIDAgMCAxODEgMTY0YTExIDExIDAgMCAwIDExIDExdjJhMTMgMTMgMCAwIDEtMTMtMTMgMTIgMTIgMCAwIDEgMy4xMS03LjUzbDIuMzYtMi4zNmE0LjkzIDQuOTMgMCAwIDAgLjg1LTUuMjRsLS40My0uODRhNi4xIDYuMSAwIDAgMC00Ljg3LTMuMDNIMTQ1djM1LjAyYTguMDggOC4wOCAwIDAgMS00LjEzIDYuNjZsLS44NC40M2E2LjkxIDYuOTEgMCAwIDEtNy41Ni0xLjIybC0yLjM2LTIuMzZBMTAuMDYgMTAuMDYgMCAwIDAgMTI0IDE4MWExMSAxMSAwIDAgMC0xMSAxMWgtMmExMyAxMyAwIDAgMSAxMy0xM2MyLjQ3IDAgNS43OSAxLjM3IDcuNTMgMy4xMWwyLjM2IDIuMzZhNC45NCA0Ljk0IDAgMCAwIDUuMjQuODVsLjg0LS40M2E2LjEgNi4xIDAgMCAwIDMuMDMtNC44N1YxNDVoLTM1LjAyYTguMDggOC4wOCAwIDAgMS02LjY2LTQuMTNsLS40My0uODRhNi45MSA2LjkxIDAgMCAxIDEuMjItNy41NmwyLjM2LTIuMzZBMTAuMDYgMTAuMDYgMCAwIDAgMTA3IDEyNGExMSAxMSAwIDAgMC0yMiAwYzAgMS45NCAxLjE2IDQuNzUgMi41MyA2LjExbDIuMzYgMi4zNmE2LjkzIDYuOTMgMCAwIDEgMS4yMiA3LjU2bC0uNDMuODRhOC4wOCA4LjA4IDAgMCAxLTYuNjYgNC4xM0g0OXYzNS4wMmE2LjEgNi4xIDAgMCAwIDMuMDMgNC44N2wuODQuNDNjMS41OC43OSA0IC40IDUuMjQtLjg1bDIuMzYtMi4zNmExMi4wNCAxMi4wNCAwIDAgMSA3LjUxLTMuMTFBMTMgMTMgMCAwIDEgODEgMTkyaC0yYTExIDExIDAgMCAwLTExLTExYy0xLjk0IDAtNC43NSAxLjE2LTYuMTEgMi41M2wtMi4zNiAyLjM2YTYuOTMgNi45MyAwIDAgMS03LjU2IDEuMjJsLS44NC0uNDNhOC4wOCA4LjA4IDAgMCAxLTQuMTMtNi42NlYxNDVIMTEuOThhNi4xIDYuMSAwIDAgMC00Ljg3IDMuMDNsLS40My44NGMtLjc5IDEuNTgtLjQgNCAuODUgNS4yNGwyLjM2IDIuMzZhMTIuMDQgMTIuMDQgMCAwIDEgMy4xMSA3LjUxQTEzIDEzIDAgMCAxIDAgMTc3di0yYTExIDExIDAgMCAwIDExLTExYzAtMS45NC0xLjE2LTQuNzUtMi41My02LjExbC0yLjM2LTIuMzZhNi45MyA2LjkzIDAgMCAxLTEuMjItNy41NmwuNDMtLjg0YTguMDggOC4wOCAwIDAgMSA2LjY2LTQuMTNINDd2LTM1LjAyYTYuMSA2LjEgMCAwIDAtMy4wMy00Ljg3bC0uODQtLjQzYy0xLjU5LS44LTQtLjQtNS4yNC44NWwtMi4zNiAyLjM2QTEyIDEyIDAgMCAxIDI4IDEwOWExMyAxMyAwIDEgMSAwLTI2YzIuNDcgMCA1Ljc5IDEuMzcgNy41MyAzLjExbDIuMzYgMi4zNmE0Ljk0IDQuOTQgMCAwIDAgNS4yNC44NWwuODQtLjQzQTYuMSA2LjEgMCAwIDAgNDcgODQuMDJWNDlIMTEuOThhOC4wOCA4LjA4IDAgMCAxLTYuNjYtNC4xM2wtLjQzLS44NGE2LjkxIDYuOTEgMCAwIDEgMS4yMi03LjU2bDIuMzYtMi4zNkExMC4wNiAxMC4wNiAwIDAgMCAxMSAyOCAxMSAxMSAwIDAgMCAwIDE3di0yYTEzIDEzIDAgMCAxIDEzIDEzYzAgMi40Ny0xLjM3IDUuNzktMy4xMSA3LjUzbC0yLjM2IDIuMzZhNC45NCA0Ljk0IDAgMCAwLS44NSA1LjI0bC40My44NEE2LjEgNi4xIDAgMCAwIDExLjk4IDQ3SDQ3VjExLjk4YTguMDggOC4wOCAwIDAgMSA0LjEzLTYuNjZsLjg0LS40M2E2LjkxIDYuOTEgMCAwIDEgNy41NiAxLjIybDIuMzYgMi4zNkExMC4wNiAxMC4wNiAwIDAgMCA2OCAxMSAxMSAxMSAwIDAgMCA3OSAwaDJhMTMgMTMgMCAwIDEtMTMgMTMgMTIgMTIgMCAwIDEtNy41My0zLjExbC0yLjM2LTIuMzZhNC45MyA0LjkzIDAgMCAwLTUuMjQtLjg1bC0uODQuNDNBNi4xIDYuMSAwIDAgMCA0OSAxMS45OFY0N2gzNS4wMmE4LjA4IDguMDggMCAwIDEgNi42NiA0LjEzbC40My44NGE2LjkxIDYuOTEgMCAwIDEtMS4yMiA3LjU2bC0yLjM2IDIuMzZBMTAuMDYgMTAuMDYgMCAwIDAgODUgNjhhMTEgMTEgMCAwIDAgMjIgMGMwLTEuOTQtMS4xNi00Ljc1LTIuNTMtNi4xMWwtMi4zNi0yLjM2YTYuOTMgNi45MyAwIDAgMS0xLjIyLTcuNTZsLjQzLS44NGE4LjA4IDguMDggMCAwIDEgNi42Ni00LjEzSDE0M1YxMS45OGE2LjEgNi4xIDAgMCAwLTMuMDMtNC44N2wtLjg0LS40M2MtMS41OS0uOC00LS40LTUuMjQuODVsLTIuMzYgMi4zNkExMiAxMiAwIDAgMSAxMjQgMTNhMTMgMTMgMCAwIDEtMTMtMTNoMmExMSAxMSAwIDAgMCAxMSAxMWMxLjk0IDAgNC43NS0xLjE2IDYuMTEtMi41M2wyLjM2LTIuMzZhNi45MyA2LjkzIDAgMCAxIDcuNTYtMS4yMmwuODQuNDNhOC4wOCA4LjA4IDAgMCAxIDQuMTMgNi42NlY0N2gzNS4wMmE2LjEgNi4xIDAgMCAwIDQuODctMy4wM2wuNDMtLjg0Yy44LTEuNTkuNC00LS44NS01LjI0bC0yLjM2LTIuMzZBMTIgMTIgMCAwIDEgMTc5IDI4YTEzIDEzIDAgMCAxIDEzLTEzek04NC4wMiAxNDNhNi4xIDYuMSAwIDAgMCA0Ljg3LTMuMDNsLjQzLS44NGMuOC0xLjU5LjQtNC0uODUtNS4yNGwtMi4zNi0yLjM2QTEyIDEyIDAgMCAxIDgzIDEyNGExMyAxMyAwIDEgMSAyNiAwYzAgMi40Ny0xLjM3IDUuNzktMy4xMSA3LjUzbC0yLjM2IDIuMzZhNC45NCA0Ljk0IDAgMCAwLS44NSA1LjI0bC40My44NGE2LjEgNi4xIDAgMCAwIDQuODcgMy4wM0gxNDN2LTM1LjAyYTguMDggOC4wOCAwIDAgMSA0LjEzLTYuNjZsLjg0LS40M2E2LjkxIDYuOTEgMCAwIDEgNy41NiAxLjIybDIuMzYgMi4zNkExMC4wNiAxMC4wNiAwIDAgMCAxNjQgMTA3YTExIDExIDAgMCAwIDAtMjJjLTEuOTQgMC00Ljc1IDEuMTYtNi4xMSAyLjUzbC0yLjM2IDIuMzZhNi45MyA2LjkzIDAgMCAxLTcuNTYgMS4yMmwtLjg0LS40M2E4LjA4IDguMDggMCAwIDEtNC4xMy02LjY2VjQ5aC0zNS4wMmE2LjEgNi4xIDAgMCAwLTQuODcgMy4wM2wtLjQzLjg0Yy0uNzkgMS41OC0uNCA0IC44NSA1LjI0bDIuMzYgMi4zNmExMi4wNCAxMi4wNCAwIDAgMSAzLjExIDcuNTFBMTMgMTMgMCAxIDEgODMgNjhhMTIgMTIgMCAwIDEgMy4xMS03LjUzbDIuMzYtMi4zNmE0LjkzIDQuOTMgMCAwIDAgLjg1LTUuMjRsLS40My0uODRBNi4xIDYuMSAwIDAgMCA4NC4wMiA0OUg0OXYzNS4wMmE4LjA4IDguMDggMCAwIDEtNC4xMyA2LjY2bC0uODQuNDNhNi45MSA2LjkxIDAgMCAxLTcuNTYtMS4yMmwtMi4zNi0yLjM2QTEwLjA2IDEwLjA2IDAgMCAwIDI4IDg1YTExIDExIDAgMCAwIDAgMjJjMS45NCAwIDQuNzUtMS4xNiA2LjExLTIuNTNsMi4zNi0yLjM2YTYuOTMgNi45MyAwIDAgMSA3LjU2LTEuMjJsLjg0LjQzYTguMDggOC4wOCAwIDAgMSA0LjEzIDYuNjZWMTQzaDM1LjAyeic+PC9wYXRoPjwvc3ZnPg==);
-}
-
-.dark-mode {
- --text-color: #eee;
- --background-color: #333;
- --background-color-rgb: 51, 51, 51;
- --shadow-color: rgba(255, 255, 255, 0.2);
- --border-color: rgb(131 131 131 / 50%);
- --background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxOTInIGhlaWdodD0nMTkyJyB2aWV3Qm94PScwIDAgMTkyIDE5Mic+PHBhdGggZmlsbD0nIzVhNWE1YScgZmlsbC1vcGFjaXR5PScwLjUnIGQ9J00xOTIgMTV2MmExMSAxMSAwIDAgMC0xMSAxMWMwIDEuOTQgMS4xNiA0Ljc1IDIuNTMgNi4xMWwyLjM2IDIuMzZhNi45MyA2LjkzIDAgMCAxIDEuMjIgNy41NmwtLjQzLjg0YTguMDggOC4wOCAwIDAgMS02LjY2IDQuMTNIMTQ1djM1LjAyYTYuMSA2LjEgMCAwIDAgMy4wMyA0Ljg3bC44NC40M2MxLjU4Ljc5IDQgLjQgNS4yNC0uODVsMi4zNi0yLjM2YTEyLjA0IDEyLjA0IDAgMCAxIDcuNTEtMy4xMSAxMyAxMyAwIDEgMSAuMDIgMjYgMTIgMTIgMCAwIDEtNy41My0zLjExbC0yLjM2LTIuMzZhNC45MyA0LjkzIDAgMCAwLTUuMjQtLjg1bC0uODQuNDNhNi4xIDYuMSAwIDAgMC0zLjAzIDQuODdWMTQzaDM1LjAyYTguMDggOC4wOCAwIDAgMSA2LjY2IDQuMTNsLjQzLjg0YTYuOTEgNi45MSAwIDAgMS0xLjIyIDcuNTZsLTIuMzYgMi4zNkExMC4wNiAxMC4wNiAwIDAgMCAxODEgMTY0YTExIDExIDAgMCAwIDExIDExdjJhMTMgMTMgMCAwIDEtMTMtMTMgMTIgMTIgMCAwIDEgMy4xMS03LjUzbDIuMzYtMi4zNmE0LjkzIDQuOTMgMCAwIDAgLjg1LTUuMjRsLS40My0uODRhNi4xIDYuMSAwIDAgMC00Ljg3LTMuMDNIMTQ1djM1LjAyYTguMDggOC4wOCAwIDAgMS00LjEzIDYuNjZsLS44NC40M2E2LjkxIDYuOTEgMCAwIDEtNy41Ni0xLjIybC0yLjM2LTIuMzZBMTAuMDYgMTAuMDYgMCAwIDAgMTI0IDE4MWExMSAxMSAwIDAgMC0xMSAxMWgtMmExMyAxMyAwIDAgMSAxMy0xM2MyLjQ3IDAgNS43OSAxLjM3IDcuNTMgMy4xMWwyLjM2IDIuMzZhNC45NCA0Ljk0IDAgMCAwIDUuMjQuODVsLjg0LS40M2E2LjEgNi4xIDAgMCAwIDMuMDMtNC44N1YxNDVoLTM1LjAyYTguMDggOC4wOCAwIDAgMS02LjY2LTQuMTNsLS40My0uODRhNi45MSA2LjkxIDAgMCAxIDEuMjItNy41NmwyLjM2LTIuMzZBMTAuMDYgMTAuMDYgMCAwIDAgMTA3IDEyNGExMSAxMSAwIDAgMC0yMiAwYzAgMS45NCAxLjE2IDQuNzUgMi41MyA2LjExbDIuMzYgMi4zNmE2LjkzIDYuOTMgMCAwIDEgMS4yMiA3LjU2bC0uNDMuODRhOC4wOCA4LjA4IDAgMCAxLTYuNjYgNC4xM0g0OXYzNS4wMmE2LjEgNi4xIDAgMCAwIDMuMDMgNC44N2wuODQuNDNjMS41OC43OSA0IC40IDUuMjQtLjg1bDIuMzYtMi4zNmExMi4wNCAxMi4wNCAwIDAgMSA3LjUxLTMuMTFBMTMgMTMgMCAwIDEgODEgMTkyaC0yYTExIDExIDAgMCAwLTExLTExYy0xLjk0IDAtNC43NSAxLjE2LTYuMTEgMi41M2wtMi4zNiAyLjM2YTYuOTMgNi45MyAwIDAgMS03LjU2IDEuMjJsLS44NC0uNDNhOC4wOCA4LjA4IDAgMCAxLTQuMTMtNi42NlYxNDVIMTEuOThhNi4xIDYuMSAwIDAgMC00Ljg3IDMuMDNsLS40My44NGMtLjc5IDEuNTgtLjQgNCAuODUgNS4yNGwyLjM2IDIuMzZhMTIuMDQgMTIuMDQgMCAwIDEgMy4xMSA3LjUxQTEzIDEzIDAgMCAxIDAgMTc3di0yYTExIDExIDAgMCAwIDExLTExYzAtMS45NC0xLjE2LTQuNzUtMi41My02LjExbC0yLjM2LTIuMzZhNi45MyA2LjkzIDAgMCAxLTEuMjItNy41NmwuNDMtLjg0YTguMDggOC4wOCAwIDAgMSA2LjY2LTQuMTNINDd2LTM1LjAyYTYuMSA2LjEgMCAwIDAtMy4wMy00Ljg3bC0uODQtLjQzYy0xLjU5LS44LTQtLjQtNS4yNC44NWwtMi4zNiAyLjM2QTEyIDEyIDAgMCAxIDI4IDEwOWExMyAxMyAwIDEgMSAwLTI2YzIuNDcgMCA1Ljc5IDEuMzcgNy41MyAzLjExbDIuMzYgMi4zNmE0Ljk0IDQuOTQgMCAwIDAgNS4yNC44NWwuODQtLjQzQTYuMSA2LjEgMCAwIDAgNDcgODQuMDJWNDlIMTEuOThhOC4wOCA4LjA4IDAgMCAxLTYuNjYtNC4xM2wtLjQzLS44NGE2LjkxIDYuOTEgMCAwIDEgMS4yMi03LjU2bDIuMzYtMi4zNkExMC4wNiAxMC4wNiAwIDAgMCAxMSAyOCAxMSAxMSAwIDAgMCAwIDE3di0yYTEzIDEzIDAgMCAxIDEzIDEzYzAgMi40Ny0xLjM3IDUuNzktMy4xMSA3LjUzbC0yLjM2IDIuMzZhNC45NCA0Ljk0IDAgMCAwLS44NSA1LjI0bC40My44NEE2LjEgNi4xIDAgMCAwIDExLjk4IDQ3SDQ3VjExLjk4YTguMDggOC4wOCAwIDAgMSA0LjEzLTYuNjZsLjg0LS40M2E2LjkxIDYuOTEgMCAwIDEgNy41NiAxLjIybDIuMzYgMi4zNkExMC4wNiAxMC4wNiAwIDAgMCA2OCAxMSAxMSAxMSAwIDAgMCA3OSAwaDJhMTMgMTMgMCAwIDEtMTMgMTMgMTIgMTIgMCAwIDEtNy41My0zLjExbC0yLjM2LTIuMzZhNC45MyA0LjkzIDAgMCAwLTUuMjQtLjg1bC0uODQuNDNBNi4xIDYuMSAwIDAgMCA0OSAxMS45OFY0N2gzNS4wMmE4LjA4IDguMDggMCAwIDEgNi42NiA0LjEzbC40My44NGE2LjkxIDYuOTEgMCAwIDEtMS4yMiA3LjU2bC0yLjM2IDIuMzZBMTAuMDYgMTAuMDYgMCAwIDAgODUgNjhhMTEgMTEgMCAwIDAgMjIgMGMwLTEuOTQtMS4xNi00Ljc1LTIuNTMtNi4xMWwtMi4zNi0yLjM2YTYuOTMgNi45MyAwIDAgMS0xLjIyLTcuNTZsLjQzLS44NGE4LjA4IDguMDggMCAwIDEgNi42Ni00LjEzSDE0M1YxMS45OGE2LjEgNi4xIDAgMCAwLTMuMDMtNC44N2wtLjg0LS40M2MtMS41OS0uOC00LS40LTUuMjQuODVsLTIuMzYgMi4zNkExMiAxMiAwIDAgMSAxMjQgMTNhMTMgMTMgMCAwIDEtMTMtMTNoMmExMSAxMSAwIDAgMCAxMSAxMWMxLjk0IDAgNC43NS0xLjE2IDYuMTEtMi41M2wyLjM2LTIuMzZhNi45MyA2LjkzIDAgMCAxIDcuNTYtMS4yMmwuODQuNDNhOC4wOCA4LjA4IDAgMCAxIDQuMTMgNi42NlY0N2gzNS4wMmE2LjEgNi4xIDAgMCAwIDQuODctMy4wM2wuNDMtLjg0Yy44LTEuNTkuNC00LS44NS01LjI0bC0yLjM2LTIuMzZBMTIgMTIgMCAwIDEgMTc5IDI4YTEzIDEzIDAgMCAxIDEzLTEzek04NC4wMiAxNDNhNi4xIDYuMSAwIDAgMCA0Ljg3LTMuMDNsLjQzLS44NGMuOC0xLjU5LjQtNC0uODUtNS4yNGwtMi4zNi0yLjM2QTEyIDEyIDAgMCAxIDgzIDEyNGExMyAxMyAwIDEgMSAyNiAwYzAgMi40Ny0xLjM3IDUuNzktMy4xMSA3LjUzbC0yLjM2IDIuMzZhNC45NCA0Ljk0IDAgMCAwLS44NSA1LjI0bC40My44NGE2LjEgNi4xIDAgMCAwIDQuODcgMy4wM0gxNDN2LTM1LjAyYTguMDggOC4wOCAwIDAgMSA0LjEzLTYuNjZsLjg0LS40M2E2LjkxIDYuOTEgMCAwIDEgNy41NiAxLjIybDIuMzYgMi4zNkExMC4wNiAxMC4wNiAwIDAgMCAxNjQgMTA3YTExIDExIDAgMCAwIDAtMjJjLTEuOTQgMC00Ljc1IDEuMTYtNi4xMSAyLjUzbC0yLjM2IDIuMzZhNi45MyA2LjkzIDAgMCAxLTcuNTYgMS4yMmwtLjg0LS40M2E4LjA4IDguMDggMCAwIDEtNC4xMy02LjY2VjQ5aC0zNS4wMmE2LjEgNi4xIDAgMCAwLTQuODcgMy4wM2wtLjQzLjg0Yy0uNzkgMS41OC0uNCA0IC44NSA1LjI0bDIuMzYgMi4zNmExMi4wNCAxMi4wNCAwIDAgMSAzLjExIDcuNTFBMTMgMTMgMCAxIDEgODMgNjhhMTIgMTIgMCAwIDEgMy4xMS03LjUzbDIuMzYtMi4zNmE0LjkzIDQuOTMgMCAwIDAgLjg1LTUuMjRsLS40My0uODRBNi4xIDYuMSAwIDAgMCA4NC4wMiA0OUg0OXYzNS4wMmE4LjA4IDguMDggMCAwIDEtNC4xMyA2LjY2bC0uODQuNDNhNi45MSA2LjkxIDAgMCAxLTcuNTYtMS4yMmwtMi4zNi0yLjM2QTEwLjA2IDEwLjA2IDAgMCAwIDI4IDg1YTExIDExIDAgMCAwIDAgMjJjMS45NCAwIDQuNzUtMS4xNiA2LjExLTIuNTNsMi4zNi0yLjM2YTYuOTMgNi45MyAwIDAgMSA3LjU2LTEuMjJsLjg0LjQzYTguMDggOC4wOCAwIDAgMSA0LjEzIDYuNjZWMTQzaDM1LjAyeic+PC9wYXRoPjwvc3ZnPg==);
-}
-
-* {
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- box-sizing: border-box;
-}
-
-/* 顶部呼吸弹窗通知动画 - 全局样式 */
-@keyframes slideDownAndBreathe {
- 0% {
- transform: translate(-50%, -100%);
- opacity: 0;
- }
- 50% {
- transform: translate(-50%, 0);
- opacity: 1;
- }
- 60% {
- transform: translate(-50%, 0) scale(1.03);
- }
- 70% {
- transform: translate(-50%, 0) scale(1);
- }
- 80% {
- transform: translate(-50%, 0) scale(1.02);
- }
- 100% {
- transform: translate(-50%, 0) scale(1);
- opacity: 1;
- }
-}
-
-@keyframes slideUpAndFade {
- from {
- transform: translate(-50%, 0) scale(1);
- opacity: 1;
- }
- to {
- transform: translate(-50%, -100%) scale(0.9);
- opacity: 0;
- }
-}
-
-/* 确保通知在全局样式下正确显示 */
-.top-notification {
- position: fixed !important;
- top: 0 !important;
- left: 50% !important;
- z-index: 10000 !important;
-}
-
-a {
- text-decoration: none;
-}
-
-ul {
- padding: 0;
- list-style: none;
- margin: 0;
-}
-
-body, html {
- height: 100%;
- margin: 0;
- display: flex;
- flex-direction: column;
- font-family: 'HarmonyOS_Regular', 'MiSans', 'HarmonyOS Sans SC', sans-serif;
- color: var(--text-color);
- overflow: hidden;
-}
-
-body.dark-mode {
- filter: brightness(0.7);
-}
-
-/* App 页面 */
-#app {
- flex: 1;
- display: flex;
- flex-direction: column;
- padding: 0 10px;
-}
-
-.background {
- position: fixed;
- top: 0;
- left: 0;
- width: 100vw;
- height: 100vh;
- display: flex;
- align-items: center;
- justify-content: center;
- z-index: -2;
- background: var(--background-color) var(--background-image) repeat;
-}
-
-
-footer {
- padding: 10px 0;
- display: flex;
- justify-content: center;
- margin: 0;
- font-size: var(--text-size);
- gap: 8px;
-
- a {
- color: var(--text-color);
- transition: all 0.3s ease-in-out;
- &:hover {
- color: var(--hover-link-color);
- }
- }
-}
-
-.police_link {
- display: flex;
- align-items: center;
-
- .police_img {
- display: inline-block;
- width: 20px;
- height: 20px;
- background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAACglBMVEUAAAD89dn+/ODz6KrcrGreqFfYrn3x16769M3oxnyaaVzhs2ifaFXbrGLkvFnpyF7v2X/kwm3cp1nhsGfqw3rntVzjrFPt3oDjvGnbnFGti3q0lH7ktoLryXn9v1T4znr/74bnvGz034v+2I/ktoDz6ZLkwY/Dfz7buoftzYbq2IPr0pjs3bLv6KPRrnbKhFv/+dDZr4Lx38f/+cH/95f42oL7/97s2Y3++uzTk3AAAXgCAWbmulrdmUXWHRcBAm7uzWbpwmLsxl3ktV3qvFr/0ljmwFHksE7fo0raSijXPSDWAgjPAAJrdoeUj4EAAICRiXb143Pyy27w1Gz+z2XtymH/217qyVy7jluTeFrrwFfislP+xVJRNlHpuFDpsErVkEbysETajkPpgj7ThT3ilDvXdTg5FDjdhTXtcTDWZTC7TCbuXiPTOCLJPR/TLhzJJxP9LA+0Bw/QFg2Ej5kcPpdyhZSptJEACJFpfo4AG44XMInFvYfTvIejmYRyeoJzdoK9un7FrnwAEHp8enny2HjWwHjKtnhcX3jYzHfu2HWsonPNwnH70m9WTm8AAW//723pym3dtmm0o2ZeWWb/4mPtwmJuYmL/vmB5ZGAMAF2njVn4xFjYnli0mVjiqVfyyVbmtlbXkVPlvFLNrFKjfVLuvlBgHlDsuU9ODk7/2E02Gk3jqkqEaUr/tUngjkf7n0b6xERCJETdn0K1gD/ooD3Ulj3TZT3WjjzOeDqBWDr3pDlMADnbbTf2gjbkbzaTYDZpAjbplzTEazPXXzOeXzDMPi38jizJWSrVSCrzfCjVdCjTQCbFUiTlYCPiRh7SIRrRDBG/ABHBDAvEGArJAAJrcyAdAAAAOnRSTlMAGghC4MasaVv7+/n39fTw7Ozr5+bk5OHg0tHLx8TDwb68urKxq5+cmJWTjIN8b11MSEFBNTApJyEUZZQtrgAAAW1JREFUGNNigAJGdmkpdkYGZGDMxnN019qlXGwGCDGmiPQDh89lTupOj2CCa5WPjTzlnevps6E8Vhkqasa9esrxC3b5nsWXZ/huEjEHC5oE+M/O8c63u5h7NafRPsAUrFnOz2rLeW87Ly87H6/O/hYFC6Cg3u46/3n7fE5sc1tfnNlj7+eqABTUONRUMX1jdl5W2t6kqTOtahLVgIIsGUGl9tnJJ/OOnNm/3bq6NZUFKAgY7851ZVZFhVln05ILL1lXxqRIAAVVNofUVu0pulJQ4HnsYHN7b7QmUFAmaX5IiZW19crls6yt6sOc18gCBTnnLkoNaov0nbyko69h2lZbdwGgIMdij4TTc8JWxSS6TnDNSMgOZ2YAifK7pexwcHG3cQi2tZ0oCBZjMBIOd1oY5eQY6uJhE+woBBFUCuxydnZxd4yz9bCxcQhUhYSmFl/cgmXxK+KjnNxCxXVhAWqpr84qKSbKqqhtCOYDALPYc2hoS0J5AAAAAElFTkSuQmCC");
- }
-}
-
-@media screen and (max-width: 768px) {
- .police_link {
- display: none;
- }
-}
\ No newline at end of file
+:root {
+ --border-radius: 10px;
+ --text-size: 16px;
+ --icon-size: 20px;
+ --text-color: #333;
+ --background-color: #eee;
+ --background-color-rgb: 238, 238, 238;
+ --shadow-color: rgba(0, 0, 0, 0.2);
+ --border-color: rgb(193 193 193 / 50%);
+ --hover-link-color: #ffcc00;
+ --hover-link-color-rgb: 255, 204, 0;
+ --hover-other-color: #555;
+ --surface-color: rgba(238, 238, 238, 0.86);
+ --surface-solid: #f6f6f4;
+ --surface-muted: rgba(255, 255, 255, 0.38);
+ --text-muted: #6d6d68;
+ --success-color: #238636;
+ --danger-color: #c9362b;
+ --warning-color: #a76500;
+ --focus-ring: rgba(255, 204, 0, 0.34);
+ --control-height: 40px;
+ --background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxOTInIGhlaWdodD0nMTkyJyB2aWV3Qm94PScwIDAgMTkyIDE5Mic+PHBhdGggZmlsbD0nI2QzZDNkMycgZmlsbC1vcGFjaXR5PScwLjUnIGQ9J00xOTIgMTV2MmExMSAxMSAwIDAgMC0xMSAxMWMwIDEuOTQgMS4xNiA0Ljc1IDIuNTMgNi4xMWwyLjM2IDIuMzZhNi45MyA2LjkzIDAgMCAxIDEuMjIgNy41NmwtLjQzLjg0YTguMDggOC4wOCAwIDAgMS02LjY2IDQuMTNIMTQ1djM1LjAyYTYuMSA2LjEgMCAwIDAgMy4wMyA0Ljg3bC44NC40M2MxLjU4Ljc5IDQgLjQgNS4yNC0uODVsMi4zNi0yLjM2YTEyLjA0IDEyLjA0IDAgMCAxIDcuNTEtMy4xMSAxMyAxMyAwIDEgMSAuMDIgMjYgMTIgMTIgMCAwIDEtNy41My0zLjExbC0yLjM2LTIuMzZhNC45MyA0LjkzIDAgMCAwLTUuMjQtLjg1bC0uODQuNDNhNi4xIDYuMSAwIDAgMC0zLjAzIDQuODdWMTQzaDM1LjAyYTguMDggOC4wOCAwIDAgMSA2LjY2IDQuMTNsLjQzLjg0YTYuOTEgNi45MSAwIDAgMS0xLjIyIDcuNTZsLTIuMzYgMi4zNkExMC4wNiAxMC4wNiAwIDAgMCAxODEgMTY0YTExIDExIDAgMCAwIDExIDExdjJhMTMgMTMgMCAwIDEtMTMtMTMgMTIgMTIgMCAwIDEgMy4xMS03LjUzbDIuMzYtMi4zNmE0LjkzIDQuOTMgMCAwIDAgLjg1LTUuMjRsLS40My0uODRhNi4xIDYuMSAwIDAgMC00Ljg3LTMuMDNIMTQ1djM1LjAyYTguMDggOC4wOCAwIDAgMS00LjEzIDYuNjZsLS44NC40M2E2LjkxIDYuOTEgMCAwIDEtNy41Ni0xLjIybC0yLjM2LTIuMzZBMTAuMDYgMTAuMDYgMCAwIDAgMTI0IDE4MWExMSAxMSAwIDAgMC0xMSAxMWgtMmExMyAxMyAwIDAgMSAxMy0xM2MyLjQ3IDAgNS43OSAxLjM3IDcuNTMgMy4xMWwyLjM2IDIuMzZhNC45NCA0Ljk0IDAgMCAwIDUuMjQuODVsLjg0LS40M2E2LjEgNi4xIDAgMCAwIDMuMDMtNC44N1YxNDVoLTM1LjAyYTguMDggOC4wOCAwIDAgMS02LjY2LTQuMTNsLS40My0uODRhNi45MSA2LjkxIDAgMCAxIDEuMjItNy41NmwyLjM2LTIuMzZBMTAuMDYgMTAuMDYgMCAwIDAgMTA3IDEyNGExMSAxMSAwIDAgMC0yMiAwYzAgMS45NCAxLjE2IDQuNzUgMi41MyA2LjExbDIuMzYgMi4zNmE2LjkzIDYuOTMgMCAwIDEgMS4yMiA3LjU2bC0uNDMuODRhOC4wOCA4LjA4IDAgMCAxLTYuNjYgNC4xM0g0OXYzNS4wMmE2LjEgNi4xIDAgMCAwIDMuMDMgNC44N2wuODQuNDNjMS41OC43OSA0IC40IDUuMjQtLjg1bDIuMzYtMi4zNmExMi4wNCAxMi4wNCAwIDAgMSA3LjUxLTMuMTFBMTMgMTMgMCAwIDEgODEgMTkyaC0yYTExIDExIDAgMCAwLTExLTExYy0xLjk0IDAtNC43NSAxLjE2LTYuMTEgMi41M2wtMi4zNiAyLjM2YTYuOTMgNi45MyAwIDAgMS03LjU2IDEuMjJsLS44NC0uNDNhOC4wOCA4LjA4IDAgMCAxLTQuMTMtNi42NlYxNDVIMTEuOThhNi4xIDYuMSAwIDAgMC00Ljg3IDMuMDNsLS40My44NGMtLjc5IDEuNTgtLjQgNCAuODUgNS4yNGwyLjM2IDIuMzZhMTIuMDQgMTIuMDQgMCAwIDEgMy4xMSA3LjUxQTEzIDEzIDAgMCAxIDAgMTc3di0yYTExIDExIDAgMCAwIDExLTExYzAtMS45NC0xLjE2LTQuNzUtMi41My02LjExbC0yLjM2LTIuMzZhNi45MyA2LjkzIDAgMCAxLTEuMjItNy41NmwuNDMtLjg0YTguMDggOC4wOCAwIDAgMSA2LjY2LTQuMTNINDd2LTM1LjAyYTYuMSA2LjEgMCAwIDAtMy4wMy00Ljg3bC0uODQtLjQzYy0xLjU5LS44LTQtLjQtNS4yNC44NWwtMi4zNiAyLjM2QTEyIDEyIDAgMCAxIDI4IDEwOWExMyAxMyAwIDEgMSAwLTI2YzIuNDcgMCA1Ljc5IDEuMzcgNy41MyAzLjExbDIuMzYgMi4zNmE0Ljk0IDQuOTQgMCAwIDAgNS4yNC44NWwuODQtLjQzQTYuMSA2LjEgMCAwIDAgNDcgODQuMDJWNDlIMTEuOThhOC4wOCA4LjA4IDAgMCAxLTYuNjYtNC4xM2wtLjQzLS44NGE2LjkxIDYuOTEgMCAwIDEgMS4yMi03LjU2bDIuMzYtMi4zNkExMC4wNiAxMC4wNiAwIDAgMCAxMSAyOCAxMSAxMSAwIDAgMCAwIDE3di0yYTEzIDEzIDAgMCAxIDEzIDEzYzAgMi40Ny0xLjM3IDUuNzktMy4xMSA3LjUzbC0yLjM2IDIuMzZhNC45NCA0Ljk0IDAgMCAwLS44NSA1LjI0bC40My44NEE2LjEgNi4xIDAgMCAwIDExLjk4IDQ3SDQ3VjExLjk4YTguMDggOC4wOCAwIDAgMSA0LjEzLTYuNjZsLjg0LS40M2E2LjkxIDYuOTEgMCAwIDEgNy41NiAxLjIybDIuMzYgMi4zNkExMC4wNiAxMC4wNiAwIDAgMCA2OCAxMSAxMSAxMSAwIDAgMCA3OSAwaDJhMTMgMTMgMCAwIDEtMTMgMTMgMTIgMTIgMCAwIDEtNy41My0zLjExbC0yLjM2LTIuMzZhNC45MyA0LjkzIDAgMCAwLTUuMjQtLjg1bC0uODQuNDNBNi4xIDYuMSAwIDAgMCA0OSAxMS45OFY0N2gzNS4wMmE4LjA4IDguMDggMCAwIDEgNi42NiA0LjEzbC40My44NGE2LjkxIDYuOTEgMCAwIDEtMS4yMiA3LjU2bC0yLjM2IDIuMzZBMTAuMDYgMTAuMDYgMCAwIDAgODUgNjhhMTEgMTEgMCAwIDAgMjIgMGMwLTEuOTQtMS4xNi00Ljc1LTIuNTMtNi4xMWwtMi4zNi0yLjM2YTYuOTMgNi45MyAwIDAgMS0xLjIyLTcuNTZsLjQzLS44NGE4LjA4IDguMDggMCAwIDEgNi42Ni00LjEzSDE0M1YxMS45OGE2LjEgNi4xIDAgMCAwLTMuMDMtNC44N2wtLjg0LS40M2MtMS41OS0uOC00LS40LTUuMjQuODVsLTIuMzYgMi4zNkExMiAxMiAwIDAgMSAxMjQgMTNhMTMgMTMgMCAwIDEtMTMtMTNoMmExMSAxMSAwIDAgMCAxMSAxMWMxLjk0IDAgNC43NS0xLjE2IDYuMTEtMi41M2wyLjM2LTIuMzZhNi45MyA2LjkzIDAgMCAxIDcuNTYtMS4yMmwuODQuNDNhOC4wOCA4LjA4IDAgMCAxIDQuMTMgNi42NlY0N2gzNS4wMmE2LjEgNi4xIDAgMCAwIDQuODctMy4wM2wuNDMtLjg0Yy44LTEuNTkuNC00LS44NS01LjI0bC0yLjM2LTIuMzZBMTIgMTIgMCAwIDEgMTc5IDI4YTEzIDEzIDAgMCAxIDEzLTEzek04NC4wMiAxNDNhNi4xIDYuMSAwIDAgMCA0Ljg3LTMuMDNsLjQzLS44NGMuOC0xLjU5LjQtNC0uODUtNS4yNGwtMi4zNi0yLjM2QTEyIDEyIDAgMCAxIDgzIDEyNGExMyAxMyAwIDEgMSAyNiAwYzAgMi40Ny0xLjM3IDUuNzktMy4xMSA3LjUzbC0yLjM2IDIuMzZhNC45NCA0Ljk0IDAgMCAwLS44NSA1LjI0bC40My44NGE2LjEgNi4xIDAgMCAwIDQuODcgMy4wM0gxNDN2LTM1LjAyYTguMDggOC4wOCAwIDAgMSA0LjEzLTYuNjZsLjg0LS40M2E2LjkxIDYuOTEgMCAwIDEgNy41NiAxLjIybDIuMzYgMi4zNkExMC4wNiAxMC4wNiAwIDAgMCAxNjQgMTA3YTExIDExIDAgMCAwIDAtMjJjLTEuOTQgMC00Ljc1IDEuMTYtNi4xMSAyLjUzbC0yLjM2IDIuMzZhNi45MyA2LjkzIDAgMCAxLTcuNTYgMS4yMmwtLjg0LS40M2E4LjA4IDguMDggMCAwIDEtNC4xMy02LjY2VjQ5aC0zNS4wMmE2LjEgNi4xIDAgMCAwLTQuODcgMy4wM2wtLjQzLjg0Yy0uNzkgMS41OC0uNCA0IC44NSA1LjI0bDIuMzYgMi4zNmExMi4wNCAxMi4wNCAwIDAgMSAzLjExIDcuNTFBMTMgMTMgMCAxIDEgODMgNjhhMTIgMTIgMCAwIDEgMy4xMS03LjUzbDIuMzYtMi4zNmE0LjkzIDQuOTMgMCAwIDAgLjg1LTUuMjRsLS40My0uODRBNi4xIDYuMSAwIDAgMCA4NC4wMiA0OUg0OXYzNS4wMmE4LjA4IDguMDggMCAwIDEtNC4xMyA2LjY2bC0uODQuNDNhNi45MSA2LjkxIDAgMCAxLTcuNTYtMS4yMmwtMi4zNi0yLjM2QTEwLjA2IDEwLjA2IDAgMCAwIDI4IDg1YTExIDExIDAgMCAwIDAgMjJjMS45NCAwIDQuNzUtMS4xNiA2LjExLTIuNTNsMi4zNi0yLjM2YTYuOTMgNi45MyAwIDAgMSA3LjU2LTEuMjJsLjg0LjQzYTguMDggOC4wOCAwIDAgMSA0LjEzIDYuNjZWMTQzaDM1LjAyeic+PC9wYXRoPjwvc3ZnPg==);
+}
+
+.dark-mode {
+ --text-color: #eee;
+ --background-color: #333;
+ --background-color-rgb: 51, 51, 51;
+ --shadow-color: rgba(255, 255, 255, 0.2);
+ --border-color: rgb(131 131 131 / 50%);
+ --surface-color: rgba(51, 51, 51, 0.9);
+ --surface-solid: #292927;
+ --surface-muted: rgba(255, 255, 255, 0.055);
+ --text-muted: #b3b3ad;
+ --success-color: #58a86b;
+ --danger-color: #ff7168;
+ --warning-color: #e4ac4f;
+ --focus-ring: rgba(255, 204, 0, 0.26);
+ --background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxOTInIGhlaWdodD0nMTkyJyB2aWV3Qm94PScwIDAgMTkyIDE5Mic+PHBhdGggZmlsbD0nIzVhNWE1YScgZmlsbC1vcGFjaXR5PScwLjUnIGQ9J00xOTIgMTV2MmExMSAxMSAwIDAgMC0xMSAxMWMwIDEuOTQgMS4xNiA0Ljc1IDIuNTMgNi4xMWwyLjM2IDIuMzZhNi45MyA2LjkzIDAgMCAxIDEuMjIgNy41NmwtLjQzLjg0YTguMDggOC4wOCAwIDAgMS02LjY2IDQuMTNIMTQ1djM1LjAyYTYuMSA2LjEgMCAwIDAgMy4wMyA0Ljg3bC44NC40M2MxLjU4Ljc5IDQgLjQgNS4yNC0uODVsMi4zNi0yLjM2YTEyLjA0IDEyLjA0IDAgMCAxIDcuNTEtMy4xMSAxMyAxMyAwIDEgMSAuMDIgMjYgMTIgMTIgMCAwIDEtNy41My0zLjExbC0yLjM2LTIuMzZhNC45MyA0LjkzIDAgMCAwLTUuMjQtLjg1bC0uODQuNDNhNi4xIDYuMSAwIDAgMC0zLjAzIDQuODdWMTQzaDM1LjAyYTguMDggOC4wOCAwIDAgMSA2LjY2IDQuMTNsLjQzLjg0YTYuOTEgNi45MSAwIDAgMS0xLjIyIDcuNTZsLTIuMzYgMi4zNkExMC4wNiAxMC4wNiAwIDAgMCAxODEgMTY0YTExIDExIDAgMCAwIDExIDExdjJhMTMgMTMgMCAwIDEtMTMtMTMgMTIgMTIgMCAwIDEgMy4xMS03LjUzbDIuMzYtMi4zNmE0LjkzIDQuOTMgMCAwIDAgLjg1LTUuMjRsLS40My0uODRhNi4xIDYuMSAwIDAgMC00Ljg3LTMuMDNIMTQ1djM1LjAyYTguMDggOC4wOCAwIDAgMS00LjEzIDYuNjZsLS44NC40M2E2LjkxIDYuOTEgMCAwIDEtNy41Ni0xLjIybC0yLjM2LTIuMzZBMTAuMDYgMTAuMDYgMCAwIDAgMTI0IDE4MWExMSAxMSAwIDAgMC0xMSAxMWgtMmExMyAxMyAwIDAgMSAxMy0xM2MyLjQ3IDAgNS43OSAxLjM3IDcuNTMgMy4xMWwyLjM2IDIuMzZhNC45NCA0Ljk0IDAgMCAwIDUuMjQuODVsLjg0LS40M2E2LjEgNi4xIDAgMCAwIDMuMDMtNC44N1YxNDVoLTM1LjAyYTguMDggOC4wOCAwIDAgMS02LjY2LTQuMTNsLS40My0uODRhNi45MSA2LjkxIDAgMCAxIDEuMjItNy41NmwyLjM2LTIuMzZBMTAuMDYgMTAuMDYgMCAwIDAgMTA3IDEyNGExMSAxMSAwIDAgMC0yMiAwYzAgMS45NCAxLjE2IDQuNzUgMi41MyA2LjExbDIuMzYgMi4zNmE2LjkzIDYuOTMgMCAwIDEgMS4yMiA3LjU2bC0uNDMuODRhOC4wOCA4LjA4IDAgMCAxLTYuNjYgNC4xM0g0OXYzNS4wMmE2LjEgNi4xIDAgMCAwIDMuMDMgNC44N2wuODQuNDNjMS41OC43OSA0IC40IDUuMjQtLjg1bDIuMzYtMi4zNmExMi4wNCAxMi4wNCAwIDAgMSA3LjUxLTMuMTFBMTMgMTMgMCAwIDEgODEgMTkyaC0yYTExIDExIDAgMCAwLTExLTExYy0xLjk0IDAtNC43NSAxLjE2LTYuMTEgMi41M2wtMi4zNiAyLjM2YTYuOTMgNi45MyAwIDAgMS03LjU2IDEuMjJsLS44NC0uNDNhOC4wOCA4LjA4IDAgMCAxLTQuMTMtNi42NlYxNDVIMTEuOThhNi4xIDYuMSAwIDAgMC00Ljg3IDMuMDNsLS40My44NGMtLjc5IDEuNTgtLjQgNCAuODUgNS4yNGwyLjM2IDIuMzZhMTIuMDQgMTIuMDQgMCAwIDEgMy4xMSA3LjUxQTEzIDEzIDAgMCAxIDAgMTc3di0yYTExIDExIDAgMCAwIDExLTExYzAtMS45NC0xLjE2LTQuNzUtMi41My02LjExbC0yLjM2LTIuMzZhNi45MyA2LjkzIDAgMCAxLTEuMjItNy41NmwuNDMtLjg0YTguMDggOC4wOCAwIDAgMSA2LjY2LTQuMTNINDd2LTM1LjAyYTYuMSA2LjEgMCAwIDAtMy4wMy00Ljg3bC0uODQtLjQzYy0xLjU5LS44LTQtLjQtNS4yNC44NWwtMi4zNiAyLjM2QTEyIDEyIDAgMCAxIDI4IDEwOWExMyAxMyAwIDEgMSAwLTI2YzIuNDcgMCA1Ljc5IDEuMzcgNy41MyAzLjExbDIuMzYgMi4zNmE0Ljk0IDQuOTQgMCAwIDAgNS4yNC44NWwuODQtLjQzQTYuMSA2LjEgMCAwIDAgNDcgODQuMDJWNDlIMTEuOThhOC4wOCA4LjA4IDAgMCAxLTYuNjYtNC4xM2wtLjQzLS44NGE2LjkxIDYuOTEgMCAwIDEgMS4yMi03LjU2bDIuMzYtMi4zNkExMC4wNiAxMC4wNiAwIDAgMCAxMSAyOCAxMSAxMSAwIDAgMCAwIDE3di0yYTEzIDEzIDAgMCAxIDEzIDEzYzAgMi40Ny0xLjM3IDUuNzktMy4xMSA3LjUzbC0yLjM2IDIuMzZhNC45NCA0Ljk0IDAgMCAwLS44NSA1LjI0bC40My44NEE2LjEgNi4xIDAgMCAwIDExLjk4IDQ3SDQ3VjExLjk4YTguMDggOC4wOCAwIDAgMSA0LjEzLTYuNjZsLjg0LS40M2E2LjkxIDYuOTEgMCAwIDEgNy41NiAxLjIybDIuMzYgMi4zNkExMC4wNiAxMC4wNiAwIDAgMCA2OCAxMSAxMSAxMSAwIDAgMCA3OSAwaDJhMTMgMTMgMCAwIDEtMTMgMTMgMTIgMTIgMCAwIDEtNy41My0zLjExbC0yLjM2LTIuMzZhNC45MyA0LjkzIDAgMCAwLTUuMjQtLjg1bC0uODQuNDNBNi4xIDYuMSAwIDAgMCA0OSAxMS45OFY0N2gzNS4wMmE4LjA4IDguMDggMCAwIDEgNi42NiA0LjEzbC40My44NGE2LjkxIDYuOTEgMCAwIDEtMS4yMiA3LjU2bC0yLjM2IDIuMzZBMTAuMDYgMTAuMDYgMCAwIDAgODUgNjhhMTEgMTEgMCAwIDAgMjIgMGMwLTEuOTQtMS4xNi00Ljc1LTIuNTMtNi4xMWwtMi4zNi0yLjM2YTYuOTMgNi45MyAwIDAgMS0xLjIyLTcuNTZsLjQzLS44NGE4LjA4IDguMDggMCAwIDEgNi42Ni00LjEzSDE0M1YxMS45OGE2LjEgNi4xIDAgMCAwLTMuMDMtNC44N2wtLjg0LS40M2MtMS41OS0uOC00LS40LTUuMjQuODVsLTIuMzYgMi4zNkExMiAxMiAwIDAgMSAxMjQgMTNhMTMgMTMgMCAwIDEtMTMtMTNoMmExMSAxMSAwIDAgMCAxMSAxMWMxLjk0IDAgNC43NS0xLjE2IDYuMTEtMi41M2wyLjM2LTIuMzZhNi45MyA2LjkzIDAgMCAxIDcuNTYtMS4yMmwuODQuNDNhOC4wOCA4LjA4IDAgMCAxIDQuMTMgNi42NlY0N2gzNS4wMmE2LjEgNi4xIDAgMCAwIDQuODctMy4wM2wuNDMtLjg0Yy44LTEuNTkuNC00LS44NS01LjI0bC0yLjM2LTIuMzZBMTIgMTIgMCAwIDEgMTc5IDI4YTEzIDEzIDAgMCAxIDEzLTEzek04NC4wMiAxNDNhNi4xIDYuMSAwIDAgMCA0Ljg3LTMuMDNsLjQzLS44NGMuOC0xLjU5LjQtNC0uODUtNS4yNGwtMi4zNi0yLjM2QTEyIDEyIDAgMCAxIDgzIDEyNGExMyAxMyAwIDEgMSAyNiAwYzAgMi40Ny0xLjM3IDUuNzktMy4xMSA3LjUzbC0yLjM2IDIuMzZhNC45NCA0Ljk0IDAgMCAwLS44NSA1LjI0bC40My44NGE2LjEgNi4xIDAgMCAwIDQuODcgMy4wM0gxNDN2LTM1LjAyYTguMDggOC4wOCAwIDAgMSA0LjEzLTYuNjZsLjg0LS40M2E2LjkxIDYuOTEgMCAwIDEgNy41NiAxLjIybDIuMzYgMi4zNkExMC4wNiAxMC4wNiAwIDAgMCAxNjQgMTA3YTExIDExIDAgMCAwIDAtMjJjLTEuOTQgMC00Ljc1IDEuMTYtNi4xMSAyLjUzbC0yLjM2IDIuMzZhNi45MyA2LjkzIDAgMCAxLTcuNTYgMS4yMmwtLjg0LS40M2E4LjA4IDguMDggMCAwIDEtNC4xMy02LjY2VjQ5aC0zNS4wMmE2LjEgNi4xIDAgMCAwLTQuODcgMy4wM2wtLjQzLjg0Yy0uNzkgMS41OC0uNCA0IC44NSA1LjI0bDIuMzYgMi4zNmExMi4wNCAxMi4wNCAwIDAgMSAzLjExIDcuNTFBMTMgMTMgMCAxIDEgODMgNjhhMTIgMTIgMCAwIDEgMy4xMS03LjUzbDIuMzYtMi4zNmE0LjkzIDQuOTMgMCAwIDAgLjg1LTUuMjRsLS40My0uODRBNi4xIDYuMSAwIDAgMCA4NC4wMiA0OUg0OXYzNS4wMmE4LjA4IDguMDggMCAwIDEtNC4xMyA2LjY2bC0uODQuNDNhNi45MSA2LjkxIDAgMCAxLTcuNTYtMS4yMmwtMi4zNi0yLjM2QTEwLjA2IDEwLjA2IDAgMCAwIDI4IDg1YTExIDExIDAgMCAwIDAgMjJjMS45NCAwIDQuNzUtMS4xNiA2LjExLTIuNTNsMi4zNi0yLjM2YTYuOTMgNi45MyAwIDAgMSA3LjU2LTEuMjJsLjg0LjQzYTguMDggOC4wOCAwIDAgMSA0LjEzIDYuNjZWMTQzaDM1LjAyeic+PC9wYXRoPjwvc3ZnPg==);
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html,
+body,
+#app {
+ min-height: 100%;
+ margin: 0;
+}
+
+body {
+ min-width: 320px;
+ font-family: 'HarmonyOS_Regular', 'MiSans', 'HarmonyOS Sans SC', system-ui, sans-serif;
+ color: var(--text-color);
+ background: var(--background-color);
+ transition: color 0.2s ease, background-color 0.2s ease;
+}
+
+button,
+input,
+textarea,
+select {
+ font: inherit;
+}
+
+button,
+a {
+ -webkit-tap-highlight-color: transparent;
+}
+
+button {
+ letter-spacing: 0;
+}
+
+a {
+ color: inherit;
+ text-decoration: none;
+}
+
+button:focus-visible,
+a:focus-visible,
+input:focus-visible,
+textarea:focus-visible,
+select:focus-visible {
+ outline: 3px solid var(--focus-ring);
+ outline-offset: 2px;
+}
+
+ul {
+ padding: 0;
+ margin: 0;
+ list-style: none;
+}
+
+.public-shell {
+ position: relative;
+ min-height: 100vh;
+ min-height: 100dvh;
+ display: flex;
+ flex-direction: column;
+ padding: 0 14px;
+ overflow-x: hidden;
+}
+
+.background {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100vw;
+ height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: -1;
+ background: var(--background-color) var(--background-image) repeat;
+}
+
+.site-footer {
+ padding: 12px 0 16px;
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ align-items: center;
+ margin-top: auto;
+ font-size: 14px;
+ gap: 6px 12px;
+ color: var(--text-muted);
+ text-align: center;
+
+ a {
+ color: inherit;
+ transition: color 0.2s ease;
+ &:hover {
+ color: var(--hover-link-color);
+ }
+ }
+}
+
+.police-link {
+ display: flex;
+ align-items: center;
+ gap: 5px;
+}
+
+@media screen and (max-width: 768px) {
+ .public-shell {
+ padding: 0 10px;
+ }
+
+ .site-footer {
+ font-size: 12px;
+ padding-bottom: 10px;
+ }
+}
+
+@media (prefers-reduced-motion: reduce) {
+ *,
+ *::before,
+ *::after {
+ scroll-behavior: auto !important;
+ animation-duration: 0.01ms !important;
+ animation-iteration-count: 1 !important;
+ transition-duration: 0.01ms !important;
+ }
+}