From 94a28aa31ab69933b92673b387561ef8fdc670f3 Mon Sep 17 00:00:00 2001 From: 12975 <1297598740@qq.com> Date: Mon, 26 Jan 2026 02:17:45 +0800 Subject: [PATCH] =?UTF-8?q?feat:=201.=20=E6=B7=B1=E5=BA=A6=E6=B2=89?= =?UTF-8?q?=E6=B5=B8=E7=9A=84=E8=A7=86=E8=A7=89=E7=B3=BB=E7=BB=9F=20Mesh?= =?UTF-8?q?=20Gradients:=20=E5=BC=95=E5=85=A5=E4=BA=86=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E6=B5=81=E4=BD=93=E6=B8=90=E5=8F=98=E8=83=8C=E6=99=AF=EF=BC=8C?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E4=B8=8D=E5=86=8D=E9=9D=99=E6=AD=A2=EF=BC=8C?= =?UTF-8?q?=E8=80=8C=E6=98=AF=E5=A6=82=E5=90=8C=E5=91=BC=E5=90=B8=E8=88=AC?= =?UTF-8?q?=E6=9C=89=E7=9D=80=E5=BE=AE=E5=A6=99=E7=9A=84=E5=BE=8B=E5=8A=A8?= =?UTF-8?q?=E3=80=82=20Glassmorphism=202.0:=20=E5=85=A8=E9=9D=A2=E5=8D=87?= =?UTF-8?q?=E7=BA=A7=E7=9A=84=E7=8E=BB=E7=92=83=E6=8B=9F=E6=80=81=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=EF=BC=88Cards,=20Modals,=20Toasts=EF=BC=89=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E5=90=88=20Slate=20=E6=B7=B1=E8=89=B2=E7=B3=BB?= =?UTF-8?q?=E8=83=8C=E6=99=AF=EF=BC=8C=E5=9C=A8=E6=9A=97=E5=A4=9C=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E4=B8=8B=E5=91=88=E7=8E=B0=E5=87=BA=E6=9E=81=E4=BD=B3?= =?UTF-8?q?=E7=9A=84=E6=82=AC=E6=B5=AE=E6=84=9F=E4=B8=8E=E5=B1=82=E6=AC=A1?= =?UTF-8?q?=E6=84=9F=E3=80=82=20=E5=AE=8C=E7=BE=8E=E7=89=88=E5=BC=8F:=20?= =?UTF-8?q?=E5=9F=BA=E4=BA=8E=20Perfect=20Fourth=20=E6=AF=94=E4=BE=8B?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E4=BA=86=E5=AD=97=E5=8F=B7=E9=98=B6=E6=A2=AF?= =?UTF-8?q?=EF=BC=8C=E9=98=85=E8=AF=BB=E4=BD=93=E9=AA=8C=E6=9B=B4=E5=8A=A0?= =?UTF-8?q?=E6=84=89=E6=82=A6=E3=80=82=202.=20=E2=80=9C=E6=9C=89=E7=94=9F?= =?UTF-8?q?=E5=91=BD=E5=8A=9B=E2=80=9D=E7=9A=84=E5=BE=AE=E4=BA=A4=E4=BA=92?= =?UTF-8?q?=20=E8=A7=A6=E6=8E=A7=E5=8F=8D=E9=A6=88:=20=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E7=AB=AF=E5=92=8C=E6=A1=8C=E9=9D=A2=E7=AB=AF=E7=9A=84=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E3=80=81=E5=8D=A1=E7=89=87=E7=8E=B0=E5=9C=A8=E9=83=BD?= =?UTF-8?q?=E6=9C=89=E4=BA=86=E5=9F=BA=E4=BA=8E=E7=89=A9=E7=90=86=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E7=9A=84=20Scale=20=E6=88=96=20Ripple=20=E5=8F=8D?= =?UTF-8?q?=E9=A6=88=EF=BC=8C=E6=93=8D=E4=BD=9C=E4=B8=8D=E5=86=8D=E6=84=9F?= =?UTF-8?q?=E8=A7=89=E6=98=AF=E5=9C=A8=E7=82=B9=E5=87=BB=E2=80=9C=E6=AD=BB?= =?UTF-8?q?=E2=80=9D=E7=9A=84=E5=83=8F=E7=B4=A0=E3=80=82=20=E7=A9=BA?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E4=B8=8D=E7=A9=BA:=20=E9=87=8D=E6=96=B0?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E4=BA=86=20Empty=20States=EF=BC=8C=E6=82=AC?= =?UTF-8?q?=E5=81=9C=E6=97=B6=E5=9B=BE=E6=A0=87=E4=BC=9A=E4=BA=A7=E7=94=9F?= =?UTF-8?q?=203D=20=E6=97=8B=E8=BD=AC=EF=BC=8C=E5=BC=95=E5=AF=BC=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E8=BF=9B=E8=A1=8C=E6=93=8D=E4=BD=9C=E3=80=82=20?= =?UTF-8?q?=E6=97=A0=E9=9A=9C=E7=A2=8D=E8=81=9A=E7=84=A6:=20=E4=B8=BA?= =?UTF-8?q?=E9=94=AE=E7=9B=98=E6=93=8D=E4=BD=9C=E6=B7=BB=E5=8A=A0=E4=BA=86?= =?UTF-8?q?=E5=8F=8C=E5=B1=82=20Focus=20Ring=EF=BC=8C=E6=97=A2=E7=BE=8E?= =?UTF-8?q?=E8=A7=82=E5=8F=88=E6=B8=85=E6=99=B0=E3=80=82=203.=20=E6=A0=B8?= =?UTF-8?q?=E5=BF=83=E5=8A=9F=E8=83=BD=E5=8C=BA=E9=87=8D=E5=A1=91=20?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E7=AE=B1=20(Tools):=20=E5=8F=98=E8=BA=AB?= =?UTF-8?q?=E4=B8=BA=E5=8F=91=E5=85=89=E7=9A=84=203D=20=E7=8E=BB=E7=92=83?= =?UTF-8?q?=E9=9D=A2=E6=9D=BF=E9=98=B5=E5=88=97=E3=80=82=20=E8=B4=A6?= =?UTF-8?q?=E6=9C=AC=E7=AE=A1=E7=90=86:=20=E5=8D=87=E7=BA=A7=E4=B8=BA?= =?UTF-8?q?=E5=85=A8=E5=B0=81=E9=9D=A2=E8=89=BA=E6=9C=AF=E5=8D=A1=E7=89=87?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=E5=8A=A8=E6=80=81=E4=B8=BB=E9=A2=98?= =?UTF-8?q?=E8=89=B2=E6=98=A0=E5=B0=84=E3=80=82=20=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E5=AF=BC=E8=88=AA:=20=E5=BA=95=E9=83=A8=E5=AF=BC=E8=88=AA?= =?UTF-8?q?=E6=A0=8F=E8=BF=9B=E5=8C=96=E4=B8=BA=E2=80=9C=E6=82=AC=E6=B5=AE?= =?UTF-8?q?=E5=B2=9B=E2=80=9D=E8=AE=BE=E8=AE=A1=EF=BC=8C=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E7=9A=84=E7=81=B5=E5=8A=A8=E6=84=9F=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/Navigation/Navigation.css | 17 +- .../CategoryPieChart/CategoryPieChart.css | 20 +- .../report/TrendLineChart/TrendLineChart.css | 20 +- src/index.css | 21 ++ src/pages/Budget/Budget.css | 23 +- .../LedgerManagePage/LedgerManagePage.css | 34 +- src/pages/Settings/Settings.css | 56 +++- src/pages/ToolsPage/ToolsPage.css | 24 +- src/styles/components.css | 305 +++++++++++++++++- src/styles/themes.css | 81 ++--- src/styles/variables.css | 34 +- 11 files changed, 502 insertions(+), 133 deletions(-) diff --git a/src/components/common/Navigation/Navigation.css b/src/components/common/Navigation/Navigation.css index 9a5756d..9000841 100644 --- a/src/components/common/Navigation/Navigation.css +++ b/src/components/common/Navigation/Navigation.css @@ -11,17 +11,19 @@ .navigation { background: var(--glass-panel-bg); - -webkit-backdrop-filter: var(--glass-blur); - backdrop-filter: var(--glass-blur); + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); border-top: 1px solid var(--glass-border); position: fixed; bottom: 0; left: 0; right: 0; z-index: 100; - box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.05); + box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.05); + padding-bottom: env(safe-area-inset-bottom); } + .navigation-toggle { display: none; } @@ -57,12 +59,17 @@ position: relative; } +.navigation-link:active { + transform: scale(0.92); +} + .navigation-link:hover { - color: var(--color-primary); - background-color: var(--color-primary-lighter); + color: var(--accent-primary); + background-color: var(--bg-hover); transform: translateY(-2px); } + .navigation-link:focus { outline: none; box-shadow: 0 0 0 2px var(--color-primary-light); diff --git a/src/components/report/CategoryPieChart/CategoryPieChart.css b/src/components/report/CategoryPieChart/CategoryPieChart.css index 996a93c..c0d6e70 100644 --- a/src/components/report/CategoryPieChart/CategoryPieChart.css +++ b/src/components/report/CategoryPieChart/CategoryPieChart.css @@ -1,14 +1,24 @@ .category-pie-chart { - background: var(--card-bg); - border-radius: 8px; - padding: 1rem; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + background: var(--glass-panel-bg); + backdrop-filter: blur(16px); + -webkit-backdrop-filter: blur(16px); + border: 1px solid var(--glass-border); + border-radius: var(--radius-xl); + padding: var(--spacing-lg); + box-shadow: var(--shadow-lg); min-height: 400px; display: flex; align-items: center; justify-content: center; + transition: all 0.3s ease; } +.category-pie-chart:hover { + box-shadow: var(--shadow-glow-md); + border-color: rgba(var(--accent-rgb), 0.3); +} + + .chart-loading, .chart-empty { text-align: center; @@ -22,4 +32,4 @@ .category-pie-chart { padding: 0.5rem; } -} +} \ No newline at end of file diff --git a/src/components/report/TrendLineChart/TrendLineChart.css b/src/components/report/TrendLineChart/TrendLineChart.css index 1366b2a..c46ff67 100644 --- a/src/components/report/TrendLineChart/TrendLineChart.css +++ b/src/components/report/TrendLineChart/TrendLineChart.css @@ -1,14 +1,24 @@ .trend-line-chart { - background: var(--card-bg); - border-radius: 8px; - padding: 1rem; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + background: var(--glass-panel-bg); + backdrop-filter: blur(16px); + -webkit-backdrop-filter: blur(16px); + border: 1px solid var(--glass-border); + border-radius: var(--radius-xl); + padding: var(--spacing-lg); + box-shadow: var(--shadow-lg); min-height: 400px; display: flex; align-items: center; justify-content: center; + transition: all 0.3s ease; } +.trend-line-chart:hover { + box-shadow: var(--shadow-glow-md); + border-color: rgba(var(--accent-rgb), 0.3); +} + + .chart-loading, .chart-empty { text-align: center; @@ -22,4 +32,4 @@ .trend-line-chart { padding: 0.5rem; } -} +} \ No newline at end of file diff --git a/src/index.css b/src/index.css index 2ef63e0..698fbe9 100644 --- a/src/index.css +++ b/src/index.css @@ -99,4 +99,25 @@ button { clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; +} + +/* Accessibility Focus Ring */ +:focus-visible { + outline: 2px solid var(--accent-primary); + outline-offset: 2px; + box-shadow: 0 0 0 4px rgba(var(--accent-rgb), 0.2); + border-radius: 4px; +} + +/* Reduced Motion */ +@media (prefers-reduced-motion: reduce) { + + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + scroll-behavior: auto !important; + } } \ No newline at end of file diff --git a/src/pages/Budget/Budget.css b/src/pages/Budget/Budget.css index 87b637d..b658125 100644 --- a/src/pages/Budget/Budget.css +++ b/src/pages/Budget/Budget.css @@ -45,25 +45,25 @@ border: none; border-radius: var(--radius-full); cursor: pointer; - transition: all 0.2s ease; - box-shadow: 0 4px 10px rgba(99, 102, 241, 0.3); + transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); + box-shadow: 0 4px 12px rgba(var(--accent-rgb), 0.3); } .budget-header__create-btn:hover { transform: translateY(-2px); - box-shadow: 0 6px 16px rgba(99, 102, 241, 0.4); + box-shadow: 0 8px 16px rgba(var(--accent-rgb), 0.4); } .budget-header__create-btn--piggy { - background: var(--gradient-accent); - box-shadow: 0 4px 10px rgba(249, 115, 22, 0.3); + background: linear-gradient(135deg, #f97316 0%, #fbbf24 100%); + box-shadow: 0 4px 12px rgba(249, 115, 22, 0.3); } .budget-header__create-btn--piggy:hover { - background: var(--gradient-accent); - box-shadow: 0 6px 16px rgba(249, 115, 22, 0.4); + box-shadow: 0 8px 16px rgba(249, 115, 22, 0.4); } + /* Content */ .budget-content { display: flex; @@ -74,15 +74,16 @@ /* Form Section */ .budget-form-section { background: var(--glass-panel-bg); - backdrop-filter: var(--glass-blur); - -webkit-backdrop-filter: var(--glass-blur); + backdrop-filter: blur(24px); + -webkit-backdrop-filter: blur(24px); border: 1px solid var(--glass-border); border-radius: var(--radius-xl); padding: var(--spacing-xl); - box-shadow: var(--glass-shadow); - animation: slideUp 0.3s ease; + box-shadow: var(--shadow-xl); + animation: slideUp 0.4s cubic-bezier(0.16, 1, 0.3, 1); } + /* Sections */ .budgets-section, .piggy-banks-section { diff --git a/src/pages/LedgerManagePage/LedgerManagePage.css b/src/pages/LedgerManagePage/LedgerManagePage.css index d77b964..b65906b 100644 --- a/src/pages/LedgerManagePage/LedgerManagePage.css +++ b/src/pages/LedgerManagePage/LedgerManagePage.css @@ -11,16 +11,23 @@ /* Header */ .ledger-manage-page__header { - margin-bottom: 1.5rem; + margin-bottom: var(--spacing-xl); } .ledger-manage-page__title { - font-size: 1.875rem; - font-weight: 700; - color: #111827; + font-family: 'Outfit', sans-serif; + font-size: var(--font-3xl); + font-weight: 800; margin: 0; + background: var(--gradient-primary); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + color: var(--color-primary); + letter-spacing: -0.5px; } + /* Tabs */ .ledger-manage-page__tabs { display: flex; @@ -113,6 +120,7 @@ from { transform: rotate(0deg); } + to { transform: rotate(360deg); } @@ -144,17 +152,23 @@ .ledger-manage-card { display: flex; flex-direction: column; - background-color: white; - border-radius: 0.75rem; - box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); + background: var(--glass-panel-bg); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + border: 1px solid var(--glass-border); + border-radius: var(--radius-xl); + box-shadow: var(--shadow-sm); overflow: hidden; - transition: box-shadow 0.2s; + transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); } .ledger-manage-card:hover { - box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + transform: translateY(-6px); + box-shadow: var(--shadow-xl); + border-color: rgba(var(--accent-rgb), 0.3); } + /* Card Cover */ .ledger-manage-card__cover { height: 160px; @@ -327,4 +341,4 @@ .ledger-manage-card__action-btn { width: 100%; } -} +} \ No newline at end of file diff --git a/src/pages/Settings/Settings.css b/src/pages/Settings/Settings.css index 6a480a9..c9d24eb 100644 --- a/src/pages/Settings/Settings.css +++ b/src/pages/Settings/Settings.css @@ -6,8 +6,22 @@ width: 100%; padding-bottom: var(--spacing-2xl); animation: fadeIn 0.5s ease-out; + position: relative; } +.settings-page::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 400px; + background: radial-gradient(at 50% 0%, rgba(var(--accent-rgb), 0.15) 0px, transparent 70%); + pointer-events: none; + z-index: 0; +} + + .settings-header { margin-bottom: var(--spacing-xl); } @@ -30,44 +44,49 @@ display: flex; gap: var(--spacing-xs); margin-bottom: var(--spacing-xl); - padding: var(--spacing-xs); + padding: 6px; background: var(--glass-panel-bg); backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); border: 1px solid var(--glass-border); border-radius: var(--radius-full); overflow-x: auto; box-shadow: var(--shadow-sm); width: fit-content; + position: relative; + z-index: 10; } .tab-button { display: flex; align-items: center; gap: var(--spacing-sm); - padding: var(--spacing-sm) var(--spacing-lg); + padding: 0.6rem 1.25rem; background: transparent; border: none; border-radius: var(--radius-full); - color: var(--color-text-secondary); - font-size: var(--font-base); + color: var(--text-secondary); + font-size: 0.9375rem; font-weight: 600; cursor: pointer; - transition: all 0.2s ease; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); white-space: nowrap; + position: relative; } .tab-button:hover { - color: var(--color-text); + color: var(--text-primary); background: rgba(255, 255, 255, 0.5); } .tab-button.active { color: white; background: var(--gradient-primary); - box-shadow: 0 2px 8px rgba(99, 102, 241, 0.3); + box-shadow: 0 4px 12px rgba(var(--accent-rgb), 0.3); } + .settings-content { width: 100%; } @@ -651,31 +670,36 @@ } .theme-color-btn { - width: 36px; - height: 36px; + width: 42px; + height: 42px; border-radius: 50%; - border: 3px solid transparent; + border: 3px solid var(--bg-card); cursor: pointer; - transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); + transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); display: flex; align-items: center; justify-content: center; box-shadow: var(--shadow-sm); padding: 0; + outline: none; } .theme-color-btn:hover { - transform: translateY(-2px); - box-shadow: var(--shadow-md); + transform: translateY(-4px) scale(1.1); + box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15); + z-index: 1; } .theme-color-btn.active { border-color: var(--bg-primary); - box-shadow: 0 0 0 2px var(--color-text); - /* Outer ring effect */ - transform: scale(1.1); + box-shadow: + 0 0 0 3px var(--accent-primary), + 0 10px 20px -5px rgba(var(--accent-rgb), 0.4); + transform: scale(1.15); + z-index: 2; } + .theme-check-icon { color: white; width: 20px; diff --git a/src/pages/ToolsPage/ToolsPage.css b/src/pages/ToolsPage/ToolsPage.css index 9b62d1a..8640891 100644 --- a/src/pages/ToolsPage/ToolsPage.css +++ b/src/pages/ToolsPage/ToolsPage.css @@ -36,28 +36,34 @@ .tool-card { position: relative; padding: 32px 24px; - background-color: #ffffff; - border-radius: 16px; + background: var(--glass-panel-bg); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + border: 1px solid var(--glass-border); + border-radius: var(--radius-xl); border-top: 4px solid; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); + box-shadow: var(--shadow-sm); cursor: pointer; - transition: all 200ms ease; + transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); display: flex; flex-direction: column; align-items: center; text-align: center; - min-height: 200px; + min-height: 220px; + overflow: hidden; } .tool-card:hover { - transform: translateY(-4px); - box-shadow: 0 8px 16px rgba(0, 0, 0, 0.12); + transform: translateY(-8px); + box-shadow: var(--shadow-xl); + background: var(--glass-panel-bg-hover); } .tool-card:active { - transform: translateY(-2px); + transform: translateY(-2px) scale(0.98); } + /* Tool Icon */ .tool-icon { width: 80px; @@ -159,4 +165,4 @@ .tool-description { color: #9ca3af; } -} +} \ No newline at end of file diff --git a/src/styles/components.css b/src/styles/components.css index cd501ee..8c68d56 100644 --- a/src/styles/components.css +++ b/src/styles/components.css @@ -138,10 +138,33 @@ } .btn-primary:active:not(:disabled) { - transform: scale(0.98); - box-shadow: 0 2px 10px -2px rgba(var(--accent-rgb), 0.4); + transform: scale(0.96); + box-shadow: 0 2px 8px rgba(var(--accent-rgb), 0.3); } +/* Ripple Effect Simulation via pseudo-element */ +.btn-primary::after { + content: ''; + position: absolute; + top: 50%; + left: 50%; + width: 300%; + height: 300%; + background: rgba(255, 255, 255, 0.2); + border-radius: 50%; + transform: translate(-50%, -50%) scale(0); + opacity: 0; + transition: transform 0.6s, opacity 0.6s; + pointer-events: none; +} + +.btn-primary:active::after { + transform: translate(-50%, -50%) scale(1); + opacity: 1; + transition: 0s; +} + + /* 次要按钮 */ .btn-secondary { background: transparent; @@ -244,10 +267,16 @@ outline: none; background: var(--bg-secondary); border-bottom-color: var(--accent-primary); - box-shadow: 0 -1px 0 0 var(--accent-primary) inset; - /* Double bottom border feel */ + box-shadow: 0 -2px 0 0 var(--accent-primary) inset, 0 4px 12px rgba(var(--accent-rgb), 0.1); + transform: translateY(-1px); } +.input:focus-visible { + outline: 2px solid var(--accent-primary); + outline-offset: 2px; +} + + .input:disabled { opacity: 0.5; cursor: not-allowed; @@ -639,4 +668,270 @@ background: var(--color-bg); } -/* Add custom scrollbar here if not already effective via index.css */ \ No newline at end of file +/* ======================================== + * 模态框 (Modal) + * ======================================== */ + +.modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.4); + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + animation: fadeIn 0.3s cubic-bezier(0.4, 0, 0.2, 1); + padding: var(--spacing-md); +} + +.modal-content { + background: var(--glass-panel-bg); + backdrop-filter: blur(24px); + -webkit-backdrop-filter: blur(24px); + border: 1px solid var(--glass-border); + border-radius: var(--radius-2xl); + width: 100%; + max-width: 500px; + max-height: 90vh; + overflow-y: auto; + box-shadow: var(--shadow-2xl); + animation: modalSlideUp 0.4s cubic-bezier(0.16, 1, 0.3, 1); + position: relative; + z-index: 1001; +} + +@keyframes modalSlideUp { + from { + opacity: 0; + transform: translateY(40px) scale(0.95); + } + + to { + opacity: 1; + transform: translateY(0) scale(1); + } +} + +/* Modal Headers & Footers */ +.modal-header { + padding: var(--spacing-xl); + border-bottom: 1px solid var(--glass-border); + display: flex; + justify-content: space-between; + align-items: center; +} + +.modal-title { + font-family: 'Outfit', sans-serif; + font-size: var(--text-xl); + font-weight: 700; + color: var(--text-primary); + margin: 0; +} + +.modal-body { + padding: var(--spacing-xl); +} + +.modal-footer { + padding: var(--spacing-lg) var(--spacing-xl); + border-top: 1px solid var(--glass-border); + display: flex; + justify-content: flex-end; + gap: var(--spacing-md); + background: rgba(0, 0, 0, 0.02); +} + +/* Close Button */ +.modal-close-btn { + background: transparent; + border: none; + cursor: pointer; + color: var(--text-secondary); + padding: 4px; + border-radius: 50%; + transition: all 0.2s; + display: flex; + align-items: center; + justify-content: center; +} + +/* ======================================== + * 消息通知 (Toast) + * ======================================== */ + +.toast-container { + position: fixed; + top: var(--spacing-xl); + right: var(--spacing-xl); + z-index: 2000; + display: flex; + flex-direction: column; + gap: var(--spacing-md); + pointer-events: none; +} + +.toast { + background: var(--glass-panel-bg); + backdrop-filter: blur(16px); + -webkit-backdrop-filter: blur(16px); + border: 1px solid var(--glass-border); + padding: var(--spacing-md) var(--spacing-lg); + border-radius: var(--radius-lg); + box-shadow: var(--shadow-xl); + color: var(--text-primary); + font-weight: 500; + display: flex; + align-items: center; + gap: var(--spacing-md); + pointer-events: auto; + animation: toastSlideIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); + min-width: 300px; +} + +.toast--success { + border-left: 4px solid var(--accent-success); +} + +.toast--error { + border-left: 4px solid var(--accent-error); +} + +.toast--info { + border-left: 4px solid var(--accent-primary); +} + +/* ======================================== + * 空状态 (Empty States) + * ======================================== */ + +.empty-state { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; + padding: var(--spacing-2xl); + background: var(--glass-panel-bg); + backdrop-filter: blur(16px); + -webkit-backdrop-filter: blur(16px); + border: 1px dashed var(--glass-border); + border-radius: var(--radius-xl); + color: var(--text-secondary); + transition: all 0.3s ease; + min-height: 300px; +} + +.empty-state:hover { + background: var(--glass-bg); + border-color: var(--accent-primary); + transform: translateY(-2px); +} + +.empty-state-icon { + font-size: 4rem; + color: var(--text-muted); + margin-bottom: var(--spacing-md); + opacity: 0.5; + transition: all 0.3s ease; +} + +.empty-state:hover .empty-state-icon { + color: var(--accent-primary); + opacity: 1; + transform: scale(1.1) rotate(5deg); +} + +.empty-state-title { + font-size: var(--text-lg); + font-weight: 600; + color: var(--text-primary); + margin-bottom: var(--spacing-xs); +} + +.empty-state-description { + font-size: var(--text-sm); + color: var(--text-secondary); + max-width: 400px; + margin-bottom: var(--spacing-lg); +} + + +@keyframes toastSlideIn { + from { + opacity: 0; + transform: translateX(100%) scale(0.8); + } + + to { + opacity: 1; + transform: translateX(0) scale(1); + } +} + +/* ======================================== + * 加载状态 (Loading) + * ======================================== */ + +.loading-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(255, 255, 255, 0.5); + backdrop-filter: blur(4px); + display: flex; + align-items: center; + justify-content: center; + z-index: 10; + border-radius: inherit; +} + +.loading-spinner { + width: 40px; + height: 40px; + border: 3px solid rgba(var(--accent-rgb), 0.1); + border-top-color: var(--accent-primary); + border-radius: 50%; + animation: spin 0.8s linear infinite; +} + +.loading-dots { + display: flex; + gap: 4px; +} + +.loading-dot { + width: 8px; + height: 8px; + background: var(--accent-primary); + border-radius: 50%; + animation: bounce 1.4s infinite ease-in-out both; +} + +.loading-dot:nth-child(1) { + animation-delay: -0.32s; +} + +.loading-dot:nth-child(2) { + animation-delay: -0.16s; +} + +@keyframes bounce { + + 0%, + 80%, + 100% { + transform: scale(0); + } + + 40% { + transform: scale(1); + } +} \ No newline at end of file diff --git a/src/styles/themes.css b/src/styles/themes.css index 98141b2..804f4d9 100644 --- a/src/styles/themes.css +++ b/src/styles/themes.css @@ -10,72 +10,51 @@ /* ======================================== * 暗夜模式 (Dark Mode) - 默认 * ======================================== */ +/* Dark Mode - Deeper & Richer */ :root, :root[data-theme="dark"] { - /* 背景层级 */ - --bg-primary: #1c1917; - /* Stone 900 */ - --bg-secondary: #292524; - /* Stone 800 */ - --bg-tertiary: #44403c; - /* Stone 700 */ - --bg-elevated: #292524; - --bg-hover: rgba(245, 158, 11, 0.1); - --bg-active: rgba(245, 158, 11, 0.15); + /* 背景层级 - Deep Blue/Slate base instead of pure grey */ + --bg-primary: #0f172a; + /* Slate 900 */ + --bg-secondary: #1e293b; + /* Slate 800 */ + --bg-tertiary: #334155; + /* Slate 700 */ + --bg-elevated: #1e293b; + --bg-hover: rgba(255, 255, 255, 0.05); + --bg-active: rgba(255, 255, 255, 0.1); /* 文本层级 */ - --text-primary: #fafaf9; - /* Stone 50 */ - --text-secondary: #a8a29e; - /* Stone 400 */ - --text-muted: #78716c; - /* Stone 500 */ - --text-inverse: #1c1917; + --text-primary: #f8fafc; + /* Slate 50 */ + --text-secondary: #94a3b8; + /* Slate 400 */ + --text-muted: #64748b; + /* Slate 500 */ + --text-inverse: #0f172a; /* 强调色 - AMBER SCHEME (Default) */ - --accent-primary: #f59e0b; + --accent-primary: #fbbf24; + /* Amber 400 - Brighter for dark mode */ + --accent-rgb: 251, 191, 36; + --accent-primary-hover: #f59e0b; /* Amber 500 */ - --accent-rgb: 245, 158, 11; - --accent-primary-hover: #ea580c; - /* Orange 600 */ - --accent-secondary: #fbbf24; - /* Amber 400 */ - - --accent-success: #10b981; - /* Emerald */ - --accent-warning: #f97316; - /* Orange 500 */ - --accent-error: #ef4444; - /* Red */ - --accent-info: #3b82f6; - /* Blue */ - - /* 收入/支出颜色 */ - --color-income: #10b981; - --color-expense: #ef4444; - --color-transfer: #f59e0b; - - /* 边框 & 分割线 */ - --border-color: rgba(255, 255, 255, 0.08); - --border-color-strong: rgba(255, 255, 255, 0.15); - --divider-color: rgba(255, 255, 255, 0.05); + --accent-secondary: #fcd34d; + /* Amber 300 */ /* 玻璃拟态 (Glassmorphism) */ - --glass-bg: rgba(28, 25, 23, 0.7); + --glass-bg: rgba(15, 23, 42, 0.7); --glass-border: rgba(255, 255, 255, 0.08); - --glass-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.36); - --glass-shine: rgba(255, 255, 255, 0.03); - - /* 滚动条 */ - --scrollbar-track: transparent; - --scrollbar-thumb: rgba(255, 255, 255, 0.1); - --scrollbar-thumb-hover: var(--accent-primary); + --glass-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4); + --glass-shine: rgba(255, 255, 255, 0.05); + --glass-panel-bg: rgba(30, 41, 59, 0.6); /* 阴影 */ --shadow-color: rgba(0, 0, 0, 0.5); - --shadow-glow: 0 0 20px rgba(var(--accent-rgb), 0.3); + --shadow-glow: 0 0 25px rgba(var(--accent-rgb), 0.2); } + /* ======================================== * 白日模式 (Light Mode) * ======================================== */ diff --git a/src/styles/variables.css b/src/styles/variables.css index 380e6ee..7a79f2a 100644 --- a/src/styles/variables.css +++ b/src/styles/variables.css @@ -11,34 +11,36 @@ --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', sans-serif; --font-mono: 'JetBrains Mono', 'Fira Code', 'SF Mono', monospace; - /* 字号 */ + /* 字号 - Perfect Fourth Scale */ --text-xs: 0.75rem; /* 12px */ - --text-sm: 0.875rem; - /* 14px */ - --text-base: 1rem; - /* 16px */ - --text-lg: 1.125rem; - /* 18px */ - --text-xl: 1.25rem; + --text-sm: 0.9375rem; + /* 15px - Slightly larger for readability */ + --text-base: 1.0625rem; + /* 17px - Premium body size */ + --text-lg: 1.25rem; /* 20px */ - --text-2xl: 1.5rem; + --text-xl: 1.5rem; /* 24px */ - --text-3xl: 1.875rem; - /* 30px */ - --text-4xl: 2.25rem; - /* 36px */ + --text-2xl: 2rem; + /* 32px */ + --text-3xl: 2.5rem; + /* 40px */ + --text-4xl: 3.25rem; + /* 52px */ /* 字重 */ --font-normal: 400; --font-medium: 500; --font-semibold: 600; --font-bold: 700; + --font-extrabold: 800; /* 行高 */ - --leading-tight: 1.25; - --leading-normal: 1.5; - --leading-relaxed: 1.75; + --leading-tight: 1.2; + --leading-normal: 1.6; + --leading-relaxed: 1.8; + /* ======================================== * 间距系统