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
-44
View File
@@ -82,48 +82,6 @@ const SIGNALR_UPDATE_TYPE_DEVICE_STATUS = 12;
const SIGNALR_UPDATE_TYPE_BACKUP_RESTORE_PROGRESS = 13;
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 {
if (typeof window === 'undefined') return 'system';
@@ -292,8 +250,6 @@ export default function App() {
}
}, [phase, profile, session]);
useEffect(() => installMagneticUiFeedback(), []);
function handleToggleTheme() {
setThemePreference((prev) => {
const current = prev === 'system' ? systemTheme : prev;
+1
View File
@@ -1,6 +1,7 @@
import { render } from 'preact';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import App from './App';
import './tailwind.css';
import './styles.css';
const queryClient = new QueryClient({
+262 -1
View File
@@ -9,4 +9,265 @@
@import './styles/motion.css';
@import './styles/responsive.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 {
height: 100%;
display: grid;
place-items: center;
color: var(--muted);
font-size: 18px;
animation: fade-in-up var(--dur-panel) var(--ease-out-strong) both;
@apply grid h-full place-items-center text-lg text-muted;
}
.auth-page {
min-height: 100%;
display: grid;
place-items: center;
padding: 24px;
position: relative;
background: transparent;
@apply relative grid min-h-full place-items-center bg-transparent p-6;
}
.public-send-page {
@@ -23,16 +13,9 @@
}
.auth-card {
width: 100%;
position: relative;
background: var(--panel);
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;
@apply relative w-full overflow-hidden border bg-panel p-[30px] shadow-elevated;
border-color: var(--line);
border-radius: 22px;
}
.auth-card h1 {
@@ -41,17 +24,12 @@
}
.standalone-shell {
@apply grid gap-3.5;
width: min(640px, 100%);
display: grid;
gap: 14px;
animation: fade-in-up 420ms var(--ease-out-strong) both;
}
.standalone-brand {
display: inline-flex;
align-items: center;
gap: 14px;
margin-bottom: 12px;
@apply mb-3 inline-flex items-center gap-3.5;
}
.standalone-brand-outside {
@@ -61,10 +39,7 @@
}
.standalone-brand-logo {
width: 56px;
height: 56px;
object-fit: contain;
flex-shrink: 0;
@apply h-14 w-14 flex-shrink-0 object-contain;
filter: drop-shadow(0 8px 18px rgba(43, 102, 217, 0.22));
}
@@ -77,11 +52,7 @@
}
.standalone-title {
margin: 0 0 4px 0;
text-align: left;
font-size: 31px;
line-height: 1.15;
letter-spacing: -0.035em;
@apply m-0 mb-1 text-left text-3xl font-bold leading-tight tracking-normal;
}
.standalone-muted {
@@ -99,10 +70,7 @@
}
.jwt-warning-box {
border: 1px solid #f1d8a5;
border-radius: 12px;
background: #fffaf0;
padding: 12px 14px;
@apply rounded-xl border border-amber-200 bg-amber-50 px-3.5 py-3;
}
.jwt-warning-label {
@@ -157,11 +125,7 @@
}
.jwt-generator-actions {
margin-top: 10px;
display: flex;
align-items: center;
gap: 10px;
flex-wrap: wrap;
@apply mt-2.5 flex flex-wrap items-center gap-2.5;
}
.jwt-copy-hint {
@@ -171,10 +135,7 @@
}
.standalone-footer {
width: 100%;
text-align: center;
font-size: 13px;
color: #64748b;
@apply w-full text-center text-[13px] text-slate-500;
}
.standalone-footer a {
+5 -8
View File
@@ -1,5 +1,5 @@
* {
box-sizing: border-box;
@apply box-border;
}
html,
@@ -7,21 +7,18 @@ body,
#root {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
@apply h-full w-full;
color: var(--text);
background: var(--bg-accent);
font-family: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', 'Noto Sans SC', sans-serif;
}
body {
position: relative;
transition:
background-color var(--dur-medium) var(--ease-smooth),
color var(--dur-medium) var(--ease-smooth);
@apply relative antialiased;
transition: background-color var(--dur-medium) var(--ease-smooth), color var(--dur-medium) var(--ease-smooth);
}
body.dialog-open {
overflow: hidden;
@apply overflow-hidden;
overscroll-behavior: contain;
}
+75 -381
View File
@@ -2,85 +2,14 @@
:root[data-theme='dark'] #root,
:root[data-theme='dark'] .app-page,
:root[data-theme='dark'] .auth-page {
background: transparent;
background: var(--bg-accent);
color: var(--text);
}
:root[data-theme='dark'] .app-shell,
:root[data-theme='dark'] .auth-card,
:root[data-theme='dark'] .dialog,
:root[data-theme='dark'] .jwt-warning-box,
: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'] h1,
:root[data-theme='dark'] h2,
:root[data-theme='dark'] h3,
:root[data-theme='dark'] h4,
:root[data-theme='dark'] .brand,
:root[data-theme='dark'] .mobile-page-title,
:root[data-theme='dark'] .detail-title,
@@ -89,277 +18,6 @@
:root[data-theme='dark'] .kv-main strong,
:root[data-theme='dark'] .list-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'] .backup-destination-name,
:root[data-theme='dark'] .backup-browser-entry,
@@ -376,6 +34,20 @@
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'] .backup-destination-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-inline-suffix,
: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'] .list-sub {
:root[data-theme='dark'] .tree-label {
color: var(--muted);
}
:root[data-theme='dark'] .import-export-panel p,
:root[data-theme='dark'] .dialog-message,
:root[data-theme='dark'] .local-error,
:root[data-theme='dark'] .status-ok {
color: var(--muted);
:root[data-theme='dark'] .input,
:root[data-theme='dark'] .textarea,
:root[data-theme='dark'] select.input,
:root[data-theme='dark'] .search-input,
: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 {
background: #1d3048;
color: #c9d8eb;
: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: color-mix(in srgb, var(--muted) 76%, transparent);
}
:root[data-theme='dark'] .backup-help-trigger {
border-color: #38618f;
background: #173150;
color: #9ec5ff;
: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: 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'] .backup-help-trigger:focus-visible {
border-color: #5f92d7;
background: #20426a;
:root[data-theme='dark'] .input-readonly {
background: var(--panel-muted);
color: var(--muted-strong);
}
: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);
border-color: var(--line);
color: var(--text);
}
:root[data-theme='dark'] .backup-help-bubble::before {
background: var(--panel);
border-left-color: var(--line);
border-top-color: var(--line);
:root[data-theme='dark'] .toast-item.error,
:root[data-theme='dark'] .toast-item.warning {
border-color: color-mix(in srgb, var(--danger) 36%, var(--line));
background: color-mix(in srgb, var(--danger) 12%, var(--panel));
color: var(--text);
}
:root[data-theme='dark'] .table td {
border-bottom-color: #203047;
: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: var(--warning);
}
:root[data-theme='dark'] .local-error {
color: #ff9bb0;
color: var(--danger);
}
:root[data-theme='dark'] .status-ok {
color: #9be2bd;
}
:root[data-theme='dark'] .totp-qr {
background: #ffffff;
border-color: rgba(15, 23, 42, 0.12);
color: var(--success);
}
:root[data-theme='dark'] .totp-qr,
:root[data-theme='dark'] .totp-qr svg,
:root[data-theme='dark'] .totp-qr img {
background: #ffffff;
border-radius: 8px;
border-color: rgba(15, 23, 42, 0.12);
}
+34 -132
View File
@@ -1,38 +1,20 @@
.muted {
margin: 0 0 16px 0;
text-align: center;
color: var(--muted);
line-height: 1.65;
@apply m-0 mb-4 text-center leading-relaxed text-muted;
}
.field {
display: block;
margin-bottom: 14px;
@apply mb-3.5 block;
}
.field > span {
display: block;
margin-bottom: 8px;
font-size: 14px;
font-weight: 600;
@apply mb-2 block text-sm font-semibold;
}
.input {
width: 100%;
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);
@apply h-12 w-full rounded-xl border px-3.5 py-2.5 text-base text-ink outline-none transition;
background: var(--panel);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9);
transition:
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);
border-color: rgba(74, 103, 150, 0.34);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.82);
}
select.input {
@@ -59,15 +41,10 @@ input[type='file'].input {
}
input[type='file'].input::file-selector-button {
height: 32px;
border: 1px solid #3f5b9e;
border-radius: 999px;
padding: 0 12px;
@apply mr-2.5 h-8 cursor-pointer rounded-full border px-3 font-bold;
background: #eef4ff;
border-color: #9db8ea;
color: #1f4ea0;
font-weight: 700;
cursor: pointer;
margin-right: 10px;
}
input[type='file'].input::file-selector-button:hover {
@@ -76,32 +53,25 @@ input[type='file'].input::file-selector-button:hover {
}
.textarea {
min-height: 110px;
height: auto;
resize: vertical;
@apply h-auto min-h-28 resize-y;
}
.input:focus {
border-color: rgba(43, 102, 217, 0.6);
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);
transform: translateY(-1px);
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);
}
.input-readonly {
background: #eef2f7;
color: #475569;
@apply bg-slate-100 text-slate-600;
}
.input:disabled {
background: #e2e8f0;
border-color: #cbd5e1;
color: #94a3b8;
cursor: not-allowed;
@apply cursor-not-allowed border-slate-300 bg-slate-200 text-slate-400;
}
.password-wrap {
position: relative;
@apply relative;
}
.password-wrap .input {
@@ -109,32 +79,12 @@ input[type='file'].input::file-selector-button:hover {
}
.password-toggle {
position: absolute;
right: 8px;
top: 50%;
@apply absolute right-2 top-1/2 grid cursor-pointer place-items-center border-0 bg-transparent text-blue-700 transition;
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 {
position: absolute;
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);
@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;
}
.password-toggle:hover,
@@ -144,33 +94,13 @@ input[type='file'].input::file-selector-button:hover {
}
.btn {
height: 36px;
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);
@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;
}
.topbar-actions .btn,
.user-chip,
.side-link,
.mobile-tab {
--mag-x: 0px;
--mag-y: 0px;
position: relative;
overflow: hidden;
}
@@ -181,8 +111,8 @@ input[type='file'].input::file-selector-button:hover {
.mobile-tab::before {
content: '';
position: absolute;
left: var(--mx, 50%);
top: var(--my, 50%);
left: 50%;
top: 50%;
width: 110px;
height: 110px;
border-radius: 999px;
@@ -199,12 +129,11 @@ input[type='file'].input::file-selector-button:hover {
.user-chip:hover::before,
.side-link:hover::before,
.mobile-tab:hover::before {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
opacity: 0;
}
.btn:hover:not(:disabled) {
transform: translateY(-2px) scale(1.01);
transform: translateY(-1px);
}
.btn:active:not(:disabled) {
@@ -216,30 +145,23 @@ input[type='file'].input::file-selector-button:hover {
}
.btn.full {
width: 100%;
height: 50px;
font-size: 22px;
margin: 10px 0;
@apply my-2.5 h-12 w-full text-lg;
}
.btn-primary {
background: linear-gradient(135deg, #2563eb, #3b82f6 72%);
border-color: rgba(15, 63, 152, 0.32);
color: #fff;
box-shadow: 0 14px 28px rgba(37, 99, 235, 0.24);
@apply border-blue-700/30 bg-blue-600 text-white;
box-shadow: 0 10px 22px rgba(37, 99, 235, 0.20);
}
.btn-primary:hover {
background: linear-gradient(135deg, #1d4ed8, #3377f0 72%);
border-color: rgba(15, 63, 152, 0.38);
box-shadow: 0 18px 34px rgba(37, 99, 235, 0.28);
@apply bg-blue-700;
box-shadow: 0 12px 26px rgba(37, 99, 235, 0.22);
}
.btn-secondary {
background: var(--panel);
border-color: rgba(37, 99, 235, 0.22);
color: var(--primary-strong);
box-shadow: 0 8px 18px rgba(13, 31, 68, 0.05);
@apply bg-panel text-brand-strong;
border-color: rgba(37, 99, 235, 0.20);
box-shadow: 0 6px 14px rgba(13, 31, 68, 0.04);
}
.btn-secondary:hover {
@@ -248,9 +170,8 @@ input[type='file'].input::file-selector-button:hover {
}
.btn-danger {
background: rgba(255, 255, 255, 0.8);
@apply bg-white/80 text-danger;
border-color: rgba(217, 45, 87, 0.28);
color: var(--danger);
}
.btn-danger:hover {
@@ -259,42 +180,23 @@ input[type='file'].input::file-selector-button:hover {
}
.btn:disabled {
background: #e2e8f0;
border-color: #cbd5e1;
color: #94a3b8;
cursor: not-allowed;
@apply cursor-not-allowed border-slate-300 bg-slate-200 text-slate-400;
}
.or {
text-align: center;
margin: 10px 0;
color: #334155;
@apply my-2.5 text-center text-slate-700;
}
.field-help {
margin-top: 8px;
font-size: 13px;
line-height: 1.5;
color: #667085;
@apply mt-2 text-[13px] leading-normal text-slate-500;
}
.auth-support-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
margin: -2px 0 12px;
@apply -mt-0.5 mb-3 flex items-center justify-between gap-2.5;
}
.auth-link-btn {
border: none;
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);
@apply cursor-pointer border-0 bg-transparent p-0 text-[13px] font-bold text-blue-700 transition;
}
.auth-link-btn:hover {
+11 -18
View File
@@ -21,77 +21,63 @@
@keyframes fade-in-up {
from {
opacity: 0;
transform: translate3d(0, 16px, 0);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
@keyframes shell-enter {
from {
opacity: 0;
transform: translate3d(0, 18px, 0) scale(0.992);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0) scale(1);
}
}
@keyframes surface-enter {
from {
opacity: 0;
transform: translate3d(0, 20px, 0) scale(0.985);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0) scale(1);
}
}
@keyframes menu-in {
from {
opacity: 0;
transform: translate3d(0, 10px, 0) scale(0.96);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0) scale(1);
}
}
@keyframes dialog-in {
from {
opacity: 0;
transform: translate3d(0, 18px, 0) scale(0.96);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0) scale(1);
}
}
@keyframes toast-in {
from {
opacity: 0;
transform: translate3d(18px, 0, 0) scale(0.97);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0) scale(1);
}
}
@keyframes stagger-rise {
from {
opacity: 0;
transform: translate3d(0, 18px, 0) scale(0.985);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0) scale(1);
}
}
@@ -107,21 +93,28 @@
@keyframes dialog-out {
from {
opacity: 1;
transform: translate3d(0, 0, 0) scale(1);
}
to {
opacity: 0;
transform: translate3d(0, 10px, 0) scale(0.972);
}
}
@keyframes route-stage-in {
from {
opacity: 0;
transform: translate3d(0, 14px, 0);
}
to {
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 {
transform: translate3d(var(--mag-x), calc(var(--mag-y) - 1px), 0);
transform: translateY(-1px);
}
.mobile-tab.active {
+32 -127
View File
@@ -1,44 +1,22 @@
.app-page {
min-height: 100%;
padding: 20px;
position: relative;
background: transparent;
@apply relative min-h-full bg-transparent p-5;
}
.app-shell {
@apply relative mx-auto flex max-w-[1600px] flex-col overflow-hidden border bg-panel-soft shadow-elevated;
height: calc(100vh - 40px);
max-width: 1600px;
margin: 0 auto;
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;
border-color: var(--line);
border-radius: 24px;
}
.topbar {
height: 58px;
border-bottom: 1px solid var(--line-soft);
color: #0f172a;
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);
@apply flex h-[58px] items-center justify-between border-b px-[18px] text-slate-900 transition;
border-color: var(--line-soft);
background: rgba(244, 248, 255, 0.82);
}
.brand {
display: inline-flex;
align-items: center;
gap: 8px;
font-size: 34px;
font-weight: 800;
color: var(--text);
@apply inline-flex items-center gap-2 text-[34px] font-extrabold text-ink;
}
.brand-wordmark {
@@ -50,30 +28,17 @@
}
.mobile-page-title {
display: none;
min-width: 0;
@apply hidden min-w-0 overflow-hidden text-ellipsis whitespace-nowrap text-[19px] font-extrabold leading-tight text-slate-900;
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 {
width: 42px;
height: 42px;
object-fit: contain;
@apply h-[42px] w-[42px] object-contain;
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 {
display: flex;
align-items: center;
gap: 10px;
@apply flex items-center gap-2.5;
}
.mobile-tabbar {
@@ -93,9 +58,7 @@
}
.theme-switch-wrap {
display: inline-flex;
align-items: center;
justify-content: center;
@apply inline-flex items-center justify-center;
}
.theme-switch {
@@ -112,20 +75,9 @@
}
.theme-switch-slider {
position: absolute;
cursor: pointer;
top: 0;
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;
@apply absolute inset-0 cursor-pointer rounded-full border transition;
background: #dbeafe;
border-color: #9dbbec;
}
.theme-switch-slider::before {
@@ -182,7 +134,7 @@
}
.theme-switch:hover .theme-switch-slider {
transform: scale(1.02);
transform: none;
}
.theme-switch:hover .sun svg,
@@ -196,105 +148,58 @@
padding: 0 12px;
font-size: 13px;
font-weight: 600;
transform: translate3d(var(--mag-x), var(--mag-y), 0);
transition-duration: 220ms;
}
.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 {
display: inline-flex;
align-items: center;
gap: 6px;
height: 34px;
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);
@apply inline-flex h-[34px] items-center gap-1.5 rounded-full border px-3 text-sm font-semibold text-muted-strong transition;
background: rgba(249, 251, 255, 0.94);
border-color: rgba(148, 163, 184, 0.30);
box-shadow: 0 8px 16px rgba(13, 31, 68, 0.04);
}
.user-chip:hover {
transform: translate3d(var(--mag-x), calc(var(--mag-y) - 1px), 0);
box-shadow: 0 16px 28px rgba(15, 23, 42, 0.08);
box-shadow: 0 10px 22px rgba(15, 23, 42, 0.06);
}
.app-main {
flex: 1;
min-height: 0;
display: grid;
@apply grid min-h-0 flex-1;
grid-template-columns: 200px 1fr;
}
.app-side {
border-right: 1px solid var(--line-soft);
padding: 16px 12px;
display: flex;
flex-direction: column;
gap: 8px;
@apply flex flex-col gap-2 border-r px-3 py-4;
border-color: var(--line-soft);
}
.side-link {
display: flex;
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);
@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;
}
.side-link:hover {
background: #ffffff;
background: #fff;
border-color: rgba(128, 152, 192, 0.18);
color: var(--text);
transform: translate3d(calc(var(--mag-x) + 3px), var(--mag-y), 0);
box-shadow: 0 14px 24px rgba(15, 23, 42, 0.05);
box-shadow: 0 10px 18px rgba(15, 23, 42, 0.04);
}
.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);
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 {
min-height: 0;
padding: 14px;
overflow: hidden;
@apply min-h-0 overflow-hidden p-3.5;
}
.route-stage {
height: 100%;
min-height: 0;
overflow: auto;
}
@media (min-width: 901px) {
.route-stage {
animation: route-stage-in 240ms var(--ease-out-soft) both;
}
@apply h-full min-h-0 overflow-auto;
}
.mobile-sidebar-mask {
+38 -28
View File
@@ -1,21 +1,28 @@
:root {
--bg-accent: #e7edf8;
--panel: #f9fbff;
--panel-soft: #f2f6fd;
--panel-muted: #e8eff9;
--line: rgba(128, 152, 192, 0.32);
--line-soft: rgba(143, 167, 206, 0.18);
--bg-accent: #eef3fa;
--panel: #ffffff;
--panel-soft: #f6f8fc;
--panel-muted: #edf2f8;
--panel-subtle: #f8fafc;
--line: rgba(113, 132, 163, 0.28);
--line-soft: rgba(113, 132, 163, 0.16);
--text: #0b1730;
--muted: #60708b;
--muted-strong: #334765;
--muted: #5f6f85;
--muted-strong: #2f4058;
--primary: #2563eb;
--primary-hover: #1d4ed8;
--primary-strong: #0f3f98;
--danger: #d92d57;
--success: #0f766e;
--warning: #b45309;
--overlay-strong: rgba(15, 23, 42, 0.56);
--shadow-sm: 0 10px 22px rgba(13, 31, 68, 0.045);
--shadow-md: 0 22px 48px rgba(13, 31, 68, 0.08);
--shadow-lg: 0 28px 76px rgba(13, 31, 68, 0.11);
--shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.05);
--shadow-md: 0 8px 24px rgba(15, 23, 42, 0.08);
--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-soft: cubic-bezier(0.24, 0.8, 0.32, 1);
--ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);
@@ -26,21 +33,24 @@
}
:root[data-theme='dark'] {
--bg-accent: #06111d;
--panel: #0d192b;
--panel-soft: #112136;
--panel-muted: #0a1626;
--line: rgba(108, 141, 190, 0.28);
--line-soft: rgba(120, 152, 198, 0.16);
--text: #edf4ff;
--muted: #8fa6c6;
--muted-strong: #c3d5ef;
--primary: #84b6ff;
--primary-hover: #a6ccff;
--primary-strong: #f3f8ff;
--danger: #ff8ba8;
--overlay-strong: rgba(2, 8, 20, 0.84);
--shadow-sm: 0 14px 28px rgba(1, 7, 18, 0.24);
--shadow-md: 0 24px 52px rgba(1, 7, 18, 0.36);
--shadow-lg: 0 34px 88px rgba(1, 7, 18, 0.46);
--bg-accent: #0b1020;
--panel: #111827;
--panel-soft: #0f172a;
--panel-muted: #0b1324;
--panel-subtle: #151e2e;
--line: rgba(148, 163, 184, 0.20);
--line-soft: rgba(148, 163, 184, 0.12);
--text: #e5edf8;
--muted: #9aa8bb;
--muted-strong: #c7d2e2;
--primary: #8bb8ff;
--primary-hover: #a9ccff;
--primary-strong: #dceaff;
--danger: #fb7185;
--success: #5eead4;
--warning: #fbbf24;
--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 {
display: grid;
@apply grid h-full min-h-0 gap-3 p-0.5;
grid-template-columns: 240px minmax(420px, 46%) minmax(575px, 1fr);
gap: 12px;
height: 100%;
min-height: 0;
padding: 2px;
}
.sidebar,
.list-panel,
.card {
background: var(--panel);
border: 1px solid var(--line);
border-radius: 18px;
box-shadow: var(--shadow-sm);
@apply border bg-panel shadow-soft;
border-color: var(--line);
border-radius: 16px;
}
.sidebar {
padding: 0;
overflow: auto;
border: none;
box-shadow: none;
background: transparent;
@apply overflow-auto border-0 bg-transparent p-0 shadow-none;
}
.sidebar-block {
border: 1px solid var(--line);
border-radius: 19px;
padding: 12px;
margin-bottom: 8px;
background: var(--panel);
@apply mb-2 rounded-2xl border bg-panel p-3;
border-color: var(--line);
}
.sidebar-title {
font-size: 13px;
font-weight: 700;
color: #344054;
margin-bottom: 8px;
@apply mb-2 text-[13px] font-bold text-slate-700;
}
.sidebar-title-row {
@@ -51,21 +36,11 @@
}
.folder-title-actions {
display: inline-flex;
align-items: center;
gap: 8px;
@apply inline-flex items-center gap-2;
}
.folder-add-btn {
border: none;
background: transparent;
color: #334155;
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
padding: 0;
line-height: 1;
@apply inline-flex cursor-pointer items-center justify-center border-0 bg-transparent p-0 leading-none text-slate-700;
}
.folder-add-btn:hover {
@@ -73,21 +48,10 @@
}
.search-input {
width: 100%;
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);
@apply h-12 w-full rounded-xl border px-3.5 py-2.5 text-base text-ink outline-none transition;
background: var(--panel);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9);
transition:
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);
border-color: rgba(74, 103, 150, 0.34);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.82);
}
.search-input-wrap {
@@ -99,8 +63,7 @@
.search-input:focus {
border-color: rgba(43, 102, 217, 0.6);
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);
transform: translateY(-1px);
box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.10), inset 0 1px 0 rgba(255, 255, 255, 0.95);
}
.search-input-wrap .search-input {
@@ -137,27 +100,11 @@
}
.tree-btn {
width: 100%;
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);
@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;
}
.tree-btn:hover {
transform: translateX(2px);
background: rgba(37, 99, 235, 0.05);
}
.tree-btn.active {
@@ -218,11 +165,7 @@
}
.list-col {
display: flex;
flex-direction: column;
min-width: 0;
min-height: 0;
max-width: 540px;
@apply flex min-h-0 min-w-0 max-w-[540px] flex-col;
}
.toolbar {
@@ -241,10 +184,7 @@
}
.list-head {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 8px;
@apply mb-2 flex items-center gap-2.5;
}
.list-head .search-input-wrap {
@@ -343,32 +283,13 @@
}
.list-panel {
overflow: auto;
min-height: 0;
padding: 8px;
@apply min-h-0 overflow-auto p-2;
}
.list-item {
width: 100%;
background: rgba(249, 251, 255, 0.88);
border: 1px solid 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);
@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.9);
border-color: var(--line);
contain: paint;
}
@@ -395,8 +316,7 @@
.list-item:hover {
background: #fcfdff;
border-color: rgba(148, 163, 184, 0.26);
box-shadow: 0 16px 28px rgba(15, 23, 42, 0.06);
transform: translate3d(0, -2px, 0) scale(1.008);
box-shadow: 0 10px 22px rgba(15, 23, 42, 0.05);
}
.list-item:hover::before {
@@ -407,8 +327,7 @@
.list-item.active {
background: rgba(37, 99, 235, 0.1);
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);
transform: translate3d(0, -1px, 0) scale(1.004);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.42);
}
.list-item.active::before {
@@ -564,8 +483,7 @@
}
.card {
padding: 16px 18px;
margin-bottom: 10px;
@apply mb-2.5 px-[18px] py-4;
}
.detail-col > .card {
+3
View File
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;