Refactor styles to utilize Tailwind CSS utility classes for improved consistency and maintainability across forms, motion, shell, and vault components. Remove deprecated reduced-motion styles and consolidate motion-related animations. Update color tokens for better contrast and accessibility. Introduce a new Tailwind CSS configuration file.

This commit is contained in:
shuaiplus
2026-04-24 15:14:12 +08:00
parent 033d44808f
commit d40b0514fd
18 changed files with 1490 additions and 943 deletions
+949 -13
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -40,6 +40,9 @@
"@cloudflare/workers-types": "^4.20260131.0", "@cloudflare/workers-types": "^4.20260131.0",
"@preact/preset-vite": "^2.10.3", "@preact/preset-vite": "^2.10.3",
"@types/node": "^25.2.3", "@types/node": "^25.2.3",
"autoprefixer": "^10.4.21",
"postcss": "^8.5.6",
"tailwindcss": "^3.4.17",
"tsx": "^4.21.0", "tsx": "^4.21.0",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"vite": "^7.3.1", "vite": "^7.3.1",
+6
View File
@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
+33
View File
@@ -0,0 +1,33 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./webapp/index.html', './webapp/src/**/*.{ts,tsx}'],
darkMode: ['class', '[data-theme="dark"]'],
theme: {
extend: {
colors: {
canvas: 'var(--bg-accent)',
panel: 'var(--panel)',
'panel-soft': 'var(--panel-soft)',
'panel-muted': 'var(--panel-muted)',
line: 'var(--line)',
'line-soft': 'var(--line-soft)',
ink: 'var(--text)',
muted: 'var(--muted)',
'muted-strong': 'var(--muted-strong)',
brand: 'var(--primary)',
'brand-hover': 'var(--primary-hover)',
'brand-strong': 'var(--primary-strong)',
danger: 'var(--danger)',
},
boxShadow: {
soft: 'var(--shadow-sm)',
panel: 'var(--shadow-md)',
elevated: 'var(--shadow-lg)',
},
fontFamily: {
sans: ['Segoe UI', 'PingFang SC', 'Microsoft YaHei', 'Noto Sans SC', 'sans-serif'],
},
},
},
plugins: [],
};
-44
View File
@@ -82,48 +82,6 @@ const SIGNALR_UPDATE_TYPE_DEVICE_STATUS = 12;
const SIGNALR_UPDATE_TYPE_BACKUP_RESTORE_PROGRESS = 13; const SIGNALR_UPDATE_TYPE_BACKUP_RESTORE_PROGRESS = 13;
type ThemePreference = 'system' | 'light' | 'dark'; type ThemePreference = 'system' | 'light' | 'dark';
const MAGNETIC_SELECTOR = '.topbar .btn, .topbar .user-chip, .side-link, .mobile-tab';
function installMagneticUiFeedback() {
if (typeof window === 'undefined' || typeof document === 'undefined') return () => {};
if (typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return () => {};
if (typeof window.matchMedia === 'function' && window.matchMedia('(pointer: coarse)').matches) return () => {};
const resetNode = (node: HTMLElement) => {
node.style.setProperty('--mag-x', '0px');
node.style.setProperty('--mag-y', '0px');
node.style.removeProperty('--mx');
node.style.removeProperty('--my');
};
const onPointerMove = (event: PointerEvent) => {
const node = event.target instanceof Element ? event.target.closest<HTMLElement>(MAGNETIC_SELECTOR) : null;
if (!node) return;
const rect = node.getBoundingClientRect();
const localX = event.clientX - rect.left;
const localY = event.clientY - rect.top;
const dx = (localX - rect.width / 2) / Math.max(rect.width / 2, 1);
const dy = (localY - rect.height / 2) / Math.max(rect.height / 2, 1);
node.style.setProperty('--mx', `${localX}px`);
node.style.setProperty('--my', `${localY}px`);
node.style.setProperty('--mag-x', `${dx * 6}px`);
node.style.setProperty('--mag-y', `${dy * 4}px`);
};
const onPointerLeave = (event: Event) => {
const node = event.target instanceof Element ? event.target.closest<HTMLElement>(MAGNETIC_SELECTOR) : null;
if (!node) return;
resetNode(node);
};
document.addEventListener('pointermove', onPointerMove, { passive: true });
document.addEventListener('pointerleave', onPointerLeave, true);
return () => {
document.removeEventListener('pointermove', onPointerMove);
document.removeEventListener('pointerleave', onPointerLeave, true);
};
}
function readThemePreference(): ThemePreference { function readThemePreference(): ThemePreference {
if (typeof window === 'undefined') return 'system'; if (typeof window === 'undefined') return 'system';
@@ -292,8 +250,6 @@ export default function App() {
} }
}, [phase, profile, session]); }, [phase, profile, session]);
useEffect(() => installMagneticUiFeedback(), []);
function handleToggleTheme() { function handleToggleTheme() {
setThemePreference((prev) => { setThemePreference((prev) => {
const current = prev === 'system' ? systemTheme : prev; const current = prev === 'system' ? systemTheme : prev;
+1
View File
@@ -1,6 +1,7 @@
import { render } from 'preact'; import { render } from 'preact';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import App from './App'; import App from './App';
import './tailwind.css';
import './styles.css'; import './styles.css';
const queryClient = new QueryClient({ const queryClient = new QueryClient({
+262 -1
View File
@@ -9,4 +9,265 @@
@import './styles/motion.css'; @import './styles/motion.css';
@import './styles/responsive.css'; @import './styles/responsive.css';
@import './styles/dark.css'; @import './styles/dark.css';
@import './styles/reduced-motion.css';
/* Unified product polish: clean, flat, quiet surfaces across desktop, mobile, and dark mode. */
.app-shell,
.auth-card,
.dialog-card,
.card,
.list-panel,
.sidebar-block,
.settings-subcard,
.backup-operations-sidebar,
.backup-destination-sidebar,
.backup-detail-panel,
.restore-progress-card,
.backup-recommendation-card,
.backup-destination-item,
.backup-browser-list,
.backup-browser-path,
.totp-code-row,
.mobile-settings-link,
.table tr {
border-color: var(--line);
border-radius: var(--radius-lg);
background: var(--panel);
box-shadow: var(--shadow-sm);
}
.app-shell {
background: var(--panel-soft);
border-radius: var(--radius-xl);
box-shadow: var(--shadow-lg);
}
.topbar,
.mobile-tabbar,
.app-side {
background: var(--panel-soft);
border-color: var(--line-soft);
}
.brand-logo,
.brand-wordmark,
.standalone-brand-logo,
.standalone-brand-wordmark {
filter: none;
}
.btn,
.input,
.search-input,
.side-link,
.mobile-tab,
.tree-btn,
.list-item,
.dialog-card,
.mobile-sidebar-sheet,
.mobile-detail-sheet,
.create-menu,
.sort-menu,
.toast-item {
transition-duration: 150ms;
}
.btn:hover:not(:disabled),
.side-link:hover,
.mobile-tab:hover,
.tree-btn:hover,
.list-item:hover,
.create-menu-item:hover,
.sort-menu-item:hover,
.folder-delete-btn:hover,
.eye-btn:hover,
.password-toggle:hover {
transform: none;
}
.btn-primary {
background: var(--primary);
border-color: transparent;
color: #ffffff;
box-shadow: none;
}
.btn-primary:hover {
background: var(--primary-hover);
box-shadow: none;
}
.btn-secondary,
.btn-danger {
box-shadow: none;
}
.btn-secondary:hover,
.side-link:hover,
.mobile-tab:hover,
.tree-btn:hover,
.list-item:hover,
.backup-destination-item:hover,
.mobile-settings-link:hover {
background: var(--panel-subtle);
}
.side-link.active,
.mobile-tab.active,
.tree-btn.active,
.list-item.active,
.sort-menu-item.active,
.backup-destination-item.active,
.backup-interval-preset.active,
.mobile-settings-link.active {
background: color-mix(in srgb, var(--primary) 12%, var(--panel));
border-color: color-mix(in srgb, var(--primary) 32%, var(--line));
color: var(--primary-strong);
box-shadow: none;
}
.list-item::before,
.topbar-actions .btn::before,
.user-chip::before,
.side-link::before,
.mobile-tab::before {
display: none;
}
.stagger-item {
opacity: 1;
animation: none;
}
.dialog-mask {
background: rgba(15, 23, 42, 0.42);
backdrop-filter: none;
-webkit-backdrop-filter: none;
}
.dialog-mask.warning {
background: rgba(15, 23, 42, 0.56);
}
.dialog-card.warning,
:root[data-theme='dark'] .dialog-card.warning {
background: var(--panel);
border-color: color-mix(in srgb, var(--danger) 28%, var(--line));
box-shadow: var(--shadow-lg);
}
.dialog-warning-badge {
border-radius: var(--radius-lg);
background: color-mix(in srgb, var(--danger) 12%, var(--panel));
color: var(--danger);
box-shadow: none;
}
.dialog-warning-kicker {
letter-spacing: 0;
text-transform: none;
}
.dialog-message.warning,
:root[data-theme='dark'] .dialog-message.warning {
background: color-mix(in srgb, var(--danger) 8%, var(--panel));
border-color: color-mix(in srgb, var(--danger) 20%, var(--line));
box-shadow: none;
color: var(--text);
}
.mobile-sidebar-sheet,
.mobile-detail-sheet {
transform: none;
box-shadow: var(--shadow-md);
}
.mobile-sidebar-sheet.open,
.mobile-detail-sheet.open {
transform: none;
}
.mobile-fab-trigger {
box-shadow: var(--shadow-md);
}
.theme-switch-slider,
.theme-switch-input:checked + .theme-switch-slider,
:root[data-theme='dark'] .theme-switch-slider {
background: var(--panel-muted);
border-color: var(--line);
}
.theme-switch-slider::before,
:root[data-theme='dark'] .theme-switch-slider::before {
background: var(--panel);
box-shadow: var(--shadow-sm);
}
:root[data-theme='dark'] .app-shell,
:root[data-theme='dark'] .auth-card,
:root[data-theme='dark'] .dialog-card,
:root[data-theme='dark'] .card,
:root[data-theme='dark'] .list-panel,
:root[data-theme='dark'] .sidebar-block,
:root[data-theme='dark'] .settings-subcard,
:root[data-theme='dark'] .backup-operations-sidebar,
:root[data-theme='dark'] .backup-destination-sidebar,
:root[data-theme='dark'] .backup-detail-panel,
:root[data-theme='dark'] .backup-recommendation-card,
:root[data-theme='dark'] .backup-recommendation-dav-item,
:root[data-theme='dark'] .backup-destination-item,
:root[data-theme='dark'] .backup-browser-list,
:root[data-theme='dark'] .backup-browser-path,
:root[data-theme='dark'] .totp-code-row,
:root[data-theme='dark'] .mobile-settings-link,
:root[data-theme='dark'] .table tr,
:root[data-theme='dark'] .list-item,
:root[data-theme='dark'] .input,
:root[data-theme='dark'] .search-input,
:root[data-theme='dark'] .create-menu,
:root[data-theme='dark'] .create-menu-item,
:root[data-theme='dark'] .sort-menu,
:root[data-theme='dark'] .sort-menu-item {
background: var(--panel);
border-color: var(--line);
color: var(--text);
box-shadow: var(--shadow-sm);
}
:root[data-theme='dark'] .topbar,
:root[data-theme='dark'] .mobile-tabbar,
:root[data-theme='dark'] .app-side {
background: var(--panel-soft);
}
:root[data-theme='dark'] .btn-secondary {
background: var(--panel);
border-color: var(--line);
color: var(--primary);
box-shadow: none;
}
:root[data-theme='dark'] .btn-primary {
background: var(--primary);
border-color: transparent;
color: #08111f;
box-shadow: none;
}
:root[data-theme='dark'] .btn-danger {
background: var(--panel);
border-color: color-mix(in srgb, var(--danger) 36%, var(--line));
color: var(--danger);
box-shadow: none;
}
:root[data-theme='dark'] .list-item:hover,
:root[data-theme='dark'] .sort-menu-item:hover,
:root[data-theme='dark'] .create-menu-item:hover,
:root[data-theme='dark'] .mobile-settings-link:hover,
:root[data-theme='dark'] .backup-destination-item:hover,
:root[data-theme='dark'] .side-link:hover,
:root[data-theme='dark'] .mobile-tab:hover,
:root[data-theme='dark'] .tree-btn:hover {
background: var(--panel-subtle);
}
+12 -51
View File
@@ -1,19 +1,9 @@
.loading-screen { .loading-screen {
height: 100%; @apply grid h-full place-items-center text-lg text-muted;
display: grid;
place-items: center;
color: var(--muted);
font-size: 18px;
animation: fade-in-up var(--dur-panel) var(--ease-out-strong) both;
} }
.auth-page { .auth-page {
min-height: 100%; @apply relative grid min-h-full place-items-center bg-transparent p-6;
display: grid;
place-items: center;
padding: 24px;
position: relative;
background: transparent;
} }
.public-send-page { .public-send-page {
@@ -23,16 +13,9 @@
} }
.auth-card { .auth-card {
width: 100%; @apply relative w-full overflow-hidden border bg-panel p-[30px] shadow-elevated;
position: relative; border-color: var(--line);
background: var(--panel); border-radius: 22px;
border: 1px solid var(--line);
border-radius: 24px;
box-shadow: var(--shadow-lg);
padding: 30px;
overflow: hidden;
transform-origin: 50% 24%;
animation: surface-enter 520ms var(--ease-out-strong) both;
} }
.auth-card h1 { .auth-card h1 {
@@ -41,17 +24,12 @@
} }
.standalone-shell { .standalone-shell {
@apply grid gap-3.5;
width: min(640px, 100%); width: min(640px, 100%);
display: grid;
gap: 14px;
animation: fade-in-up 420ms var(--ease-out-strong) both;
} }
.standalone-brand { .standalone-brand {
display: inline-flex; @apply mb-3 inline-flex items-center gap-3.5;
align-items: center;
gap: 14px;
margin-bottom: 12px;
} }
.standalone-brand-outside { .standalone-brand-outside {
@@ -61,10 +39,7 @@
} }
.standalone-brand-logo { .standalone-brand-logo {
width: 56px; @apply h-14 w-14 flex-shrink-0 object-contain;
height: 56px;
object-fit: contain;
flex-shrink: 0;
filter: drop-shadow(0 8px 18px rgba(43, 102, 217, 0.22)); filter: drop-shadow(0 8px 18px rgba(43, 102, 217, 0.22));
} }
@@ -77,11 +52,7 @@
} }
.standalone-title { .standalone-title {
margin: 0 0 4px 0; @apply m-0 mb-1 text-left text-3xl font-bold leading-tight tracking-normal;
text-align: left;
font-size: 31px;
line-height: 1.15;
letter-spacing: -0.035em;
} }
.standalone-muted { .standalone-muted {
@@ -99,10 +70,7 @@
} }
.jwt-warning-box { .jwt-warning-box {
border: 1px solid #f1d8a5; @apply rounded-xl border border-amber-200 bg-amber-50 px-3.5 py-3;
border-radius: 12px;
background: #fffaf0;
padding: 12px 14px;
} }
.jwt-warning-label { .jwt-warning-label {
@@ -157,11 +125,7 @@
} }
.jwt-generator-actions { .jwt-generator-actions {
margin-top: 10px; @apply mt-2.5 flex flex-wrap items-center gap-2.5;
display: flex;
align-items: center;
gap: 10px;
flex-wrap: wrap;
} }
.jwt-copy-hint { .jwt-copy-hint {
@@ -171,10 +135,7 @@
} }
.standalone-footer { .standalone-footer {
width: 100%; @apply w-full text-center text-[13px] text-slate-500;
text-align: center;
font-size: 13px;
color: #64748b;
} }
.standalone-footer a { .standalone-footer a {
+5 -8
View File
@@ -1,5 +1,5 @@
* { * {
box-sizing: border-box; @apply box-border;
} }
html, html,
@@ -7,21 +7,18 @@ body,
#root { #root {
margin: 0; margin: 0;
padding: 0; padding: 0;
width: 100%; @apply h-full w-full;
height: 100%;
color: var(--text); color: var(--text);
background: var(--bg-accent); background: var(--bg-accent);
font-family: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', 'Noto Sans SC', sans-serif; font-family: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', 'Noto Sans SC', sans-serif;
} }
body { body {
position: relative; @apply relative antialiased;
transition: transition: background-color var(--dur-medium) var(--ease-smooth), color var(--dur-medium) var(--ease-smooth);
background-color var(--dur-medium) var(--ease-smooth),
color var(--dur-medium) var(--ease-smooth);
} }
body.dialog-open { body.dialog-open {
overflow: hidden; @apply overflow-hidden;
overscroll-behavior: contain; overscroll-behavior: contain;
} }
+75 -381
View File
@@ -2,85 +2,14 @@
:root[data-theme='dark'] #root, :root[data-theme='dark'] #root,
:root[data-theme='dark'] .app-page, :root[data-theme='dark'] .app-page,
:root[data-theme='dark'] .auth-page { :root[data-theme='dark'] .auth-page {
background: transparent; background: var(--bg-accent);
color: var(--text); color: var(--text);
} }
:root[data-theme='dark'] .app-shell, :root[data-theme='dark'] h1,
:root[data-theme='dark'] .auth-card, :root[data-theme='dark'] h2,
:root[data-theme='dark'] .dialog, :root[data-theme='dark'] h3,
:root[data-theme='dark'] .jwt-warning-box, :root[data-theme='dark'] h4,
:root[data-theme='dark'] .backup-operations-sidebar,
:root[data-theme='dark'] .backup-destination-sidebar,
:root[data-theme='dark'] .backup-detail-panel,
:root[data-theme='dark'] .settings-subcard,
:root[data-theme='dark'] .list-panel,
:root[data-theme='dark'] .card,
:root[data-theme='dark'] .sidebar-block,
:root[data-theme='dark'] .empty {
background: var(--panel);
border-color: var(--line);
color: var(--text);
box-shadow: var(--shadow-lg);
}
:root[data-theme='dark'] .topbar,
:root[data-theme='dark'] .mobile-tabbar,
:root[data-theme='dark'] .sort-menu,
:root[data-theme='dark'] .create-menu,
:root[data-theme='dark'] .dialog-card,
:root[data-theme='dark'] .mobile-sidebar-sheet,
:root[data-theme='dark'] .mobile-detail-sheet {
background: var(--panel-soft);
border-color: var(--line);
color: var(--text);
}
:root[data-theme='dark'] .dialog-card.warning {
border-color: rgba(248, 113, 113, 0.36);
background: linear-gradient(180deg, rgba(39, 16, 16, 0.98), rgba(27, 12, 12, 0.98));
box-shadow:
0 36px 90px rgba(5, 5, 5, 0.56),
0 0 0 1px rgba(248, 113, 113, 0.12) inset;
}
:root[data-theme='dark'] .dialog-mask.warning {
background:
radial-gradient(circle at top, rgba(127, 29, 29, 0.28), transparent 34%),
linear-gradient(180deg, rgba(20, 12, 12, 0.64), rgba(2, 6, 23, 0.82));
}
:root[data-theme='dark'] .dialog-warning-badge {
background: linear-gradient(180deg, rgba(127, 29, 29, 0.8), rgba(69, 10, 10, 0.86));
color: #fda4af;
box-shadow:
0 12px 30px rgba(0, 0, 0, 0.32),
0 0 0 1px rgba(248, 113, 113, 0.14) inset;
}
:root[data-theme='dark'] .dialog-warning-kicker,
:root[data-theme='dark'] .dialog-card.warning .dialog-title {
color: #fecaca;
}
:root[data-theme='dark'] .dialog-message.warning {
border-color: rgba(248, 113, 113, 0.18);
background: linear-gradient(180deg, rgba(69, 10, 10, 0.54), rgba(67, 20, 7, 0.46));
color: #fecdd3;
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.18) inset;
}
:root[data-theme='dark'] .app-side,
:root[data-theme='dark'] .sidebar,
:root[data-theme='dark'] .mobile-sidebar-sheet .sidebar-block {
background: var(--panel-muted);
border-color: var(--line);
}
:root[data-theme='dark'] .auth-card {
background: var(--panel);
}
:root[data-theme='dark'] .brand, :root[data-theme='dark'] .brand,
:root[data-theme='dark'] .mobile-page-title, :root[data-theme='dark'] .mobile-page-title,
:root[data-theme='dark'] .detail-title, :root[data-theme='dark'] .detail-title,
@@ -89,277 +18,6 @@
:root[data-theme='dark'] .kv-main strong, :root[data-theme='dark'] .kv-main strong,
:root[data-theme='dark'] .list-title, :root[data-theme='dark'] .list-title,
:root[data-theme='dark'] .sidebar-title, :root[data-theme='dark'] .sidebar-title,
:root[data-theme='dark'] h1,
:root[data-theme='dark'] h2,
:root[data-theme='dark'] h3,
:root[data-theme='dark'] h4 {
color: var(--text);
}
:root[data-theme='dark'] .standalone-brand-wordmark,
:root[data-theme='dark'] .brand-wordmark {
text-shadow: 0 16px 28px rgba(2, 6, 23, 0.32);
}
:root[data-theme='dark'] .muted,
:root[data-theme='dark'] .detail-sub,
:root[data-theme='dark'] .field-help,
:root[data-theme='dark'] .list-sub,
:root[data-theme='dark'] .kv-label,
:root[data-theme='dark'] .standalone-muted,
:root[data-theme='dark'] .standalone-footer,
:root[data-theme='dark'] .backup-inline-note,
:root[data-theme='dark'] .backup-browser-empty,
:root[data-theme='dark'] .or,
:root[data-theme='dark'] .mobile-tab,
:root[data-theme='dark'] .side-link,
:root[data-theme='dark'] .user-chip,
:root[data-theme='dark'] .list-count {
color: var(--muted);
}
:root[data-theme='dark'] .user-chip {
background: rgba(17, 34, 56, 0.94);
border-color: var(--line);
box-shadow: 0 12px 24px rgba(1, 7, 18, 0.24);
}
:root[data-theme='dark'] .side-link:hover,
:root[data-theme='dark'] .mobile-tab:hover {
background: rgba(132, 182, 255, 0.11);
}
:root[data-theme='dark'] .side-link.active,
:root[data-theme='dark'] .mobile-tab.active,
:root[data-theme='dark'] .sort-menu-item.active,
:root[data-theme='dark'] .list-item.active {
background: linear-gradient(135deg, rgba(132, 182, 255, 0.2), rgba(56, 189, 248, 0.08));
border-color: rgba(132, 182, 255, 0.28);
color: var(--primary);
}
:root[data-theme='dark'] .input,
:root[data-theme='dark'] .textarea,
:root[data-theme='dark'] select.input,
:root[data-theme='dark'] .dialog input,
:root[data-theme='dark'] .dialog textarea,
:root[data-theme='dark'] .dialog select {
background: rgba(13, 24, 40, 0.94);
border-color: rgba(103, 136, 186, 0.36);
color: var(--text);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03);
}
:root[data-theme='dark'] .input::placeholder,
:root[data-theme='dark'] .textarea::placeholder,
:root[data-theme='dark'] input::placeholder,
:root[data-theme='dark'] textarea::placeholder {
color: #7488a8;
}
:root[data-theme='dark'] .input:focus,
:root[data-theme='dark'] .textarea:focus,
:root[data-theme='dark'] .search-input:focus,
:root[data-theme='dark'] .dialog input:focus,
:root[data-theme='dark'] .dialog textarea:focus,
:root[data-theme='dark'] .dialog select:focus {
border-color: rgba(132, 182, 255, 0.54);
background-color: rgba(16, 30, 49, 0.98);
box-shadow: 0 0 0 4px rgba(132, 182, 255, 0.12), 0 10px 22px rgba(5, 13, 28, 0.24), inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
:root[data-theme='dark'] .input-readonly {
background: #0f1b2d;
color: var(--muted-strong);
}
:root[data-theme='dark'] .input:disabled,
:root[data-theme='dark'] .btn:disabled {
background: #132033;
border-color: #22334c;
color: #70829d;
}
:root[data-theme='dark'] .btn-secondary {
background: linear-gradient(180deg, rgba(22, 41, 66, 0.98), rgba(16, 31, 52, 0.98));
border-color: rgba(132, 182, 255, 0.22);
color: #a9cdff;
box-shadow: 0 12px 22px rgba(1, 7, 18, 0.18);
}
:root[data-theme='dark'] .btn-secondary:hover {
background: linear-gradient(180deg, rgba(26, 49, 79, 0.98), rgba(19, 37, 61, 0.98));
border-color: rgba(132, 182, 255, 0.3);
}
:root[data-theme='dark'] .btn-danger {
background: linear-gradient(180deg, rgba(45, 23, 33, 0.98), rgba(35, 18, 28, 0.98));
border-color: rgba(255, 139, 168, 0.38);
color: #ff9bb0;
}
:root[data-theme='dark'] .btn-danger:hover {
background: linear-gradient(180deg, rgba(56, 27, 40, 0.98), rgba(41, 19, 31, 0.98));
border-color: rgba(255, 171, 192, 0.42);
}
:root[data-theme='dark'] .btn-primary {
background: linear-gradient(135deg, #79acff, #57c2ff 76%);
border-color: rgba(176, 214, 255, 0.22);
color: #061120;
box-shadow: 0 18px 32px rgba(10, 26, 52, 0.34);
}
:root[data-theme='dark'] .btn-primary:hover {
background: linear-gradient(135deg, #90bcff, #6accff 76%);
box-shadow: 0 22px 36px rgba(10, 26, 52, 0.38);
}
:root[data-theme='dark'] .toolbar.actions,
:root[data-theme='dark'] .list-head,
:root[data-theme='dark'] .mobile-panel-head,
:root[data-theme='dark'] .backup-recommendation-header,
:root[data-theme='dark'] .backup-operations-sidebar,
:root[data-theme='dark'] .backup-destination-sidebar,
:root[data-theme='dark'] .backup-detail-panel,
:root[data-theme='dark'] .detail-actions,
:root[data-theme='dark'] .topbar,
:root[data-theme='dark'] .app-side,
:root[data-theme='dark'] .kv-row,
:root[data-theme='dark'] .attachment-row,
:root[data-theme='dark'] .backup-browser-row {
border-color: var(--line);
}
:root[data-theme='dark'] .input,
:root[data-theme='dark'] .search-input,
:root[data-theme='dark'] .list-item,
:root[data-theme='dark'] .sidebar-block {
background: rgba(15, 28, 45, 0.94);
}
:root[data-theme='dark'] .sidebar,
:root[data-theme='dark'] .content,
:root[data-theme='dark'] .list-col,
:root[data-theme='dark'] .detail-col {
color: var(--text);
}
:root[data-theme='dark'] .mobile-sidebar-mask,
:root[data-theme='dark'] .dialog-mask {
background: var(--overlay-strong);
}
:root[data-theme='dark'] .toast {
background: linear-gradient(180deg, rgba(19, 34, 54, 0.98), rgba(14, 26, 42, 0.98));
border-color: #263a57;
color: var(--text);
}
:root[data-theme='dark'] .toast.success {
background: #0f2a1f;
border-color: #1f5b44;
color: #9be2bd;
}
:root[data-theme='dark'] .toast.error {
background: #2a1720;
border-color: #6c2b41;
color: #ffb1c0;
}
:root[data-theme='dark'] .toast.warning {
background: #2d2413;
border-color: #7b6230;
color: #f7d48b;
}
:root[data-theme='dark'] .jwt-warning-head,
:root[data-theme='dark'] .jwt-warning-label,
:root[data-theme='dark'] .jwt-warning-copy,
:root[data-theme='dark'] .jwt-warning-list {
color: #f4d48a;
}
:root[data-theme='dark'] .theme-switch-input:focus + .theme-switch-slider {
box-shadow: 0 0 0 2px rgba(132, 182, 255, 0.24);
}
:root[data-theme='dark'] .search-input,
:root[data-theme='dark'] .list-head .search-input,
:root[data-theme='dark'] .mobile-settings-card,
:root[data-theme='dark'] .mobile-settings-link,
:root[data-theme='dark'] .table tr,
:root[data-theme='dark'] .settings-subcard,
:root[data-theme='dark'] .backup-operations-sidebar,
:root[data-theme='dark'] .backup-destination-sidebar,
:root[data-theme='dark'] .backup-detail-panel,
:root[data-theme='dark'] .dialog-card,
:root[data-theme='dark'] .backup-browser-path,
:root[data-theme='dark'] .backup-browser-list,
:root[data-theme='dark'] .create-menu,
:root[data-theme='dark'] .create-menu-item,
:root[data-theme='dark'] .sort-menu,
:root[data-theme='dark'] .sort-menu-item,
:root[data-theme='dark'] .backup-recommendation-card,
:root[data-theme='dark'] .backup-recommendation-dav-item,
:root[data-theme='dark'] .backup-destination-item,
:root[data-theme='dark'] .totp-code-row,
:root[data-theme='dark'] .list-item {
background:
linear-gradient(180deg, rgba(18, 32, 52, 0.92), rgba(14, 26, 42, 0.92));
border-color: var(--line);
color: var(--text);
}
:root[data-theme='dark'] .list-item:hover,
:root[data-theme='dark'] .sort-menu-item:hover,
:root[data-theme='dark'] .create-menu-item:hover,
:root[data-theme='dark'] .mobile-settings-link:hover,
:root[data-theme='dark'] .backup-destination-item:hover {
background:
linear-gradient(180deg, rgba(24, 44, 70, 0.96), rgba(16, 31, 51, 0.96));
border-color: rgba(118, 150, 197, 0.32);
}
:root[data-theme='dark'] .list-item.active {
background: linear-gradient(135deg, rgba(132, 182, 255, 0.2), rgba(56, 189, 248, 0.1));
border-color: rgba(122, 176, 255, 0.34);
box-shadow: inset 0 0 0 1px rgba(200, 225, 255, 0.06), 0 12px 24px rgba(5, 13, 28, 0.18);
}
:root[data-theme='dark'] .list-item::before {
background:
linear-gradient(90deg, rgba(132, 182, 255, 0.08), transparent 24%, transparent 76%, rgba(56, 189, 248, 0.08)),
radial-gradient(circle at 18px 50%, rgba(255, 255, 255, 0.06), transparent 44%);
}
:root[data-theme='dark'] .backup-destination-item.active,
:root[data-theme='dark'] .backup-interval-preset.active,
:root[data-theme='dark'] .mobile-settings-link.active,
:root[data-theme='dark'] .tree-btn.active {
background: linear-gradient(135deg, rgba(132, 182, 255, 0.2), rgba(56, 189, 248, 0.1));
border-color: rgba(132, 182, 255, 0.34);
color: #f4f8ff;
}
:root[data-theme='dark'] .theme-switch-slider {
background: linear-gradient(180deg, #1d3659, #142845);
border-color: rgba(120, 152, 198, 0.34);
}
:root[data-theme='dark'] .theme-switch-slider::before {
background: linear-gradient(180deg, #f8fbff, #dce9ff);
box-shadow: 0 3px 10px rgba(2, 8, 20, 0.28);
}
:root[data-theme='dark'] .theme-switch .moon svg {
fill: #8db6ff;
}
:root[data-theme='dark'] .theme-switch .sun svg {
opacity: 0.82;
}
:root[data-theme='dark'] .totp-code-name, :root[data-theme='dark'] .totp-code-name,
:root[data-theme='dark'] .backup-destination-name, :root[data-theme='dark'] .backup-destination-name,
:root[data-theme='dark'] .backup-browser-entry, :root[data-theme='dark'] .backup-browser-entry,
@@ -376,6 +34,20 @@
color: var(--text); color: var(--text);
} }
:root[data-theme='dark'] .muted,
:root[data-theme='dark'] .detail-sub,
:root[data-theme='dark'] .field-help,
:root[data-theme='dark'] .list-sub,
:root[data-theme='dark'] .kv-label,
:root[data-theme='dark'] .standalone-muted,
:root[data-theme='dark'] .standalone-footer,
:root[data-theme='dark'] .backup-inline-note,
:root[data-theme='dark'] .backup-browser-empty,
:root[data-theme='dark'] .or,
:root[data-theme='dark'] .mobile-tab,
:root[data-theme='dark'] .side-link,
:root[data-theme='dark'] .user-chip,
:root[data-theme='dark'] .list-count,
:root[data-theme='dark'] .totp-code-username, :root[data-theme='dark'] .totp-code-username,
:root[data-theme='dark'] .backup-destination-meta, :root[data-theme='dark'] .backup-destination-meta,
:root[data-theme='dark'] .backup-browser-meta, :root[data-theme='dark'] .backup-browser-meta,
@@ -385,67 +57,89 @@
:root[data-theme='dark'] .backup-recommendation-linked-item, :root[data-theme='dark'] .backup-recommendation-linked-item,
:root[data-theme='dark'] .backup-inline-suffix, :root[data-theme='dark'] .backup-inline-suffix,
:root[data-theme='dark'] .folder-delete-btn, :root[data-theme='dark'] .folder-delete-btn,
:root[data-theme='dark'] .folder-add-btn:hover, :root[data-theme='dark'] .tree-label {
:root[data-theme='dark'] .tree-label,
:root[data-theme='dark'] .list-sub {
color: var(--muted); color: var(--muted);
} }
:root[data-theme='dark'] .import-export-panel p, :root[data-theme='dark'] .input,
:root[data-theme='dark'] .dialog-message, :root[data-theme='dark'] .textarea,
:root[data-theme='dark'] .local-error, :root[data-theme='dark'] select.input,
:root[data-theme='dark'] .status-ok { :root[data-theme='dark'] .search-input,
color: var(--muted); :root[data-theme='dark'] .dialog input,
:root[data-theme='dark'] .dialog textarea,
:root[data-theme='dark'] .dialog select {
background: var(--panel);
border-color: var(--line);
color: var(--text);
box-shadow: none;
} }
:root[data-theme='dark'] .backup-destination-type { :root[data-theme='dark'] .input::placeholder,
background: #1d3048; :root[data-theme='dark'] .textarea::placeholder,
color: #c9d8eb; :root[data-theme='dark'] input::placeholder,
:root[data-theme='dark'] textarea::placeholder {
color: color-mix(in srgb, var(--muted) 76%, transparent);
} }
:root[data-theme='dark'] .backup-help-trigger { :root[data-theme='dark'] .input:focus,
border-color: #38618f; :root[data-theme='dark'] .textarea:focus,
background: #173150; :root[data-theme='dark'] .search-input:focus,
color: #9ec5ff; :root[data-theme='dark'] .dialog input:focus,
:root[data-theme='dark'] .dialog textarea:focus,
:root[data-theme='dark'] .dialog select:focus {
border-color: color-mix(in srgb, var(--primary) 54%, var(--line));
background: var(--panel);
box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 16%, transparent);
} }
:root[data-theme='dark'] .backup-help-trigger:hover, :root[data-theme='dark'] .input-readonly {
:root[data-theme='dark'] .backup-help-trigger:focus-visible { background: var(--panel-muted);
border-color: #5f92d7; color: var(--muted-strong);
background: #20426a;
} }
:root[data-theme='dark'] .backup-help-bubble { :root[data-theme='dark'] .input:disabled,
:root[data-theme='dark'] .btn:disabled {
background: var(--panel-muted);
border-color: var(--line-soft);
color: color-mix(in srgb, var(--muted) 62%, transparent);
}
:root[data-theme='dark'] .mobile-sidebar-mask,
:root[data-theme='dark'] .dialog-mask {
background: var(--overlay-strong);
}
:root[data-theme='dark'] .toast-item {
background: var(--panel); background: var(--panel);
border-color: var(--line); border-color: var(--line);
color: var(--text); color: var(--text);
} }
:root[data-theme='dark'] .backup-help-bubble::before { :root[data-theme='dark'] .toast-item.error,
background: var(--panel); :root[data-theme='dark'] .toast-item.warning {
border-left-color: var(--line); border-color: color-mix(in srgb, var(--danger) 36%, var(--line));
border-top-color: var(--line); background: color-mix(in srgb, var(--danger) 12%, var(--panel));
color: var(--text);
} }
:root[data-theme='dark'] .table td { :root[data-theme='dark'] .jwt-warning-head,
border-bottom-color: #203047; :root[data-theme='dark'] .jwt-warning-label,
:root[data-theme='dark'] .jwt-warning-copy,
:root[data-theme='dark'] .jwt-warning-list {
color: var(--warning);
} }
:root[data-theme='dark'] .local-error { :root[data-theme='dark'] .local-error {
color: #ff9bb0; color: var(--danger);
} }
:root[data-theme='dark'] .status-ok { :root[data-theme='dark'] .status-ok {
color: #9be2bd; color: var(--success);
}
:root[data-theme='dark'] .totp-qr {
background: #ffffff;
border-color: rgba(15, 23, 42, 0.12);
} }
:root[data-theme='dark'] .totp-qr,
:root[data-theme='dark'] .totp-qr svg, :root[data-theme='dark'] .totp-qr svg,
:root[data-theme='dark'] .totp-qr img { :root[data-theme='dark'] .totp-qr img {
background: #ffffff; background: #ffffff;
border-radius: 8px; border-color: rgba(15, 23, 42, 0.12);
} }
+34 -132
View File
@@ -1,38 +1,20 @@
.muted { .muted {
margin: 0 0 16px 0; @apply m-0 mb-4 text-center leading-relaxed text-muted;
text-align: center;
color: var(--muted);
line-height: 1.65;
} }
.field { .field {
display: block; @apply mb-3.5 block;
margin-bottom: 14px;
} }
.field > span { .field > span {
display: block; @apply mb-2 block text-sm font-semibold;
margin-bottom: 8px;
font-size: 14px;
font-weight: 600;
} }
.input { .input {
width: 100%; @apply h-12 w-full rounded-xl border px-3.5 py-2.5 text-base text-ink outline-none transition;
height: 48px;
border: 1px solid rgba(74, 103, 150, 0.42);
border-radius: 14px;
padding: 10px 14px;
font-size: 16px;
outline: none;
color: var(--text);
background: var(--panel); background: var(--panel);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9); border-color: rgba(74, 103, 150, 0.34);
transition: box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.82);
border-color var(--dur-fast) var(--ease-smooth),
box-shadow var(--dur-fast) var(--ease-out-soft),
background-color var(--dur-fast) var(--ease-smooth),
transform var(--dur-fast) var(--ease-out-soft);
} }
select.input { select.input {
@@ -59,15 +41,10 @@ input[type='file'].input {
} }
input[type='file'].input::file-selector-button { input[type='file'].input::file-selector-button {
height: 32px; @apply mr-2.5 h-8 cursor-pointer rounded-full border px-3 font-bold;
border: 1px solid #3f5b9e;
border-radius: 999px;
padding: 0 12px;
background: #eef4ff; background: #eef4ff;
border-color: #9db8ea;
color: #1f4ea0; color: #1f4ea0;
font-weight: 700;
cursor: pointer;
margin-right: 10px;
} }
input[type='file'].input::file-selector-button:hover { input[type='file'].input::file-selector-button:hover {
@@ -76,32 +53,25 @@ input[type='file'].input::file-selector-button:hover {
} }
.textarea { .textarea {
min-height: 110px; @apply h-auto min-h-28 resize-y;
height: auto;
resize: vertical;
} }
.input:focus { .input:focus {
border-color: rgba(43, 102, 217, 0.6); border-color: rgba(43, 102, 217, 0.6);
background-color: #fbfdff; background-color: #fbfdff;
box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.11), 0 10px 20px rgba(37, 99, 235, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.95); box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.10), 0 8px 18px rgba(37, 99, 235, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.95);
transform: translateY(-1px);
} }
.input-readonly { .input-readonly {
background: #eef2f7; @apply bg-slate-100 text-slate-600;
color: #475569;
} }
.input:disabled { .input:disabled {
background: #e2e8f0; @apply cursor-not-allowed border-slate-300 bg-slate-200 text-slate-400;
border-color: #cbd5e1;
color: #94a3b8;
cursor: not-allowed;
} }
.password-wrap { .password-wrap {
position: relative; @apply relative;
} }
.password-wrap .input { .password-wrap .input {
@@ -109,32 +79,12 @@ input[type='file'].input::file-selector-button:hover {
} }
.password-toggle { .password-toggle {
position: absolute; @apply absolute right-2 top-1/2 grid cursor-pointer place-items-center border-0 bg-transparent text-blue-700 transition;
right: 8px;
top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
border: none;
background: transparent;
color: #275ac2;
cursor: pointer;
display: grid;
place-items: center;
transition: color var(--dur-fast) var(--ease-smooth), transform var(--dur-fast) var(--ease-out-soft);
} }
.eye-btn { .eye-btn {
position: absolute; @apply absolute bottom-2.5 right-2.5 grid h-8 w-8 cursor-pointer place-items-center border-0 bg-transparent text-slate-700 transition;
right: 10px;
bottom: 9px;
width: 30px;
height: 30px;
border: none;
background: transparent;
cursor: pointer;
display: grid;
place-items: center;
color: #334155;
transition: color var(--dur-fast) var(--ease-smooth), transform var(--dur-fast) var(--ease-out-soft);
} }
.password-toggle:hover, .password-toggle:hover,
@@ -144,33 +94,13 @@ input[type='file'].input::file-selector-button:hover {
} }
.btn { .btn {
height: 36px; @apply inline-flex h-9 cursor-pointer items-center justify-center gap-1.5 rounded-full border border-transparent px-4 text-[15px] font-bold no-underline transition;
border: 1px solid transparent;
border-radius: 999px;
padding: 0 16px;
font-size: 15px;
font-weight: 700;
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
text-decoration: none;
transition:
transform var(--dur-fast) var(--ease-out-soft),
box-shadow var(--dur-fast) var(--ease-out-soft),
background-color var(--dur-fast) var(--ease-smooth),
border-color var(--dur-fast) var(--ease-smooth),
color var(--dur-fast) var(--ease-smooth),
opacity var(--dur-fast) var(--ease-smooth);
} }
.topbar-actions .btn, .topbar-actions .btn,
.user-chip, .user-chip,
.side-link, .side-link,
.mobile-tab { .mobile-tab {
--mag-x: 0px;
--mag-y: 0px;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
} }
@@ -181,8 +111,8 @@ input[type='file'].input::file-selector-button:hover {
.mobile-tab::before { .mobile-tab::before {
content: ''; content: '';
position: absolute; position: absolute;
left: var(--mx, 50%); left: 50%;
top: var(--my, 50%); top: 50%;
width: 110px; width: 110px;
height: 110px; height: 110px;
border-radius: 999px; border-radius: 999px;
@@ -199,12 +129,11 @@ input[type='file'].input::file-selector-button:hover {
.user-chip:hover::before, .user-chip:hover::before,
.side-link:hover::before, .side-link:hover::before,
.mobile-tab:hover::before { .mobile-tab:hover::before {
opacity: 1; opacity: 0;
transform: translate(-50%, -50%) scale(1);
} }
.btn:hover:not(:disabled) { .btn:hover:not(:disabled) {
transform: translateY(-2px) scale(1.01); transform: translateY(-1px);
} }
.btn:active:not(:disabled) { .btn:active:not(:disabled) {
@@ -216,30 +145,23 @@ input[type='file'].input::file-selector-button:hover {
} }
.btn.full { .btn.full {
width: 100%; @apply my-2.5 h-12 w-full text-lg;
height: 50px;
font-size: 22px;
margin: 10px 0;
} }
.btn-primary { .btn-primary {
background: linear-gradient(135deg, #2563eb, #3b82f6 72%); @apply border-blue-700/30 bg-blue-600 text-white;
border-color: rgba(15, 63, 152, 0.32); box-shadow: 0 10px 22px rgba(37, 99, 235, 0.20);
color: #fff;
box-shadow: 0 14px 28px rgba(37, 99, 235, 0.24);
} }
.btn-primary:hover { .btn-primary:hover {
background: linear-gradient(135deg, #1d4ed8, #3377f0 72%); @apply bg-blue-700;
border-color: rgba(15, 63, 152, 0.38); box-shadow: 0 12px 26px rgba(37, 99, 235, 0.22);
box-shadow: 0 18px 34px rgba(37, 99, 235, 0.28);
} }
.btn-secondary { .btn-secondary {
background: var(--panel); @apply bg-panel text-brand-strong;
border-color: rgba(37, 99, 235, 0.22); border-color: rgba(37, 99, 235, 0.20);
color: var(--primary-strong); box-shadow: 0 6px 14px rgba(13, 31, 68, 0.04);
box-shadow: 0 8px 18px rgba(13, 31, 68, 0.05);
} }
.btn-secondary:hover { .btn-secondary:hover {
@@ -248,9 +170,8 @@ input[type='file'].input::file-selector-button:hover {
} }
.btn-danger { .btn-danger {
background: rgba(255, 255, 255, 0.8); @apply bg-white/80 text-danger;
border-color: rgba(217, 45, 87, 0.28); border-color: rgba(217, 45, 87, 0.28);
color: var(--danger);
} }
.btn-danger:hover { .btn-danger:hover {
@@ -259,42 +180,23 @@ input[type='file'].input::file-selector-button:hover {
} }
.btn:disabled { .btn:disabled {
background: #e2e8f0; @apply cursor-not-allowed border-slate-300 bg-slate-200 text-slate-400;
border-color: #cbd5e1;
color: #94a3b8;
cursor: not-allowed;
} }
.or { .or {
text-align: center; @apply my-2.5 text-center text-slate-700;
margin: 10px 0;
color: #334155;
} }
.field-help { .field-help {
margin-top: 8px; @apply mt-2 text-[13px] leading-normal text-slate-500;
font-size: 13px;
line-height: 1.5;
color: #667085;
} }
.auth-support-row { .auth-support-row {
display: flex; @apply -mt-0.5 mb-3 flex items-center justify-between gap-2.5;
align-items: center;
justify-content: space-between;
gap: 10px;
margin: -2px 0 12px;
} }
.auth-link-btn { .auth-link-btn {
border: none; @apply cursor-pointer border-0 bg-transparent p-0 text-[13px] font-bold text-blue-700 transition;
background: transparent;
padding: 0;
color: #1d4ed8;
font-size: 13px;
font-weight: 700;
cursor: pointer;
transition: color var(--dur-fast) var(--ease-smooth), transform var(--dur-fast) var(--ease-out-soft), opacity var(--dur-fast) var(--ease-smooth);
} }
.auth-link-btn:hover { .auth-link-btn:hover {
+11 -18
View File
@@ -21,77 +21,63 @@
@keyframes fade-in-up { @keyframes fade-in-up {
from { from {
opacity: 0; opacity: 0;
transform: translate3d(0, 16px, 0);
} }
to { to {
opacity: 1; opacity: 1;
transform: translate3d(0, 0, 0);
} }
} }
@keyframes shell-enter { @keyframes shell-enter {
from { from {
opacity: 0; opacity: 0;
transform: translate3d(0, 18px, 0) scale(0.992);
} }
to { to {
opacity: 1; opacity: 1;
transform: translate3d(0, 0, 0) scale(1);
} }
} }
@keyframes surface-enter { @keyframes surface-enter {
from { from {
opacity: 0; opacity: 0;
transform: translate3d(0, 20px, 0) scale(0.985);
} }
to { to {
opacity: 1; opacity: 1;
transform: translate3d(0, 0, 0) scale(1);
} }
} }
@keyframes menu-in { @keyframes menu-in {
from { from {
opacity: 0; opacity: 0;
transform: translate3d(0, 10px, 0) scale(0.96);
} }
to { to {
opacity: 1; opacity: 1;
transform: translate3d(0, 0, 0) scale(1);
} }
} }
@keyframes dialog-in { @keyframes dialog-in {
from { from {
opacity: 0; opacity: 0;
transform: translate3d(0, 18px, 0) scale(0.96);
} }
to { to {
opacity: 1; opacity: 1;
transform: translate3d(0, 0, 0) scale(1);
} }
} }
@keyframes toast-in { @keyframes toast-in {
from { from {
opacity: 0; opacity: 0;
transform: translate3d(18px, 0, 0) scale(0.97);
} }
to { to {
opacity: 1; opacity: 1;
transform: translate3d(0, 0, 0) scale(1);
} }
} }
@keyframes stagger-rise { @keyframes stagger-rise {
from { from {
opacity: 0; opacity: 0;
transform: translate3d(0, 18px, 0) scale(0.985);
} }
to { to {
opacity: 1; opacity: 1;
transform: translate3d(0, 0, 0) scale(1);
} }
} }
@@ -107,21 +93,28 @@
@keyframes dialog-out { @keyframes dialog-out {
from { from {
opacity: 1; opacity: 1;
transform: translate3d(0, 0, 0) scale(1);
} }
to { to {
opacity: 0; opacity: 0;
transform: translate3d(0, 10px, 0) scale(0.972);
} }
} }
@keyframes route-stage-in { @keyframes route-stage-in {
from { from {
opacity: 0; opacity: 0;
transform: translate3d(0, 14px, 0);
} }
to { to {
opacity: 1; opacity: 1;
transform: translate3d(0, 0, 0); }
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 1ms !important;
animation-iteration-count: 1 !important;
scroll-behavior: auto !important;
transition-duration: 1ms !important;
} }
} }
-32
View File
@@ -1,32 +0,0 @@
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
*,
*::before,
*::after {
animation-duration: 1ms !important;
animation-iteration-count: 1 !important;
transition-duration: 1ms !important;
scroll-behavior: auto !important;
}
.btn:hover:not(:disabled),
.btn:active:not(:disabled),
.side-link:hover,
.tree-btn:hover,
.list-item:hover,
.list-item.active,
.search-input:focus,
.input:focus,
.password-toggle:hover,
.eye-btn:hover,
.auth-link-btn:hover,
.sort-menu-item:hover,
.create-menu-item:hover,
.toast-close:hover,
.mobile-sidebar-close:hover {
transform: none !important;
}
}
+1 -1
View File
@@ -213,7 +213,7 @@
} }
.mobile-tab:hover { .mobile-tab:hover {
transform: translate3d(var(--mag-x), calc(var(--mag-y) - 1px), 0); transform: translateY(-1px);
} }
.mobile-tab.active { .mobile-tab.active {
+32 -127
View File
@@ -1,44 +1,22 @@
.app-page { .app-page {
min-height: 100%; @apply relative min-h-full bg-transparent p-5;
padding: 20px;
position: relative;
background: transparent;
} }
.app-shell { .app-shell {
@apply relative mx-auto flex max-w-[1600px] flex-col overflow-hidden border bg-panel-soft shadow-elevated;
height: calc(100vh - 40px); height: calc(100vh - 40px);
max-width: 1600px; border-color: var(--line);
margin: 0 auto; border-radius: 24px;
position: relative;
background: var(--panel-soft);
border: 1px solid var(--line);
border-radius: 28px;
box-shadow: var(--shadow-lg);
display: flex;
flex-direction: column;
overflow: hidden;
animation: shell-enter 560ms var(--ease-out-strong) both;
} }
.topbar { .topbar {
height: 58px; @apply flex h-[58px] items-center justify-between border-b px-[18px] text-slate-900 transition;
border-bottom: 1px solid var(--line-soft); border-color: var(--line-soft);
color: #0f172a; background: rgba(244, 248, 255, 0.82);
background: rgba(244, 248, 255, 0.72);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 18px;
transition: background-color var(--dur-fast) var(--ease-smooth), border-color var(--dur-fast) var(--ease-smooth);
} }
.brand { .brand {
display: inline-flex; @apply inline-flex items-center gap-2 text-[34px] font-extrabold text-ink;
align-items: center;
gap: 8px;
font-size: 34px;
font-weight: 800;
color: var(--text);
} }
.brand-wordmark { .brand-wordmark {
@@ -50,30 +28,17 @@
} }
.mobile-page-title { .mobile-page-title {
display: none; @apply hidden min-w-0 overflow-hidden text-ellipsis whitespace-nowrap text-[19px] font-extrabold leading-tight text-slate-900;
min-width: 0;
max-width: min(58vw, 240px); max-width: min(58vw, 240px);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 19px;
line-height: 1.2;
font-weight: 800;
color: #0f172a;
} }
.brand-logo { .brand-logo {
width: 42px; @apply h-[42px] w-[42px] object-contain;
height: 42px;
object-fit: contain;
filter: drop-shadow(0 10px 22px rgba(43, 102, 217, 0.22)); filter: drop-shadow(0 10px 22px rgba(43, 102, 217, 0.22));
transition: transform var(--dur-medium) var(--ease-out-soft), filter var(--dur-medium) var(--ease-out-soft);
} }
.topbar-actions { .topbar-actions {
display: flex; @apply flex items-center gap-2.5;
align-items: center;
gap: 10px;
} }
.mobile-tabbar { .mobile-tabbar {
@@ -93,9 +58,7 @@
} }
.theme-switch-wrap { .theme-switch-wrap {
display: inline-flex; @apply inline-flex items-center justify-center;
align-items: center;
justify-content: center;
} }
.theme-switch { .theme-switch {
@@ -112,20 +75,9 @@
} }
.theme-switch-slider { .theme-switch-slider {
position: absolute; @apply absolute inset-0 cursor-pointer rounded-full border transition;
cursor: pointer; background: #dbeafe;
top: 0; border-color: #9dbbec;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(180deg, #dceaff, #c8dcff);
border: 1px solid #9dbbec;
transition:
background var(--dur-medium) var(--ease-out-soft),
border-color var(--dur-medium) var(--ease-smooth),
box-shadow var(--dur-fast) var(--ease-out-soft),
transform var(--dur-fast) var(--ease-out-soft);
border-radius: 999px;
} }
.theme-switch-slider::before { .theme-switch-slider::before {
@@ -182,7 +134,7 @@
} }
.theme-switch:hover .theme-switch-slider { .theme-switch:hover .theme-switch-slider {
transform: scale(1.02); transform: none;
} }
.theme-switch:hover .sun svg, .theme-switch:hover .sun svg,
@@ -196,105 +148,58 @@
padding: 0 12px; padding: 0 12px;
font-size: 13px; font-size: 13px;
font-weight: 600; font-weight: 600;
transform: translate3d(var(--mag-x), var(--mag-y), 0);
transition-duration: 220ms; transition-duration: 220ms;
} }
.topbar-actions .btn:hover:not(:disabled) { .topbar-actions .btn:hover:not(:disabled) {
transform: translate3d(var(--mag-x), calc(var(--mag-y) - 2px), 0) scale(1.02); transform: translateY(-1px);
} }
.user-chip { .user-chip {
display: inline-flex; @apply inline-flex h-[34px] items-center gap-1.5 rounded-full border px-3 text-sm font-semibold text-muted-strong transition;
align-items: center; background: rgba(249, 251, 255, 0.94);
gap: 6px; border-color: rgba(148, 163, 184, 0.30);
height: 34px; box-shadow: 0 8px 16px rgba(13, 31, 68, 0.04);
border-radius: 999px;
padding: 0 12px;
border: 1px solid rgba(148, 163, 184, 0.3);
background: rgba(249, 251, 255, 0.92);
color: var(--muted-strong);
font-size: 14px;
font-weight: 600;
box-shadow: 0 10px 18px rgba(13, 31, 68, 0.05);
transform: translate3d(var(--mag-x), var(--mag-y), 0);
transition:
transform 220ms var(--ease-out-soft),
box-shadow var(--dur-fast) var(--ease-out-soft),
border-color var(--dur-fast) var(--ease-smooth),
background-color var(--dur-fast) var(--ease-smooth);
} }
.user-chip:hover { .user-chip:hover {
transform: translate3d(var(--mag-x), calc(var(--mag-y) - 1px), 0); box-shadow: 0 10px 22px rgba(15, 23, 42, 0.06);
box-shadow: 0 16px 28px rgba(15, 23, 42, 0.08);
} }
.app-main { .app-main {
flex: 1; @apply grid min-h-0 flex-1;
min-height: 0;
display: grid;
grid-template-columns: 200px 1fr; grid-template-columns: 200px 1fr;
} }
.app-side { .app-side {
border-right: 1px solid var(--line-soft); @apply flex flex-col gap-2 border-r px-3 py-4;
padding: 16px 12px; border-color: var(--line-soft);
display: flex;
flex-direction: column;
gap: 8px;
} }
.side-link { .side-link {
display: flex; @apply flex items-center gap-2.5 rounded-xl border border-transparent px-3 py-2.5 text-sm font-semibold text-muted-strong no-underline transition;
align-items: center;
gap: 10px;
padding: 11px 12px;
border-radius: 14px;
color: var(--muted-strong);
text-decoration: none;
border: 1px solid transparent;
font-weight: 600;
font-size: 14px;
transition:
background-color var(--dur-fast) var(--ease-smooth),
border-color var(--dur-fast) var(--ease-smooth),
color var(--dur-fast) var(--ease-smooth),
transform var(--dur-fast) var(--ease-out-soft),
box-shadow var(--dur-fast) var(--ease-out-soft);
} }
.side-link:hover { .side-link:hover {
background: #ffffff; background: #fff;
border-color: rgba(128, 152, 192, 0.18); border-color: rgba(128, 152, 192, 0.18);
color: var(--text); color: var(--text);
transform: translate3d(calc(var(--mag-x) + 3px), var(--mag-y), 0); box-shadow: 0 10px 18px rgba(15, 23, 42, 0.04);
box-shadow: 0 14px 24px rgba(15, 23, 42, 0.05);
} }
.side-link.active { .side-link.active {
background: linear-gradient(135deg, rgba(37, 99, 235, 0.18), rgba(59, 130, 246, 0.08)); background: rgba(37, 99, 235, 0.11);
border-color: rgba(37, 99, 235, 0.28); border-color: rgba(37, 99, 235, 0.28);
color: var(--primary-strong); color: var(--primary-strong);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.64), 0 10px 18px rgba(37, 99, 235, 0.1); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.58);
} }
.content { .content {
min-height: 0; @apply min-h-0 overflow-hidden p-3.5;
padding: 14px;
overflow: hidden;
} }
.route-stage { .route-stage {
height: 100%; @apply h-full min-h-0 overflow-auto;
min-height: 0;
overflow: auto;
}
@media (min-width: 901px) {
.route-stage {
animation: route-stage-in 240ms var(--ease-out-soft) both;
}
} }
.mobile-sidebar-mask { .mobile-sidebar-mask {
+38 -28
View File
@@ -1,21 +1,28 @@
:root { :root {
--bg-accent: #e7edf8; --bg-accent: #eef3fa;
--panel: #f9fbff; --panel: #ffffff;
--panel-soft: #f2f6fd; --panel-soft: #f6f8fc;
--panel-muted: #e8eff9; --panel-muted: #edf2f8;
--line: rgba(128, 152, 192, 0.32); --panel-subtle: #f8fafc;
--line-soft: rgba(143, 167, 206, 0.18); --line: rgba(113, 132, 163, 0.28);
--line-soft: rgba(113, 132, 163, 0.16);
--text: #0b1730; --text: #0b1730;
--muted: #60708b; --muted: #5f6f85;
--muted-strong: #334765; --muted-strong: #2f4058;
--primary: #2563eb; --primary: #2563eb;
--primary-hover: #1d4ed8; --primary-hover: #1d4ed8;
--primary-strong: #0f3f98; --primary-strong: #0f3f98;
--danger: #d92d57; --danger: #d92d57;
--success: #0f766e;
--warning: #b45309;
--overlay-strong: rgba(15, 23, 42, 0.56); --overlay-strong: rgba(15, 23, 42, 0.56);
--shadow-sm: 0 10px 22px rgba(13, 31, 68, 0.045); --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.05);
--shadow-md: 0 22px 48px rgba(13, 31, 68, 0.08); --shadow-md: 0 8px 24px rgba(15, 23, 42, 0.08);
--shadow-lg: 0 28px 76px rgba(13, 31, 68, 0.11); --shadow-lg: 0 14px 38px rgba(15, 23, 42, 0.10);
--radius-sm: 8px;
--radius-md: 10px;
--radius-lg: 14px;
--radius-xl: 18px;
--ease-out-strong: cubic-bezier(0.22, 1, 0.36, 1); --ease-out-strong: cubic-bezier(0.22, 1, 0.36, 1);
--ease-out-soft: cubic-bezier(0.24, 0.8, 0.32, 1); --ease-out-soft: cubic-bezier(0.24, 0.8, 0.32, 1);
--ease-smooth: cubic-bezier(0.4, 0, 0.2, 1); --ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);
@@ -26,21 +33,24 @@
} }
:root[data-theme='dark'] { :root[data-theme='dark'] {
--bg-accent: #06111d; --bg-accent: #0b1020;
--panel: #0d192b; --panel: #111827;
--panel-soft: #112136; --panel-soft: #0f172a;
--panel-muted: #0a1626; --panel-muted: #0b1324;
--line: rgba(108, 141, 190, 0.28); --panel-subtle: #151e2e;
--line-soft: rgba(120, 152, 198, 0.16); --line: rgba(148, 163, 184, 0.20);
--text: #edf4ff; --line-soft: rgba(148, 163, 184, 0.12);
--muted: #8fa6c6; --text: #e5edf8;
--muted-strong: #c3d5ef; --muted: #9aa8bb;
--primary: #84b6ff; --muted-strong: #c7d2e2;
--primary-hover: #a6ccff; --primary: #8bb8ff;
--primary-strong: #f3f8ff; --primary-hover: #a9ccff;
--danger: #ff8ba8; --primary-strong: #dceaff;
--overlay-strong: rgba(2, 8, 20, 0.84); --danger: #fb7185;
--shadow-sm: 0 14px 28px rgba(1, 7, 18, 0.24); --success: #5eead4;
--shadow-md: 0 24px 52px rgba(1, 7, 18, 0.36); --warning: #fbbf24;
--shadow-lg: 0 34px 88px rgba(1, 7, 18, 0.46); --overlay-strong: rgba(2, 6, 23, 0.74);
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.26);
--shadow-md: 0 8px 24px rgba(0, 0, 0, 0.30);
--shadow-lg: 0 14px 38px rgba(0, 0, 0, 0.34);
} }
+25 -107
View File
@@ -1,42 +1,27 @@
.vault-grid { .vault-grid {
display: grid; @apply grid h-full min-h-0 gap-3 p-0.5;
grid-template-columns: 240px minmax(420px, 46%) minmax(575px, 1fr); grid-template-columns: 240px minmax(420px, 46%) minmax(575px, 1fr);
gap: 12px;
height: 100%;
min-height: 0;
padding: 2px;
} }
.sidebar, .sidebar,
.list-panel, .list-panel,
.card { .card {
background: var(--panel); @apply border bg-panel shadow-soft;
border: 1px solid var(--line); border-color: var(--line);
border-radius: 18px; border-radius: 16px;
box-shadow: var(--shadow-sm);
} }
.sidebar { .sidebar {
padding: 0; @apply overflow-auto border-0 bg-transparent p-0 shadow-none;
overflow: auto;
border: none;
box-shadow: none;
background: transparent;
} }
.sidebar-block { .sidebar-block {
border: 1px solid var(--line); @apply mb-2 rounded-2xl border bg-panel p-3;
border-radius: 19px; border-color: var(--line);
padding: 12px;
margin-bottom: 8px;
background: var(--panel);
} }
.sidebar-title { .sidebar-title {
font-size: 13px; @apply mb-2 text-[13px] font-bold text-slate-700;
font-weight: 700;
color: #344054;
margin-bottom: 8px;
} }
.sidebar-title-row { .sidebar-title-row {
@@ -51,21 +36,11 @@
} }
.folder-title-actions { .folder-title-actions {
display: inline-flex; @apply inline-flex items-center gap-2;
align-items: center;
gap: 8px;
} }
.folder-add-btn { .folder-add-btn {
border: none; @apply inline-flex cursor-pointer items-center justify-center border-0 bg-transparent p-0 leading-none text-slate-700;
background: transparent;
color: #334155;
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
padding: 0;
line-height: 1;
} }
.folder-add-btn:hover { .folder-add-btn:hover {
@@ -73,21 +48,10 @@
} }
.search-input { .search-input {
width: 100%; @apply h-12 w-full rounded-xl border px-3.5 py-2.5 text-base text-ink outline-none transition;
height: 48px;
border: 1px solid rgba(74, 103, 150, 0.42);
border-radius: 14px;
padding: 10px 14px;
font-size: 16px;
outline: none;
color: var(--text);
background: var(--panel); background: var(--panel);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9); border-color: rgba(74, 103, 150, 0.34);
transition: box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.82);
border-color var(--dur-fast) var(--ease-smooth),
box-shadow var(--dur-fast) var(--ease-out-soft),
background-color var(--dur-fast) var(--ease-smooth),
transform var(--dur-fast) var(--ease-out-soft);
} }
.search-input-wrap { .search-input-wrap {
@@ -99,8 +63,7 @@
.search-input:focus { .search-input:focus {
border-color: rgba(43, 102, 217, 0.6); border-color: rgba(43, 102, 217, 0.6);
background-color: #fbfdff; background-color: #fbfdff;
box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.11), 0 10px 20px rgba(37, 99, 235, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.95); box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.10), inset 0 1px 0 rgba(255, 255, 255, 0.95);
transform: translateY(-1px);
} }
.search-input-wrap .search-input { .search-input-wrap .search-input {
@@ -137,27 +100,11 @@
} }
.tree-btn { .tree-btn {
width: 100%; @apply mb-1 flex w-full min-w-0 cursor-pointer items-center gap-2 rounded-lg border-0 bg-transparent px-2.5 py-2 text-left transition;
min-width: 0;
border: none;
background: transparent;
text-align: left;
border-radius: 8px;
padding: 8px 10px;
margin-bottom: 4px;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
transition:
background-color var(--dur-fast) var(--ease-smooth),
color var(--dur-fast) var(--ease-smooth),
transform var(--dur-fast) var(--ease-out-soft),
box-shadow var(--dur-fast) var(--ease-out-soft);
} }
.tree-btn:hover { .tree-btn:hover {
transform: translateX(2px); background: rgba(37, 99, 235, 0.05);
} }
.tree-btn.active { .tree-btn.active {
@@ -218,11 +165,7 @@
} }
.list-col { .list-col {
display: flex; @apply flex min-h-0 min-w-0 max-w-[540px] flex-col;
flex-direction: column;
min-width: 0;
min-height: 0;
max-width: 540px;
} }
.toolbar { .toolbar {
@@ -241,10 +184,7 @@
} }
.list-head { .list-head {
display: flex; @apply mb-2 flex items-center gap-2.5;
align-items: center;
gap: 10px;
margin-bottom: 8px;
} }
.list-head .search-input-wrap { .list-head .search-input-wrap {
@@ -343,32 +283,13 @@
} }
.list-panel { .list-panel {
overflow: auto; @apply min-h-0 overflow-auto p-2;
min-height: 0;
padding: 8px;
} }
.list-item { .list-item {
width: 100%; @apply relative mb-2 flex min-h-[66px] w-full cursor-pointer items-center gap-2.5 overflow-hidden rounded-xl border px-3 py-2.5 transition;
background: rgba(249, 251, 255, 0.88); background: rgba(249, 251, 255, 0.9);
border: 1px solid var(--line); border-color: var(--line);
border-radius: 14px;
padding: 10px 12px;
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 8px;
min-height: 66px;
box-sizing: border-box;
position: relative;
cursor: pointer;
overflow: hidden;
transform-origin: 50% 50%;
transition:
background-color var(--dur-fast) var(--ease-smooth),
border-color var(--dur-fast) var(--ease-smooth),
box-shadow var(--dur-fast) var(--ease-out-soft),
transform var(--dur-fast) var(--ease-out-soft);
contain: paint; contain: paint;
} }
@@ -395,8 +316,7 @@
.list-item:hover { .list-item:hover {
background: #fcfdff; background: #fcfdff;
border-color: rgba(148, 163, 184, 0.26); border-color: rgba(148, 163, 184, 0.26);
box-shadow: 0 16px 28px rgba(15, 23, 42, 0.06); box-shadow: 0 10px 22px rgba(15, 23, 42, 0.05);
transform: translate3d(0, -2px, 0) scale(1.008);
} }
.list-item:hover::before { .list-item:hover::before {
@@ -407,8 +327,7 @@
.list-item.active { .list-item.active {
background: rgba(37, 99, 235, 0.1); background: rgba(37, 99, 235, 0.1);
border-color: rgba(43, 102, 217, 0.26); border-color: rgba(43, 102, 217, 0.26);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.42), 0 14px 24px rgba(43, 102, 217, 0.08); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.42);
transform: translate3d(0, -1px, 0) scale(1.004);
} }
.list-item.active::before { .list-item.active::before {
@@ -564,8 +483,7 @@
} }
.card { .card {
padding: 16px 18px; @apply mb-2.5 px-[18px] py-4;
margin-bottom: 10px;
} }
.detail-col > .card { .detail-col > .card {
+3
View File
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;