-
+
diff --git a/web-next/src/styles/theme.css b/web-next/src/styles/theme.css
index 6e50c87..4398b6b 100644
--- a/web-next/src/styles/theme.css
+++ b/web-next/src/styles/theme.css
@@ -100,11 +100,121 @@ input:focus-visible, textarea:focus-visible, select:focus-visible {
.tn-route-error-panel { width: min(420px, 100%); padding: 30px; border: 1px solid var(--tn-border); border-radius: 4px; background: var(--tn-surface); box-shadow: 0 14px 36px rgba(11, 58, 136, .08); }
.tn-route-error-panel h1 { margin: 0; color: var(--tn-text); font-size: 22px; }
.tn-route-error-panel p { margin: 10px 0 20px; color: var(--tn-text-secondary); overflow-wrap: anywhere; }
-.t-notification { width: min(360px, calc(100vw - 32px)); max-width: calc(100vw - 32px); border: 1px solid var(--tn-border); border-left-width: 1px; border-radius: 4px; box-shadow: 0 10px 26px rgba(11, 58, 136, .14); }
-/* TDesign mounts this wrapper directly under body. Keep one viewport inset
- at every breakpoint so notices remain fully visible while the page resizes. */
-.t-notification__show--top-right { right: 16px; }
-.t-notification__content { color: var(--tn-text); }
+/* ============================================================
+ Toast 样式四:柔和语义双层卡片 (Soft Tinted Card / 严格水平对齐)
+ ============================================================ */
+.t-notification {
+ width: min(380px, calc(100vw - 32px)) !important;
+ max-width: calc(100vw - 32px) !important;
+ border-radius: 6px !important;
+ padding: 12px 16px !important;
+ box-shadow: 0 10px 25px -4px rgba(15, 23, 42, 0.08), 0 4px 10px -2px rgba(15, 23, 42, 0.04) !important;
+ display: flex !important;
+ align-items: center !important;
+ gap: 10px !important;
+ box-sizing: border-box !important;
+ transition: all 0.22s cubic-bezier(0.16, 1, 0.3, 1) !important;
+}
+.t-notification__show--top-right {
+ right: 20px !important;
+}
+
+/* 核心对齐修复:清除 TDesign 默认的 margin-top: 8px 导致的文字下沉不居中 */
+.t-notification__main {
+ flex: 1 !important;
+ display: flex !important;
+ flex-direction: column !important;
+ justify-content: center !important;
+ margin: 0 !important;
+ padding: 0 !important;
+ min-width: 0 !important;
+}
+.t-notification__content {
+ color: inherit !important;
+ font-size: 13.5px !important;
+ font-weight: 500 !important;
+ line-height: 1.4 !important;
+ margin: 0 !important;
+ padding: 0 !important;
+ display: block !important;
+ word-break: break-word !important;
+}
+.t-notification__icon {
+ margin: 0 !important;
+ padding: 0 !important;
+ width: 20px !important;
+ height: 20px !important;
+ display: flex !important;
+ align-items: center !important;
+ justify-content: center !important;
+ flex-shrink: 0 !important;
+ line-height: 1 !important;
+}
+.t-notification__icon .t-icon {
+ font-size: 18px !important;
+ width: 18px !important;
+ height: 18px !important;
+ display: block !important;
+ margin: 0 auto !important;
+}
+.t-notification__close {
+ display: flex !important;
+ align-items: center !important;
+ justify-content: center !important;
+ margin: 0 0 0 auto !important;
+ padding: 0 !important;
+ height: 20px !important;
+ width: 20px !important;
+ line-height: 1 !important;
+ color: inherit !important;
+ opacity: 0.55 !important;
+ cursor: pointer !important;
+ transition: opacity 0.15s ease !important;
+ flex-shrink: 0 !important;
+}
+.t-notification__close:hover {
+ opacity: 1 !important;
+}
+
+/* Success: 柔和薄荷浅绿 */
+.t-notification.t-is-success {
+ background: #f0fdf4 !important;
+ border: 1px solid #bbf7d0 !important;
+ color: #166534 !important;
+}
+.t-notification.t-is-success .t-notification__icon {
+ color: #16a34a !important;
+}
+
+/* Info: 柔和天空浅蓝 */
+.t-notification.t-is-info {
+ background: #eff6ff !important;
+ border: 1px solid #bfdbfe !important;
+ color: #1e40af !important;
+}
+.t-notification.t-is-info .t-notification__icon {
+ color: #2563eb !important;
+}
+
+/* Warning: 柔和金橙浅黄 */
+.t-notification.t-is-warning {
+ background: #fffbeb !important;
+ border: 1px solid #fde68a !important;
+ color: #92400e !important;
+}
+.t-notification.t-is-warning .t-notification__icon {
+ color: #d97706 !important;
+}
+
+/* Error: 柔和玫瑰浅红 */
+.t-notification.t-is-error {
+ background: #fef2f2 !important;
+ border: 1px solid #fecaca !important;
+ color: #991b1b !important;
+}
+.t-notification.t-is-error .t-notification__icon {
+ color: #dc2626 !important;
+}
.tn-layout { width: 100%; height: 100%; min-height: 100vh; display: flex; flex-direction: row !important; background: var(--tn-page); overflow: hidden; }
.tn-desktop-menu { position: relative; top: 0; z-index: 30; display: block; width: 232px; height: 100%; flex: 0 0 232px; min-height: 100%; overflow: hidden; border-right: 1px solid var(--tn-border); background: var(--tn-surface); transition: width .22s ease, flex-basis .22s ease, opacity .22s ease; }
@@ -201,7 +311,59 @@ input:focus-visible, textarea:focus-visible, select:focus-visible {
.tn-action-group .t-button { color: var(--tn-text-secondary); }
.tn-action-group .t-button:not(.t-button--theme-danger):hover { color: var(--tn-blue-700); background: var(--tn-blue-100); }
.tn-action-group .t-button.t-button--theme-danger:hover { color: var(--tn-danger); background: #fff0f0; }
-.tn-empty { display: grid; min-height: 260px; place-items: center; align-content: center; gap: 10px; padding: 48px 20px; color: var(--tn-text-muted); text-align: center; }
+/* Absolutely Centered Loading and Empty States */
+.tn-empty {
+ display: flex !important;
+ flex-direction: column !important;
+ align-items: center !important;
+ justify-content: center !important;
+ min-height: max(380px, calc(100vh - 320px)) !important;
+ width: 100% !important;
+ height: 100% !important;
+ flex: 1 !important;
+ gap: 12px !important;
+ padding: 40px 20px !important;
+ color: var(--tn-text-muted) !important;
+ text-align: center !important;
+ box-sizing: border-box !important;
+}
+.expenses-page .tn-empty,
+.tn-dashboard-page .tn-empty,
+.tn-audit-table .tn-empty {
+ min-height: max(400px, calc(100vh - 300px)) !important;
+}
+.tn-detail-drawer .tn-empty,
+.tn-detail-drawer .t-drawer__body > div[role="status"] {
+ display: flex !important;
+ flex-direction: column !important;
+ align-items: center !important;
+ justify-content: center !important;
+ min-height: calc(100vh - 180px) !important;
+ height: 100% !important;
+ width: 100% !important;
+}
+.tn-auth-shell {
+ display: flex !important;
+ flex-direction: column !important;
+ align-items: center !important;
+ justify-content: center !important;
+ min-height: 100vh !important;
+ height: 100% !important;
+ padding: 24px !important;
+ background: var(--tn-page) !important;
+}
+.tn-page-loading {
+ display: flex !important;
+ flex-direction: column !important;
+ align-items: center !important;
+ justify-content: center !important;
+ min-height: calc(100vh - 120px) !important;
+ height: 100% !important;
+ width: 100% !important;
+ padding: 32px 20px !important;
+ color: var(--tn-text-muted) !important;
+ text-align: center !important;
+}
.tn-page-loading { display: grid; min-width: 0; min-height: 100%; place-items: center; align-content: center; gap: 10px; padding: 32px 20px; color: var(--tn-text-muted); text-align: center; }
.tn-empty p { margin: 0; color: var(--tn-text-secondary); }
.tn-selection { display: flex; align-items: center; gap: 14px; padding: 10px 12px; margin: 10px 0; border-left: 3px solid var(--tn-success); background: #eff7f2; color: #24543f; }
@@ -1421,10 +1583,18 @@ input:focus-visible, textarea:focus-visible, select:focus-visible {
margin: 16px 0;
}
.tn-modal-card-title {
- font-size: 15px;
- font-weight: 600;
- color: var(--tn-navy-900);
- margin-bottom: 14px;
+ font-size: 15px !important;
+ font-weight: 600 !important;
+ color: var(--tn-navy-900) !important;
+ margin-bottom: 14px !important;
+ display: flex !important;
+ align-items: center !important;
+ gap: 10px !important;
+ line-height: 1.4 !important;
+}
+.tn-modal-card-title svg {
+ flex-shrink: 0 !important;
+ display: block !important;
}
.tn-modal-metrics-row {
display: flex;
@@ -1467,3 +1637,89 @@ input:focus-visible, textarea:focus-visible, select:focus-visible {
gap: 10px;
font-size: 12px;
}
+
+
+/* ============================================================
+ 方案二:平滑极光光流条 (Beam Bar / Shimmer) 全局动效规范
+ ============================================================ */
+.tn-beam-loading {
+ display: flex !important;
+ flex-direction: column !important;
+ align-items: center !important;
+ justify-content: center !important;
+ gap: 16px !important;
+ padding: 40px 20px !important;
+ width: 100% !important;
+ height: 100% !important;
+ flex: 1 !important;
+ margin: auto !important;
+ text-align: center !important;
+}
+.tn-beam-bar {
+ width: 140px;
+ height: 4px;
+ background: #e2e8f0;
+ border-radius: 4px;
+ overflow: hidden;
+ position: relative;
+}
+.tn-beam-bar::after {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: -60px;
+ width: 60px;
+ height: 100%;
+ background: linear-gradient(90deg, transparent, var(--tn-blue-600), transparent);
+ border-radius: 4px;
+ animation: tn-beam-flow 1.3s cubic-bezier(0.4, 0, 0.2, 1) infinite;
+}
+
+.tn-beam-bar-sm {
+ width: 60px !important;
+ height: 3px !important;
+ display: inline-block;
+ vertical-align: middle;
+}
+.tn-beam-bar-sm::after {
+ width: 30px;
+ animation: tn-beam-flow-sm 1.1s cubic-bezier(0.4, 0, 0.2, 1) infinite;
+}
+
+@keyframes tn-beam-flow {
+ 0% { left: -60px; }
+ 100% { left: 140px; }
+}
+
+@keyframes tn-beam-flow-sm {
+ 0% { left: -30px; }
+ 100% { left: 60px; }
+}
+
+.tn-beam-text {
+ font-size: 13.5px;
+ color: var(--tn-text-secondary);
+ letter-spacing: 0.4px;
+}
+
+/* 彻底隐去 TDesign 默认圆环旋转圈圈,统一切换为沉稳光流 */
+.t-loading__gradient {
+ display: none !important;
+}
+.t-loading {
+ display: inline-flex !important;
+ flex-direction: column !important;
+ align-items: center !important;
+ justify-content: center !important;
+ gap: 12px !important;
+}
+
+.tn-drawer-loading-wrap {
+ min-height: max(420px, calc(100vh - 200px)) !important;
+ height: 100% !important;
+ width: 100% !important;
+ display: flex !important;
+ flex-direction: column !important;
+ align-items: center !important;
+ justify-content: center !important;
+}