@import 'tdesign-react/es/style/index.css'; @import '@fontsource-variable/plus-jakarta-sans'; /* TallyNote UX baseline: dense, calm, and keyboard-friendly surfaces. */ :root { font-family: "Plus Jakarta Sans Variable", "PingFang SC", "Microsoft YaHei", sans-serif; color: #1f2937; background: #f4f7fb; font-synthesis: none; text-rendering: optimizeLegibility; --tn-navy-950: #082f76; --tn-navy-900: #0b3a88; --tn-navy-800: #1556ad; --tn-blue-700: #175cd3; --tn-blue-100: #e8f0ff; --tn-surface: #ffffff; --tn-page: #f4f7fb; --tn-border: #dce3ec; --tn-border-subtle: #e7edf3; --tn-text: #172033; --tn-text-secondary: #475467; --tn-text-muted: #5b6575; --tn-success: #2f7d5c; --tn-warning: #805400; --tn-danger: #c93737; /* TDesign tokens kept on one deep-blue brand scale. */ --td-brand-color: #175cd3; --td-brand-color-1: #e8f0ff; --td-brand-color-2: #c9dcff; --td-brand-color-3: #9fbeff; --td-brand-color-4: #6f9ff0; --td-brand-color-5: #3d7be5; --td-brand-color-6: #2f6fe4; --td-brand-color-7: #175cd3; --td-brand-color-8: #1250bb; --td-brand-color-9: #0f429b; --td-brand-color-10: #082f76; --td-brand-color-hover: var(--td-brand-color-6); --td-brand-color-focus: var(--td-brand-color-2); --td-brand-color-active: var(--td-brand-color-8); --td-brand-color-disabled: var(--td-brand-color-3); --td-brand-color-light: var(--td-brand-color-1); --td-brand-color-light-hover: var(--td-brand-color-2); --td-mask-active: rgba(8, 47, 118, .34); --td-error-color: var(--tn-danger); --td-warning-color: var(--tn-warning); --td-success-color: var(--tn-success); --td-bg-color-page: var(--tn-page); --td-bg-color-container: var(--tn-surface); --td-text-color-primary: var(--tn-text); --td-text-color-secondary: var(--tn-text-secondary); --td-component-stroke: var(--tn-border); } * { box-sizing: border-box; } .tn-sr-only { position: absolute !important; width: 1px !important; height: 1px !important; padding: 0 !important; margin: -1px !important; overflow: hidden !important; clip: rect(0, 0, 0, 0) !important; white-space: nowrap !important; border: 0 !important; } /* The page owns scrolling in `.tn-content`; reserving a root scrollbar gutter would shrink the flex layout and make fixed notifications drift inward. */ html { min-width: 320px; height: 100%; overflow: hidden; } body { height: 100%; margin: 0; min-width: 320px; background: var(--tn-page); overflow: hidden; } button, input, textarea, select { font: inherit; } button, a { -webkit-tap-highlight-color: transparent; } button:focus-visible, a:focus-visible { outline: 2px solid #175cd3; outline-offset: 2px; } .t-dialog__close:focus-visible { border-radius: 3px; outline: 2px solid var(--td-brand-color); outline-offset: 2px; } /* Keep a single, inset focus indicator. TDesign already owns the field border, so an inset outline avoids the heavy second ring users see with the browser default while remaining visible to keyboard users. */ input:focus-visible, textarea:focus-visible, select:focus-visible { outline: 2px solid var(--td-brand-color); outline-offset: -2px; } /* TDesign resets focus-visible on its nested inputs with higher specificity. The wrapper owns the single visible indicator, so the native input does not draw a second rectangle inside it. */ .t-input :focus-visible, .t-textarea :focus-visible, .t-date-picker :focus-visible, .t-select-input :focus-visible { outline: 0 !important; } .t-input:has(:focus-visible), .t-textarea:has(:focus-visible), .t-date-picker:has(:focus-visible), .t-select-input:has(:focus-visible) { border-color: var(--td-brand-color) !important; box-shadow: inset 0 0 0 1px var(--td-brand-color) !important; } .t-input.t-is-focused, .t-input.t-input--focused, .t-textarea.t-is-focused, .t-textarea.t-textarea--focused, .t-date-picker.t-is-focused, .t-date-picker .t-input.t-is-focused, .t-select-input .t-input.t-input--focused { border-color: var(--td-brand-color) !important; box-shadow: none !important; -webkit-box-shadow: none !important; } .t-input:focus-within, .t-textarea:focus-within, .t-date-picker:focus-within, .t-select-input:focus-within { border-color: var(--td-brand-color) !important; } @media (forced-colors: active) { input:focus-visible, textarea:focus-visible, select:focus-visible { outline: 2px solid CanvasText; outline-offset: 1px; } } #root { height: 100%; min-height: 100vh; } .tn-route-error { display: grid; min-height: 100vh; place-items: center; padding: 24px; background: var(--tn-page); } .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; } /* ============================================================ 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 { top: 76px !important; right: 24px !important; z-index: 6000 !important; } @media (max-width: 768px) { .t-notification__show--top-right { top: 16px !important; right: 16px !important; left: 16px !important; width: auto !important; } } .tn-modal-error-banner { display: flex; align-items: center; gap: 10px; padding: 11px 16px; margin-bottom: 16px; border-radius: 6px; background: #fef2f2; border: 1px solid #fecaca; color: #991b1b; font-size: 13.5px; font-weight: 500; line-height: 1.4; } .tn-modal-error-banner svg { flex-shrink: 0; color: #dc2626; } /* 核心对齐修复:清除 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; } .tn-desktop-menu.is-hidden { width: 0; flex-basis: 0; border-right-width: 0; opacity: 0; pointer-events: none; } .tn-desktop-menu > .t-default-menu { width: 232px !important; height: 100%; min-height: 100%; border-right: 0; transition: width .22s ease; } .tn-desktop-menu.is-hidden > .t-default-menu { width: 0 !important; } .tn-desktop-menu > .t-default-menu .t-menu { width: 100% !important; overflow-x: hidden !important; overflow-y: auto; } .tn-desktop-menu .t-menu__logo, .tn-mobile-drawer .t-menu__logo { height: 64px; min-height: 64px; border-bottom: 1px solid var(--tn-border); border-top: 0; } .tn-layout-main { display: flex; height: 100%; min-width: 0; min-height: 0; flex: 1; flex-direction: column; overflow: hidden; } .tn-header { position: relative; z-index: 20; display: flex; align-items: center; justify-content: space-between; gap: 12px; height: 64px; flex: 0 0 64px; min-width: 0; padding: 0 24px; border-bottom: 1px solid var(--tn-border); background: rgba(255,255,255,.96); } .tn-header-leading, .tn-header-actions { min-width: 0; } .tn-header-leading { flex: 1 1 auto; } .tn-header-actions { flex: 0 1 auto; } .tn-header-menu-toggle { display: inline-flex; color: var(--tn-blue-700); } .tn-header-nav-label { display: none; min-width: 0; color: var(--tn-blue-700); font-size: 14px; font-weight: 650; white-space: nowrap; } .tn-header-user { display: inline-block; min-width: 0; max-width: 180px; overflow: hidden; color: var(--tn-text-secondary); text-overflow: ellipsis; white-space: nowrap; } .tn-user-menu-trigger { display: inline-flex; max-width: min(240px, 42vw); min-height: 40px; align-items: center; gap: 8px; padding: 4px 8px; border: 1px solid transparent; border-radius: 4px; color: var(--tn-text); } .tn-user-menu-trigger .t-button__text { display: inline-flex; min-width: 0; align-items: center; gap: 8px; } .tn-user-menu-trigger:hover, .tn-user-menu-trigger.t-is-hover { border-color: var(--tn-border); background: #f7f9fc; } .tn-user-menu-trigger:focus-visible { border-color: var(--td-brand-color-3); } .tn-user-menu-trigger .t-button__suffix { display: inline-flex; align-items: center; color: var(--tn-text-secondary); } .tn-user-avatar { flex: 0 0 32px; color: #fff; background: var(--tn-blue-700); font-size: 13px; font-weight: 700; } .tn-user-dropdown { min-width: 184px; padding: 4px; border: 1px solid var(--tn-border); border-radius: 4px; box-shadow: 0 12px 28px rgba(8, 47, 118, .16); } .tn-user-dropdown .t-dropdown__item { min-height: 38px; border-radius: 3px; } .tn-user-dropdown-button { display: block; width: 100%; min-height: 30px; padding: 0; border: 0; color: inherit; background: transparent; font: inherit; text-align: left; cursor: pointer; } .tn-user-dropdown-button:focus-visible { border-radius: 2px; outline: 2px solid var(--td-brand-color); outline-offset: 1px; } .tn-user-dropdown-identity { display: grid; gap: 3px; margin: 2px 4px 6px; padding: 8px 9px 10px; border-bottom: 1px solid var(--tn-border-subtle); } .tn-user-dropdown-identity strong { color: var(--tn-text); font-size: 13px; } .tn-user-dropdown-identity span { overflow: hidden; color: var(--tn-text-secondary); font-size: 12px; text-overflow: ellipsis; white-space: nowrap; } .tn-menu-logo { /* TDesign adds a left margin to every direct logo child. The logo owns its full-width centering, so that default inset makes the wordmark look visibly shifted to the right in both expanded and collapsed menus. */ display: flex; width: 100%; height: 64px; margin-left: 0 !important; align-items: center; justify-content: center; color: var(--tn-navy-900); } .tn-logo-full { font-size: 18px; font-weight: 750; letter-spacing: .01em; } .tn-logo-short { color: var(--tn-blue-700); font-size: 16px; font-weight: 800; letter-spacing: .04em; } .tn-menu-icon { flex: 0 0 20px; width: 20px; height: 20px; margin-right: 10px; } .tn-desktop-menu .t-menu__item, .tn-mobile-drawer .t-menu__item { width: 100%; column-gap: 0; } .tn-desktop-menu .t-menu__item .tn-menu-icon, .tn-mobile-drawer .t-menu__item .tn-menu-icon { margin-right: 10px; } .tn-desktop-menu .t-menu__item.t-is-active:not(.t-is-opened), .tn-mobile-drawer .t-menu__item.t-is-active:not(.t-is-opened) { background: var(--td-brand-color-1); color: var(--td-brand-color); } .tn-desktop-menu .t-menu__item.t-is-active:not(.t-is-opened) .t-icon, .tn-mobile-drawer .t-menu__item.t-is-active:not(.t-is-opened) .t-icon { color: var(--td-brand-color); } .tn-desktop-menu .t-menu--collapsed .tn-menu-icon { margin-right: 0; } .tn-content { min-width: 0; min-height: 0; flex: 1; overflow-x: hidden; overflow-y: auto; background: var(--tn-page); } .tn-mobile-drawer { display: none; } .tn-mobile-drawer .t-drawer__body { padding: 0; } .tn-mobile-drawer-header { display: flex; min-height: 48px; align-items: center; justify-content: space-between; gap: 8px; color: var(--tn-text); font-size: 14px; font-weight: 700; } .tn-mobile-drawer-header .t-button { color: var(--tn-text-secondary); } .tn-mobile-menu-shell { height: 100%; } .tn-mobile-drawer .t-default-menu { width: 216px !important; min-height: 100%; } .tn-mobile-drawer .t-default-menu .t-menu { width: 100% !important; min-height: 100%; border-right: 0; overflow-x: hidden !important; } .tn-shell { min-height: 100vh; background: var(--tn-page); } .tn-content { min-width: 0; padding: 28px 32px 40px; } .tn-content-inner { width: min(1480px, 100%); margin: 0 auto; } .tn-page { min-width: 0; } .tn-page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; margin-bottom: 20px; } .tn-eyebrow { margin-bottom: 4px; color: var(--tn-text-secondary); font-size: 12px; letter-spacing: .02em; } .tn-page-title { margin: 0; color: var(--tn-text); font-size: 26px; line-height: 1.2; font-weight: 700; } .tn-page-subtitle { margin: 7px 0 0; color: var(--tn-text-secondary); font-size: 13px; } .tn-page-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; } .tn-page-actions .t-button, .tn-toolbar .t-button { min-height: 36px; } .tn-flat-section { border: 1px solid var(--tn-border); border-radius: 4px; background: var(--tn-surface); } .tn-toolbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 12px; border: 1px solid var(--tn-border); border-radius: 4px; background: var(--tn-surface); } .tn-expense-month-controls, .tn-expense-search-controls, .tn-expense-filter-actions { display: flex; min-width: 0; align-items: center; gap: 8px; } .tn-expense-month-controls .tn-month-picker { width: 150px; min-width: 0; } .tn-expense-search-controls { min-width: 280px; flex: 1 1 340px; } .tn-expense-search-controls .tn-expense-search { min-width: 0; flex: 1; } .tn-expense-filter-actions { flex: 0 0 auto; } .tn-audit-toolbar { display: grid; grid-template-columns: minmax(260px, 1fr) minmax(150px, 190px) auto; align-items: center; } .tn-audit-toolbar > .t-input__wrap, .tn-audit-toolbar > .t-select__wrap { width: auto; min-width: 0; } .tn-audit-toolbar > .t-input__wrap { min-width: 0; } .tn-table-wrap { overflow: hidden; border: 1px solid var(--tn-border); border-radius: 4px; background: var(--tn-surface); } .tn-table-wrap .t-table { font-variant-numeric: tabular-nums; } .tn-summary { display: flex; align-items: baseline; gap: 16px; padding: 16px 2px 12px; color: var(--tn-text-secondary); } .tn-summary strong { color: var(--tn-text); font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; } .tn-summary .t-button { margin-left: auto; } .tn-amount, .tn-code { font-variant-numeric: tabular-nums; font-family: "Plus Jakarta Sans Variable", monospace; } .tn-amount { color: var(--tn-text); font-weight: 700; white-space: nowrap; } .tn-muted { color: var(--tn-text-muted); } .tn-note { display: block; max-width: 340px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .tn-status { display: inline-flex; align-items: center; min-height: 24px; padding: 2px 8px; border-radius: 999px; font-size: 12px; font-weight: 600; white-space: nowrap; } .tn-status-unreimbursed { color: var(--tn-warning); background: #fff7e6; } .tn-status-reimbursed { color: var(--tn-success); background: #eaf7ef; } .tn-status-disabled { color: var(--tn-text-secondary); background: #eef1f5; } .tn-missing { color: var(--tn-danger); font-size: 12px; } .tn-action-group { display: inline-flex; align-items: center; gap: 2px; } .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; } /* 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; } .tn-selection .t-button { margin-left: auto; } .tn-auth-shell { display: grid; min-height: 100vh; place-items: center; padding: 24px; background: var(--tn-page); } .tn-auth-panel { width: min(420px, 100%); padding: 38px 36px; border: 1px solid var(--tn-border); border-radius: 4px; background: var(--tn-surface); box-shadow: 0 14px 36px rgba(11, 58, 136, .08); } .tn-login-page { position: relative; z-index: 0; display: flex; height: 100vh; min-height: 100svh; flex-direction: column; overflow-x: hidden; overflow-y: auto; color: var(--tn-text); background-color: #f5f9ff; background-image: url("../assets/login-background-tech.webp"); background-position: center center; background-size: cover; animation: tn-auth-page-in .24s ease-out both; } .tn-login-page::before { position: absolute; z-index: 0; inset: 0; background: linear-gradient(90deg, rgba(247, 250, 255, .9) 0%, rgba(247, 250, 255, .72) 38%, rgba(247, 250, 255, .16) 72%, rgba(247, 250, 255, 0) 100%); content: ""; pointer-events: none; } .tn-login-header { position: relative; z-index: 1; display: flex; height: 64px; flex: 0 0 64px; align-items: center; justify-content: space-between; padding: 0 24px; border-bottom: 1px solid rgba(23, 92, 211, .18); background: rgba(255, 255, 255, .68); backdrop-filter: blur(8px); } .tn-login-brand-group { display: flex; min-width: 0; align-items: baseline; gap: 14px; } .tn-login-wordmark { color: var(--tn-navy-900); font-size: 19px; font-weight: 750; letter-spacing: .01em; white-space: nowrap; } .tn-login-environment { color: var(--tn-text-secondary); font-size: 13px; white-space: nowrap; } .tn-login-operations { color: var(--tn-text-secondary); } .tn-login-operation { color: var(--tn-text-secondary); } .tn-login-operation:hover { color: var(--td-brand-color); background: var(--td-brand-color-1); } .tn-login-container { position: absolute; z-index: 1; top: 22%; left: 5%; min-height: 500px; line-height: 22px; } .tn-login-heading { margin-bottom: 0; } .tn-login-title { margin: 4px 0 0; color: var(--tn-navy-950); font-size: 36px; font-weight: 700; line-height: 44px; } .tn-login-title-brand { color: var(--tn-blue-700); } .tn-login-subtitle { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 16px; color: var(--tn-text-secondary); font-size: 14px; } .tn-login-subtitle-divider { color: var(--tn-text-muted); } .tn-login-form { width: 400px; max-width: calc(100vw - 48px); margin-top: 48px; } .tn-login-form .t-form__item { margin-bottom: 16px; } .tn-login-form .t-input { border-color: var(--tn-border); background: rgba(255, 255, 255, .96); } .tn-login-form .t-input:hover { border-color: var(--td-brand-color-5); } .tn-login-form .t-input.t-is-focused { border-color: var(--td-brand-color); box-shadow: none; } .tn-login-form .t-input__suffix { display: inline-flex; align-items: center; gap: 4px; } .tn-login-suffix-actions { display: inline-flex; align-items: center; gap: 3px; } .tn-login-suffix-placeholder { display: none; } .tn-login-clear { display: inline-flex; width: 22px; height: 22px; align-items: center; justify-content: center; padding: 0; border: 0; border-radius: 3px; color: var(--tn-text-muted); background: transparent; cursor: pointer; } .tn-login-clear:hover { color: var(--td-brand-color); background: var(--td-brand-color-1); } .tn-login-alert { margin-bottom: 14px; border: 1px solid currentColor; border-left-width: 1px; border-radius: 4px; background: rgba(255, 255, 255, .9); } .tn-login-options { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 0 0 10px; color: var(--tn-text-secondary); font-size: 14px; } .tn-login-options .t-checkbox { flex: 0 0 auto; } .tn-login-options > span { color: var(--tn-text-secondary); white-space: nowrap; } .tn-login-submit { margin-top: 48px; margin-bottom: 0 !important; } .tn-login-note { margin-top: 24px; color: var(--tn-text-secondary); font-size: 12px; } .tn-login-note .t-typography { color: inherit; font-size: inherit; } .tn-login-dot { width: 6px; height: 6px; flex: 0 0 6px; border-radius: 50%; background: var(--tn-blue-700); } .tn-login-input-icon, .tn-login-prefix-icon { color: var(--tn-text-secondary); } .tn-login-password-toggle { display: inline-flex; width: 24px; height: 24px; align-items: center; justify-content: center; padding: 0; border: 0; border-radius: 3px; color: var(--tn-text-secondary); background: transparent; cursor: pointer; } .tn-login-password-toggle:hover { color: var(--td-brand-color); background: var(--td-brand-color-1); } .tn-login-password-toggle:focus-visible { outline: 2px solid var(--td-brand-color-3); outline-offset: 1px; } .tn-login-footer { position: absolute; z-index: 1; bottom: 64px; left: 5%; color: var(--tn-text-secondary); font-size: 14px; } .tn-dialog-note { margin: 12px 0 0; color: var(--tn-text-secondary); font-size: 13px; } .tn-password-container { width: min(920px, calc(100vw - 10%)); margin-top: clamp(76px, 16vh, 150px); } .tn-password-page .tn-password-card { max-width: 920px; margin: 4px auto 0; } .tn-password-card { overflow: hidden; border: 1px solid var(--tn-border); border-radius: 4px; background: var(--tn-surface); box-shadow: 0 10px 26px rgba(11, 58, 136, .07); } .tn-password-card-head { display: flex; align-items: flex-start; gap: 12px; padding: 22px 24px 18px; border-bottom: 1px solid var(--tn-border-subtle); } .tn-password-card-icon { display: inline-grid; width: 38px; height: 38px; flex: 0 0 38px; place-items: center; border: 1px solid var(--td-brand-color-2); border-radius: 4px; color: var(--td-brand-color); background: var(--td-brand-color-1); } .tn-password-card-head h2 { margin: 0; color: var(--tn-text); font-size: 19px; line-height: 1.3; } .tn-password-card-head p { margin: 5px 0 0; color: var(--tn-text-secondary); font-size: 13px; line-height: 1.45; } .tn-password-card-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(220px, .7fr); gap: 28px; padding: 22px 24px 24px; } .tn-password-form { width: 100%; margin: 0; } .tn-password-form .t-form__item { margin-bottom: 16px; } .tn-password-form .t-form__item:last-child { margin-bottom: 0; } .tn-password-form:not(.t-form-inline) .t-form__item--last { margin: 0 0 16px; } .tn-password-form:not(.t-form-inline) > .t-form__item.tn-password-submit { margin-top: 28px; } .tn-password-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; } .tn-password-actions .tn-password-submit-button { min-width: 112px; } .tn-password-alert { margin: 16px 24px 0; } .tn-password-guidance { align-self: start; padding: 16px; border: 1px solid var(--tn-border-subtle); border-radius: 4px; background: #f8fafc; } .tn-password-guidance-title { display: flex; align-items: center; gap: 7px; color: var(--tn-navy-900); font-size: 13px; font-weight: 700; } .tn-password-guidance > p { margin: 9px 0 12px; color: var(--tn-text-secondary); font-size: 12px; line-height: 1.5; } .tn-password-guidance ul { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; } .tn-password-guidance li { display: flex; align-items: center; gap: 7px; color: var(--tn-text-secondary); font-size: 12px; } .tn-password-guidance li svg { color: var(--tn-text-muted); } .tn-password-guidance li.is-valid { color: var(--tn-success); } .tn-password-guidance li.is-valid svg { color: var(--tn-success); } .tn-file-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; padding: 7px 9px; border: 1px solid var(--tn-border-subtle); border-radius: 3px; background: #f8fafc; } .tn-file-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .tn-file-name small { margin-left: 6px; color: var(--tn-text-muted); } .tn-detail-amount { margin: 0 0 10px; color: var(--tn-navy-900); font-size: 32px; font-weight: 700; font-variant-numeric: tabular-nums; } .tn-detail-note { white-space: pre-wrap; word-break: break-word; } .tn-preview { display: grid; min-height: 300px; max-height: 68vh; place-items: center; overflow: auto; background: #f2f5f9; border-radius: 3px; } .tn-preview img { display: block; max-width: 100%; max-height: 64vh; object-fit: contain; } .tn-preview iframe { width: 100%; height: min(64vh, calc(100dvh - 150px)); min-height: 240px; border: 0; background: #fff; } .tn-section-title { margin: 20px 0 12px; padding-top: 18px; border-top: 1px solid var(--tn-border-subtle); color: var(--tn-text); font-size: 14px; font-weight: 700; } .tn-update-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-bottom: 14px; } .tn-update-block { padding: 0; } .tn-update-block .t-card__body { display: grid; grid-template-columns: auto 1fr; align-items: center; column-gap: 10px; row-gap: 3px; padding: 18px; } .tn-update-block .t-card__body > svg { grid-row: span 3; color: var(--tn-blue-700); } .tn-update-value { color: var(--tn-navy-900); font-size: 23px; font-weight: 700; font-variant-numeric: tabular-nums; } .tn-update-release { padding: 0; margin-bottom: 14px; } .tn-update-release .t-card__body { padding: 20px; } .tn-update-release-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; } .tn-update-release h2 { margin: 3px 0 5px; color: var(--tn-text); font-size: 21px; } .tn-release-notes { margin: 16px 0; padding: 12px 14px; border-left: 3px solid var(--td-brand-color-3); background: #f7f9fc; color: var(--tn-text-secondary); font-size: 13px; line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; } .tn-release-notes .tn-eyebrow { display: block; margin-bottom: 4px; color: var(--tn-navy-900); } .tn-facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin: 18px 0; padding: 14px 0; border-top: 1px solid var(--tn-border-subtle); border-bottom: 1px solid var(--tn-border-subtle); } .tn-facts span { display: block; margin-bottom: 4px; color: var(--tn-text-secondary); font-size: 12px; } .tn-facts strong { overflow-wrap: anywhere; color: #344054; font-size: 14px; } .tn-chart-section { margin-top: 14px; padding: 18px; } .tn-chart-title { margin: 0 0 4px; color: var(--tn-text); font-size: 14px; font-weight: 700; } .tn-chart-subtitle { margin: 0 0 12px; color: var(--tn-text-secondary); font-size: 12px; } .tn-dashboard-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin-bottom: 14px; } .tn-dashboard-stat { min-width: 0; transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease; } .tn-dashboard-stat:hover { border-color: var(--td-brand-color-3); box-shadow: 0 8px 20px rgba(23, 92, 211, .08); transform: translateY(-1px); } .tn-dashboard-stat .t-card__body { display: flex; min-height: 112px; align-items: center; gap: 12px; padding: 18px; } .tn-dashboard-stat .t-card__body { justify-content: space-between; } .tn-dashboard-stat .t-statistic__content { font-weight: 700; } .tn-dashboard-stat-icon { display: inline-grid; width: 38px; height: 38px; flex: 0 0 38px; place-items: center; border: 1px solid var(--td-brand-color-2); border-radius: 4px; color: var(--td-brand-color); background: var(--td-brand-color-1); } .tn-dashboard-stat .t-statistic { min-width: 0; } .tn-dashboard-stat .t-statistic__title { margin-bottom: 5px; color: var(--tn-text-secondary); font-size: 12px; } .tn-dashboard-stat .t-statistic__content { color: var(--tn-text); font-family: "Plus Jakarta Sans Variable", sans-serif; font-size: 23px; font-variant-numeric: tabular-nums; } .tn-dashboard-grid { display: grid; grid-template-columns: minmax(0, 1.65fr) minmax(280px, .85fr); gap: 14px; margin-bottom: 14px; } .tn-dashboard-chart, .tn-dashboard-progress, .tn-dashboard-recent { min-width: 0; } .tn-dashboard-card-title { display: grid; min-width: 0; gap: 3px; } .tn-dashboard-card-title > span { color: var(--tn-text); font-weight: 600; line-height: 1.25; } .tn-dashboard-card-title > small { color: var(--tn-text-secondary); font-size: 12px; font-weight: 400; line-height: 1.35; } .tn-dashboard-chart .t-card__body { min-height: 300px; padding: 12px 18px 18px; } .tn-dashboard-chart .echarts-for-react { min-width: 0; } .tn-dashboard-chart-empty { display: flex; min-height: 286px; flex-direction: column; align-items: center; justify-content: center; gap: 6px; color: var(--tn-text-secondary); text-align: center; } .tn-dashboard-chart-empty span { font-size: 14px; font-weight: 600; } .tn-dashboard-chart-empty small { color: var(--tn-text-muted); font-size: 12px; } .tn-dashboard-progress .t-card__body { display: flex; min-height: 300px; flex-direction: column; align-items: center; justify-content: center; padding: 18px; } .tn-progress-ring { display: grid; width: 176px; height: 176px; flex: 0 0 176px; place-items: center; border-radius: 50%; transition: background .35s ease; } .tn-progress-ring > div { display: flex; width: 128px; height: 128px; flex-direction: column; align-items: center; justify-content: center; border-radius: 50%; background: var(--tn-surface); box-shadow: inset 0 0 0 1px var(--tn-border-subtle); } .tn-progress-ring strong { color: var(--tn-navy-900); font-family: "Plus Jakarta Sans Variable", sans-serif; font-size: 28px; line-height: 1.1; font-variant-numeric: tabular-nums; } .tn-progress-ring span { margin-top: 5px; color: var(--tn-text-secondary); font-size: 12px; } .tn-dashboard-progress-legend { display: grid; width: min(260px, 100%); gap: 8px; margin-top: 18px; } .tn-dashboard-progress-legend > span { display: flex; align-items: center; gap: 7px; color: var(--tn-text-secondary); font-size: 12px; } .tn-dashboard-progress-legend i { display: inline-block; width: 8px; height: 8px; flex: 0 0 8px; border-radius: 2px; } .tn-dashboard-progress-legend i.is-blue { background: var(--tn-blue-700); } .tn-dashboard-progress-legend i.is-green { background: var(--tn-success); } .tn-dashboard-progress-legend strong { margin-left: auto; color: var(--tn-text); font-family: "Plus Jakarta Sans Variable", sans-serif; font-variant-numeric: tabular-nums; } .tn-dashboard-recent { margin-bottom: 14px; } .tn-dashboard-recent .t-card__body { padding: 0; } .tn-dashboard-table { border: 0; border-radius: 0; } .tn-dashboard-table .t-table { min-width: 620px; } .tn-dashboard-actions { display: flex; align-items: center; gap: 8px; } .tn-dashboard-month-control, .tn-dashboard-secondary-actions { display: flex; align-items: center; gap: 8px; } .tn-dashboard-month-control .t-date-picker { height: 36px; } .tn-dashboard-month-control button.t-button { width: 36px; height: 36px; min-width: 36px; min-height: 36px; } .tn-dashboard-month-control .tn-dashboard-month { width: 148px; flex: 0 1 148px; } .tn-dashboard-secondary-actions .tn-dashboard-refresh, .tn-dashboard-secondary-actions .tn-dashboard-view { flex: 0 0 auto; } .tn-layout { animation: tn-app-enter .24s ease-out both; } .tn-page-transition { animation: tn-page-in .14s cubic-bezier(0.16, 1, 0.3, 1) both; will-change: opacity, transform; } .tn-page-actions .t-button { min-height: 36px; } .expenses-toolbar { display: flex; align-items: center; gap: 8px; } .expenses-toolbar .t-button--shape-square { width: 36px; height: 36px; min-width: 36px; min-height: 36px; } .tn-month-picker { width: 148px; } .tn-segmented { display: inline-flex; align-items: center; min-height: 36px; } .tn-segmented .t-radio-button { min-width: 76px; height: 32px; min-height: 32px; padding: 0 16px; line-height: 22px; } .tn-segmented .t-radio-button.t-is-checked { background: var(--td-brand-color); border-color: var(--td-brand-color); color: #fff; } .tn-expense-search { flex: 1 1 260px; min-width: 190px; } .expenses-head { margin-bottom: 16px; } .tn-table-wrap { min-width: 0; overflow-x: auto; } .tn-table-wrap .t-table { min-width: 780px; } .tn-audit-table .tn-code { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; } .tn-alert { margin: 12px 0; } .tn-inline-loading { display: flex; align-items: center; gap: 7px; min-height: 32px; margin: 0 0 10px; color: var(--tn-text-secondary); font-size: 12px; } .tn-inline-error, .tn-inline-info { display: flex; align-items: center; gap: 7px; margin-top: 10px; padding: 9px 11px; border-radius: 3px; font-size: 13px; } .tn-inline-error { color: #a33a3a; background: #fff0f0; } .tn-inline-info { color: #246044; background: #eaf7ef; } .tn-restart-countdown { margin-top: 10px; color: var(--tn-warning); font-size: 12px; font-variant-numeric: tabular-nums; } .tn-update-explainer { display: flex; align-items: flex-start; gap: 10px; margin: 0 0 14px; padding: 13px 15px; border: 1px solid var(--td-brand-color-2); border-radius: 4px; color: var(--tn-navy-900); background: var(--td-brand-color-1); } .tn-update-explainer > svg { flex: 0 0 auto; margin-top: 1px; color: var(--td-brand-color); } .tn-update-explainer strong { display: block; font-size: 13px; } .tn-update-explainer p { margin: 5px 0 0; color: var(--tn-text-secondary); font-size: 12px; line-height: 1.55; } .tn-secret { display: flex; align-items: center; gap: 10px; } .tn-secret code { flex: 1; min-width: 0; padding: 10px 12px; border: 1px solid var(--tn-border); border-radius: 3px; background: #f7f9fc; color: var(--tn-navy-900); font-family: "Plus Jakarta Sans Variable", monospace; font-size: 16px; overflow-wrap: anywhere; } .tn-table-more { display: flex; justify-content: center; padding: 16px 0; } .tn-update-block small { color: var(--tn-text-secondary); } .tn-progress { height: 7px; margin: 18px 0 10px; overflow: hidden; border-radius: 999px; background: #e8edf3; } .tn-progress span { display: block; height: 100%; border-radius: inherit; background: var(--tn-blue-700); transition: width .35s ease; } .text-success { color: var(--tn-success); } .text-danger { color: var(--tn-danger); } .expense-form { display: flex; flex-direction: column; gap: 16px; } .tn-form-field { display: flex; flex-direction: column; gap: 7px; color: var(--tn-text); font-size: 13px; font-weight: 600; } .tn-form-field > small { color: var(--tn-text-secondary); font-size: 12px; font-weight: 400; } .tn-field-error { color: var(--tn-danger); font-size: 12px; font-weight: 400; } .tn-form-field .t-input, .tn-form-field .t-textarea, .tn-form-field .t-date-picker { width: 100%; } .invoice-missing-toggle { display: inline-flex; align-items: center; gap: 7px; color: var(--tn-text); font-size: 13px; } .tn-form-help { display: block; margin-top: -8px; color: var(--tn-text-secondary); font-size: 12px; } .expense-file-list { display: flex; flex-direction: column; gap: 6px; margin: -8px 0 0; padding: 0; list-style: none; } .expense-file-list li { display: flex; align-items: center; gap: 7px; min-width: 0; padding: 7px 9px; border: 1px solid var(--tn-border-subtle); border-radius: 3px; background: #f8fafc; color: var(--tn-text); font-size: 12px; } .expense-file-list li small { margin-left: auto; color: var(--tn-text-muted); } .expense-file-list li .t-button { flex: 0 0 auto; } .expense-error { display: flex; align-items: flex-start; gap: 7px; padding: 9px 11px; border-radius: 3px; color: var(--tn-danger); background: #fff0f0; font-size: 13px; } .tn-export-status { display: flex; align-items: center; gap: 8px; padding: 9px 11px; border: 1px solid var(--td-brand-color-2); border-radius: 3px; color: var(--tn-blue-700); background: var(--td-brand-color-1); font-size: 13px; } .tn-export-status span { flex: 1; min-width: 0; } .expense-detail { display: flex; flex-direction: column; gap: 14px; } .expense-detail-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; } .expense-detail-head > strong { color: var(--tn-navy-900); font-family: "Plus Jakarta Sans Variable", monospace; font-size: 30px; font-variant-numeric: tabular-nums; } .expense-detail dl { display: grid; gap: 10px; margin: 0; } .expense-detail dl > div { display: grid; grid-template-columns: 82px minmax(0, 1fr); gap: 10px; align-items: start; } .expense-detail dt { color: var(--tn-text-secondary); font-size: 12px; } .expense-detail dd { margin: 0; color: var(--tn-text); font-size: 13px; word-break: break-word; } .expense-detail h3 { display: flex; align-items: baseline; gap: 7px; margin: 10px 0 0; padding-top: 16px; border-top: 1px solid var(--tn-border-subtle); color: var(--tn-text); font-size: 14px; } .expense-detail h3 small { color: var(--tn-text-muted); font-size: 12px; font-weight: 400; } .expense-attachments { display: flex; flex-direction: column; gap: 6px; } .expense-attachment { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; padding: 8px 9px; border: 1px solid var(--tn-border-subtle); border-radius: 3px; background: #f8fafc; } .expense-attachment > span { display: flex; align-items: center; gap: 7px; min-width: 0; color: var(--tn-text); font-size: 12px; } .expense-attachment > span small { color: var(--tn-text-muted); white-space: nowrap; } .expense-attachment > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .expense-timeline { display: flex; flex-direction: column; gap: 8px; } .expense-timeline > div { display: grid; grid-template-columns: 155px minmax(0, 1fr) 90px; gap: 8px; align-items: baseline; padding: 8px 0; border-bottom: 1px solid var(--tn-border-subtle); font-size: 12px; } .expense-timeline span, .expense-timeline small { color: var(--tn-text-secondary); } .expense-timeline strong, .expense-timeline small { min-width: 0; overflow-wrap: anywhere; word-break: break-word; } .expense-timeline strong { color: var(--tn-text); font-family: "Plus Jakarta Sans Variable", monospace; font-size: 12px; } .tn-spin, .spin { animation: tn-spin .9s linear infinite; } @keyframes tn-spin { to { transform: rotate(360deg); } } @keyframes tn-page-in { from { opacity: 0.88; transform: translateY(2px); } to { opacity: 1; transform: translateY(0); } } @keyframes tn-app-enter { from { opacity: 0; } to { opacity: 1; } } @keyframes tn-auth-page-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } } .t-dialog { border: 1px solid var(--tn-border); border-radius: 4px; box-shadow: 0 18px 42px rgba(8, 47, 118, .18); width: 560px; max-width: calc(100vw - 32px); } @media (min-width: 901px) { .t-dialog { width: 580px; } .t-dialog.tn-dialog-medium { width: 680px !important; } .t-dialog.tn-dialog-large { width: 820px !important; } .t-dialog.tn-dialog-xlarge { width: 960px !important; } } .tn-queued-runtime-notice { background: var(--tn-surface); border: 1px solid var(--tn-border); border-radius: 4px; padding: 12px 14px; margin-top: 12px; } .tn-queued-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 4px; font-weight: 500; color: var(--tn-navy-900); } .tn-queued-header span { font-size: 13.5px; } /* TDesign Dialog global no-icon & pure baseline typography normalization */ .t-dialog__header .t-icon:not(.t-icon-close), .t-dialog__body .t-icon, .t-dialog .t-icon.t-is-info, .t-dialog .t-icon.t-is-success, .t-dialog .t-icon.t-is-warning, .t-dialog .t-icon.t-is-error { display: none !important; } .t-dialog__header { font-size: 16px; font-weight: 600; color: var(--tn-navy-900); line-height: 1.4; margin-bottom: 8px; gap: 0 !important; } .t-dialog__header-content { display: block !important; width: 100%; } .t-dialog__body { font-size: 13.5px; line-height: 1.65; color: var(--tn-text); padding: 8px 0 20px 0; } .t-dialog__mask { background: var(--td-mask-active) !important; } .t-dialog__footer .t-button { min-width: 76px; } @media (max-width: 900px) { .tn-desktop-menu { display: none; } .tn-header { padding: 0 16px; } .tn-header-menu-toggle { display: inline-flex; } .tn-header-nav-label { display: inline-block; } .tn-mobile-drawer { display: block; } .tn-content { padding: 20px 16px 30px; } .tn-page-head { flex-direction: column; } .tn-page-actions { width: 100%; justify-content: flex-start; } .tn-audit-toolbar { grid-template-columns: minmax(0, 1fr); } .tn-dashboard-actions { width: 100%; justify-content: flex-start; } .tn-dashboard-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } .tn-dashboard-grid { grid-template-columns: minmax(0, 1fr); } .tn-password-card-body { grid-template-columns: minmax(0, 1fr); gap: 20px; } .tn-password-guidance { order: 2; } .tn-update-release .tn-page-actions { justify-content: flex-start; } .expenses-toolbar { align-items: stretch; } .expenses-toolbar .tn-expense-search { flex-basis: 100%; } .tn-update-grid { grid-template-columns: 1fr; } .tn-login-header { padding: 0 24px; } .tn-login-container { left: 24px; } .tn-login-footer { left: 24px; } } @media (min-width: 901px) { .tn-login-container.tn-password-container { /* The first-login form can grow beyond a short desktop viewport. Keep it in normal flow so the login canvas owns the scroll instead of clipping an absolutely positioned card. */ position: relative; top: auto; left: auto; min-height: 0; margin: clamp(40px, 10vh, 88px) 5% 64px; } } @media (min-width: 561px) and (max-width: 900px) { .tn-login-page { height: auto; min-height: 100svh; } .tn-login-container, .tn-password-container { position: relative; top: auto; left: auto; width: min(520px, calc(100% - 48px)); min-height: 0; margin: clamp(52px, 10vh, 96px) 24px 72px; } .tn-login-title { font-size: 32px; line-height: 40px; } .tn-login-form { width: 100%; max-width: 100%; } .tn-login-footer { display: none; } } @media (max-width: 560px) { .tn-content-drawer .t-drawer__content-wrapper { width: 100vw !important; max-width: 100vw; } .tn-mobile-drawer .t-drawer__content-wrapper { width: 216px !important; max-width: 216px; } .t-drawer__body { min-width: 0; overflow-x: hidden; } .tn-auth-panel { padding: 30px 22px; } .tn-password-page .tn-password-card { margin-top: 0; } .tn-password-card-head { padding: 18px 16px 15px; } .tn-password-card-body { gap: 16px; padding: 18px 16px 20px; } .tn-password-alert { margin: 14px 16px 0; } .tn-password-actions { justify-content: stretch; } .tn-password-actions .t-button { flex: 1 1 0; min-width: 0; } .tn-password-actions .tn-password-submit-button { width: 100%; min-width: 112px; } .tn-password-guidance { padding: 14px; } .tn-page-title { font-size: 23px; } .tn-page-actions .t-button { flex: 0 1 auto; min-width: 0; } .expenses-head .tn-page-actions { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; width: 100%; } .expenses-head .tn-page-actions > .t-checkbox { grid-column: 1 / -1; } .expenses-head .tn-page-actions > .t-button { width: 100%; min-width: 0; flex: none; } .tn-dashboard-actions { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); width: 100%; gap: 8px; } .tn-dashboard-month-control { display: grid; grid-column: 1 / -1; grid-template-columns: 36px minmax(0, 1fr) 36px; width: 100%; gap: 8px; } .tn-dashboard-month-control .tn-dashboard-month { width: 100%; min-width: 0; flex: none; } .tn-dashboard-secondary-actions { display: grid; grid-column: 1 / -1; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; } .tn-dashboard-secondary-actions .tn-dashboard-refresh, .tn-dashboard-secondary-actions .tn-dashboard-view { width: 100%; min-width: 0; flex: none; } .tn-dashboard-stats { grid-template-columns: minmax(0, 1fr); } .tn-dashboard-stat .t-card__body { min-height: 92px; } .tn-dashboard-chart .t-card__body, .tn-dashboard-progress .t-card__body { min-height: 270px; } .tn-facts { grid-template-columns: 1fr; gap: 10px; } .tn-update-release { padding: 0; } .tn-update-release .t-card__body { padding: 16px; } .tn-update-release-head { flex-direction: column; } .expenses-toolbar { display: grid; grid-template-columns: minmax(0, 1fr); } .expenses-toolbar .tn-segmented, .expenses-toolbar .tn-expense-month-controls, .expenses-toolbar .tn-expense-search-controls, .expenses-toolbar .tn-expense-filter-actions { width: 100%; min-width: 0; } .expenses-toolbar .tn-segmented { display: flex; } .expenses-toolbar .tn-segmented .t-radio-button { min-width: 0; flex: 1 1 50%; } .expenses-toolbar .tn-segmented .t-radio-button__label { display: flex; justify-content: center; } .tn-expense-month-controls { display: grid; grid-template-columns: 36px minmax(0, 1fr) 36px; } .tn-expense-month-controls .tn-month-picker { width: 100%; } .tn-expense-search-controls { display: grid; grid-template-columns: minmax(0, 1fr) auto; } .tn-expense-filter-actions { justify-content: space-between; } .expense-timeline > div { grid-template-columns: minmax(0, 1fr) minmax(84px, 34%); gap: 4px 8px; align-items: start; } .expense-timeline > div > span { grid-column: 1 / -1; } .expense-timeline > div > strong { white-space: normal; } .expense-timeline > div > small { max-width: none; text-align: right; white-space: normal; } .tn-login-page { min-height: 100svh; background-position: 38% center; overflow-y: auto; } .tn-login-page::before { background: linear-gradient(180deg, rgba(247, 250, 255, .94) 0%, rgba(247, 250, 255, .82) 54%, rgba(247, 250, 255, .42) 100%); } .tn-login-header { padding: 0 20px; } .tn-login-environment { display: none; } .tn-login-container, .tn-password-container { position: relative; top: auto; left: auto; width: calc(100% - 32px); min-height: 0; margin: 48px 16px 56px; } .tn-login-title { font-size: 29px; line-height: 36px; } .tn-login-form { width: 100%; max-width: 100%; } .tn-login-subtitle { gap: 5px; } .tn-login-footer { display: none; } .tn-header { gap: 8px; padding: 0 10px; } .tn-header-leading { gap: 4px !important; } .tn-header-actions { gap: 2px !important; } .tn-header-user { max-width: 72px; font-size: 12px; } .tn-header-actions .t-button { width: 36px; height: 36px; min-height: 36px; flex: 0 0 36px; } .tn-header-actions .tn-user-menu-trigger { width: auto; max-width: 168px; flex: 0 1 auto; padding-right: 5px; padding-left: 5px; } .tn-header-actions .tn-user-menu-trigger .t-button__suffix { display: none; } .tn-header-actions .tn-user-menu-trigger .tn-user-avatar { width: 30px; height: 30px; flex-basis: 30px; } .tn-header-actions .tn-user-menu-trigger .tn-header-user { max-width: 92px; } .tn-update-release .tn-page-actions { width: 100%; } .tn-update-release .tn-page-actions .t-button { width: 100%; } .tn-table-wrap:not(.tn-dashboard-table):not(.tn-audit-table) .t-table th:first-child, .tn-table-wrap:not(.tn-dashboard-table):not(.tn-audit-table) .t-table td:first-child { position: sticky; left: 0; z-index: 2; background: var(--tn-surface); box-shadow: 1px 0 0 var(--tn-border-subtle); } .tn-table-wrap:not(.tn-dashboard-table):not(.tn-audit-table) .t-table thead th:first-child { z-index: 3; } .tn-table-wrap:not(.tn-dashboard-table):not(.tn-audit-table) .t-table th:last-child, .tn-table-wrap:not(.tn-dashboard-table):not(.tn-audit-table) .t-table td:last-child { position: sticky; right: 0; z-index: 2; background: var(--tn-surface); box-shadow: -1px 0 0 var(--tn-border-subtle); } .tn-table-wrap:not(.tn-dashboard-table):not(.tn-audit-table) .t-table thead th:last-child { z-index: 3; } .tn-login-header { backdrop-filter: none; } } @media (max-width: 560px) { .tn-preview { min-height: 0; max-height: calc(100dvh - 112px); } .tn-preview iframe { height: calc(100dvh - 160px); min-height: 0; } } @media (min-width: 561px) and (max-height: 680px) { /* The Starter layout positions the form absolutely. Give short desktop windows a scrollable canvas so the lower fields are never clipped. */ .tn-login-page { height: auto; min-height: 720px; } } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; scroll-behavior: auto !important; } /* Active loading indicators must retain continuous movement so users know tasks are progressing */ .tn-beam-bar::after, .tn-spin { animation-duration: 2s !important; animation-iteration-count: infinite !important; } } /* ========================================================================== TallyNote Update Center (Redesigned UI & Interactive Styles) ========================================================================== */ /* Update Page Actions */ .tn-update-page-actions { display: flex; align-items: center; gap: 10px; } /* 4 Metrics Grid */ .tn-update-metrics-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; margin-bottom: 16px; } /* Stepper Surface */ .tn-stepper-surface { margin-bottom: 16px; padding: 20px; } .tn-stepper-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 20px; } .tn-section-heading { margin: 0 0 4px; font-size: 15px; font-weight: 700; color: var(--tn-text); } .tn-section-subheading { font-size: 12px; color: var(--tn-text-secondary); } .tn-stepper-wrap { padding: 10px 0 20px; } .tn-stepper-wrap .t-steps { max-width: 860px; margin: 0 auto; } .tn-stepper-wrap { min-width: 0; overflow-x: auto; scrollbar-width: thin; scrollbar-color: var(--td-brand-color-3) transparent; } .tn-stepper-wrap .t-steps { min-width: 680px; } /* Job Runtime Panel (Active download & progress) */ .tn-job-runtime-panel { margin-top: 14px; padding: 16px; background: #f8fbff; border: 1px solid var(--td-brand-color-2); border-radius: 4px; } .tn-job-runtime-header { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px; margin-bottom: 12px; } .tn-job-status-badge { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--tn-navy-900); min-width: 0; overflow-wrap: anywhere; } .tn-pulse-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--td-brand-color); box-shadow: 0 0 0 0 rgba(23, 92, 211, 0.7); animation: tn-pulse 1.8s infinite; } @keyframes tn-pulse { 0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(23, 92, 211, 0.7); } 70% { transform: scale(1); box-shadow: 0 0 0 6px rgba(23, 92, 211, 0); } 100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(23, 92, 211, 0); } } .tn-job-subtext { color: var(--tn-text-secondary); font-size: 12px; font-family: "Plus Jakarta Sans Variable", sans-serif; font-variant-numeric: tabular-nums; } .tn-speed-indicator { display: flex; align-items: center; gap: 8px; min-width: 0; flex-wrap: wrap; } .tn-speed-badge { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: 3px; background: #ffffff; border: 1px solid var(--td-brand-color-3); color: var(--td-brand-color); font-size: 12px; font-weight: 600; font-family: "Plus Jakarta Sans Variable", sans-serif; font-variant-numeric: tabular-nums; } .tn-eta-badge { display: inline-block; padding: 2px 8px; border-radius: 3px; background: #f2f5f9; color: var(--tn-text-secondary); font-size: 12px; font-variant-numeric: tabular-nums; } /* Progress Bar with modern stream light effect */ .tn-progress-stream { position: relative; height: 8px; background: #e1e9f4; border-radius: 999px; overflow: hidden; margin-bottom: 12px; } .tn-progress-stream-bar { height: 100%; background: linear-gradient(90deg, #175cd3 0%, #3d7be5 100%); border-radius: inherit; transition: width 0.35s ease; position: relative; } .tn-progress-stream-bar::after { content: ""; position: absolute; top: 0; left: 0; bottom: 0; right: 0; background-image: linear-gradient( -45deg, rgba(255, 255, 255, 0.25) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.25) 50%, rgba(255, 255, 255, 0.25) 75%, transparent 75%, transparent ); background-size: 30px 30px; animation: tn-stream-flow 1.5s linear infinite; } @keyframes tn-stream-flow { 0% { background-position: 0 0; } 100% { background-position: 30px 30px; } } .tn-job-runtime-desc { font-size: 12px; color: var(--tn-text-secondary); line-height: 1.6; } /* Restarting State Banner */ .tn-restarting-banner { display: flex; align-items: center; gap: 12px; padding: 8px 12px; background: #fff8e6; border: 1px solid #ffd666; border-radius: 3px; color: #8c5b00; } .tn-restarting-spinner { color: #faad14; } /* Release Surface */ .tn-release-surface { margin-bottom: 16px; padding: 20px; } .tn-release-notes-surface { margin-bottom: 16px; padding: 20px; } .tn-release-notes-header { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 12px; } .tn-release-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; } .tn-release-tag-row { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; } .tn-release-title { margin: 0 0 6px; font-size: 22px; font-weight: 700; color: var(--tn-navy-900); } .tn-release-time { font-size: 12px; color: var(--tn-text-secondary); } .tn-release-notes-box { margin: 0; padding: 12px 16px; background: #f8fafc; border: 1px solid var(--tn-border); border-left: 3px solid var(--td-brand-color); border-radius: 3px; } .tn-release-notes-heading { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--tn-navy-900); margin-bottom: 6px; } .tn-release-notes-content { font-size: 13px; color: var(--tn-text-secondary); line-height: 1.6; max-height: 140px; overflow-y: auto; } .tn-markdown-notes { color: inherit; line-height: 1.7; overflow-wrap: anywhere; } .tn-markdown-notes p, .tn-markdown-notes h3, .tn-markdown-notes h4, .tn-markdown-notes h5 { margin: 0 0 8px; } .tn-markdown-notes p:last-child, .tn-markdown-notes ul:last-child, .tn-markdown-notes pre:last-child, .tn-markdown-notes h3:last-child, .tn-markdown-notes h4:last-child, .tn-markdown-notes h5:last-child { margin-bottom: 0; } .tn-markdown-notes h3, .tn-markdown-notes h4, .tn-markdown-notes h5 { color: var(--tn-navy-900); font-weight: 700; } .tn-markdown-notes h3 { font-size: 15px; } .tn-markdown-notes h4 { font-size: 14px; } .tn-markdown-notes h5 { font-size: 13px; } .tn-markdown-notes ul { margin: 0 0 8px; padding-left: 20px; } .tn-markdown-notes li { margin: 3px 0; } .tn-markdown-notes strong { color: var(--tn-navy-900); font-weight: 700; } .tn-markdown-notes code { padding: 1px 4px; border: 1px solid var(--tn-border-subtle); border-radius: 3px; background: #f2f5f9; color: var(--tn-navy-900); font-family: "Plus Jakarta Sans Variable", ui-monospace, monospace; font-size: .92em; } .tn-markdown-notes pre { margin: 0 0 8px; padding: 10px 12px; overflow-x: auto; border: 1px solid var(--tn-border-subtle); border-radius: 3px; background: #f8fafc; white-space: pre-wrap; } .tn-markdown-notes pre code { padding: 0; border: 0; background: transparent; } .tn-markdown-notes a { color: var(--td-brand-color); text-decoration: underline; text-underline-offset: 2px; } .tn-markdown-notes-compact { font-size: 13px; } /* Facts Grid */ .tn-facts-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin: 18px 0; padding: 14px 0; border-top: 1px solid var(--tn-border-subtle); border-bottom: 1px solid var(--tn-border-subtle); } .tn-fact-item { display: flex; flex-direction: column; gap: 4px; } .tn-fact-label { font-size: 12px; color: var(--tn-text-secondary); } .tn-fact-value { font-size: 14px; color: var(--tn-text); font-weight: 600; overflow-wrap: anywhere; } .tn-fact-hint { font-size: 11px; color: var(--tn-text-muted); } .tn-release-card-actions { display: flex; align-items: center; gap: 12px; margin-top: 16px; } /* Dialog content styles */ .tn-confirm-dialog-content { font-size: 13px; line-height: 1.6; color: var(--tn-text); } .tn-update-safety-tips { margin-top: 10px; padding: 10px 14px; background: #f6f8fb; border-radius: 3px; border: 1px solid var(--tn-border-subtle); font-size: 12px; color: var(--tn-text-secondary); display: flex; flex-direction: column; gap: 4px; } .tn-full-notes-modal { margin: 0; padding: 12px; background: #f8fafc; border-radius: 3px; font-size: 13px; line-height: 1.6; color: var(--tn-text); max-height: 50vh; overflow-y: auto; } .tn-empty-surface { padding: 36px 20px; text-align: center; } .tn-empty-content { display: flex; flex-direction: column; align-items: center; gap: 8px; color: var(--tn-text-secondary); font-size: 13px; } .tn-inline-warning { display: flex; align-items: center; gap: 8px; padding: 10px 14px; margin-bottom: 14px; background: #fffbe6; border: 1px solid #ffe58f; border-radius: 3px; color: #d48806; font-size: 13px; } /* Responsive adjustments */ @media (max-width: 992px) { .tn-update-metrics-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .tn-facts-grid { grid-template-columns: 1fr; } } @media (max-width: 640px) { .tn-update-metrics-grid { grid-template-columns: 1fr; } .tn-release-header { flex-direction: column; } .tn-release-notes-header { align-items: flex-start; flex-direction: column; } .tn-release-notes-header .t-button { width: 100%; } .tn-release-card-actions { flex-direction: column; width: 100%; } .tn-release-card-actions .t-button { width: 100%; } .tn-stepper-wrap { margin-inline: -4px; padding-inline: 4px; } .tn-stepper-wrap .t-steps { min-width: 620px; } .tn-job-runtime-header { align-items: stretch; } .tn-job-status-badge, .tn-speed-indicator { width: 100%; } .tn-speed-indicator { justify-content: flex-start; } } /* System Update Console & Phase Styles */ .tn-release-version-title { margin: 4px 0 8px; font-size: 20px; font-weight: 700; color: var(--tn-navy-900); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; } .tn-release-nickname { font-size: 15px; font-weight: 500; color: var(--tn-text-secondary); } .tn-release-meta-row { display: flex; align-items: center; gap: 16px; font-size: 13px; color: var(--tn-text-secondary); flex-wrap: wrap; } .tn-meta-item { display: inline-flex; align-items: center; gap: 6px; } .tn-meta-link { display: inline-flex; align-items: center; gap: 4px; color: var(--td-brand-color); text-decoration: none; } .tn-meta-link:hover { text-decoration: underline; } /* In-Page Release Notes Container */ .tn-release-notes-surface { margin-bottom: 16px; padding: 20px; } .tn-release-notes-box { margin: 0; padding: 16px 20px; background: var(--tn-surface-alt, #f8fafc); border: 1px solid var(--tn-border); border-left: 3px solid var(--td-brand-color); border-radius: 4px; } .tn-release-notes-content { font-size: 13.5px; color: var(--tn-text); line-height: 1.7; max-height: 380px; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--td-brand-color-3) transparent; } /* Upgrade Modal Phases */ .tn-upgrade-phase-confirm { padding: 12px 0; } .tn-confirm-phase-head { display: flex; align-items: flex-start; gap: 16px; margin-bottom: 16px; } .tn-confirm-phase-head h4 { margin: 0 0 6px; font-size: 17px; font-weight: 600; color: var(--tn-navy-900); } .tn-confirm-phase-head p { margin: 0; font-size: 13.5px; } .tn-upgrade-safety-tips { background: rgba(23, 92, 211, 0.04); border: 1px solid rgba(23, 92, 211, 0.15); border-radius: 4px; padding: 14px 16px; font-size: 13px; line-height: 1.8; color: var(--tn-navy-900); margin-bottom: 20px; } .tn-modal-actions-bar { display: flex; align-items: center; justify-content: flex-end; gap: 12px; margin-top: 20px; } .tn-staged-apply-box { padding: 12px 0 4px; } .tn-staged-title { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; font-size: 15px; } .tn-upgrade-phase-completed { padding: 24px 0 12px; } .tn-completed-banner { display: flex; align-items: center; gap: 18px; background: rgba(47, 125, 92, 0.06); border: 1px solid rgba(47, 125, 92, 0.2); border-radius: 4px; padding: 18px 22px; margin-bottom: 16px; } .tn-completed-banner h4 { margin: 0 0 4px; font-size: 18px; font-weight: 600; color: #1e6043; } .tn-completed-banner p { margin: 0; font-size: 13.5px; color: var(--tn-text); } .tn-upgrade-phase-failed { padding: 16px 0; } .tn-modal-footer-close { display: flex; justify-content: center; margin-top: 18px; border-top: 1px dashed var(--tn-border); padding-top: 14px; } /* ============================================================ ASCII Layout Accurate Styles for Update Center ============================================================ */ /* 4 Metric Cards Grid - Strictly Fixed Height & Zero Layout Shift */ .tn-metrics-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 20px; align-items: start; } .tn-metric-card { height: 104px !important; min-height: 104px !important; max-height: 104px !important; box-sizing: border-box !important; padding: 0 !important; background: #ffffff; border: 1px solid var(--tn-border); border-radius: 4px; overflow: hidden !important; } .tn-metric-card .t-card__body { height: 100% !important; box-sizing: border-box !important; display: flex !important; flex-direction: column !important; justify-content: space-between !important; padding: 14px 18px !important; } .tn-metric-label { display: block; font-size: 12.5px; color: var(--tn-text-secondary); line-height: 1; margin: 0; } .tn-metric-value { font-size: 20px; font-weight: 700; color: var(--tn-navy-900); line-height: 1.2; margin: 4px 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-variant-numeric: tabular-nums; } .tn-metric-card.tn-metric-date .tn-metric-value { font-size: 16px !important; font-weight: 600 !important; line-height: 1.3 !important; } .tn-metric-foot { font-size: 12px; color: var(--tn-text-secondary); height: 20px !important; min-height: 20px !important; max-height: 20px !important; line-height: 20px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: flex; align-items: center; margin: 0; } /* Container 5: Release Details (Exact ASCII: 2 rows, 3 columns) */ .tn-ascii-release-container { padding: 22px 24px; margin-bottom: 20px; background: #ffffff; border: 1px solid var(--tn-border); border-radius: 4px; } .tn-ascii-release-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 18px; border-bottom: 1px solid #edf1f5; padding-bottom: 12px; } .tn-ascii-release-title { margin: 0; font-size: 16px; font-weight: 700; color: var(--tn-navy-900); } .tn-ascii-info-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px 24px; margin-bottom: 24px; } .tn-ascii-info-item { font-size: 13.5px; color: var(--tn-text); line-height: 1.6; } .tn-ascii-info-label { color: var(--tn-text-secondary); margin-right: 6px; } .tn-ascii-info-val { font-weight: 600; color: var(--tn-navy-900); } .tn-ascii-release-actions { display: flex; justify-content: flex-end; border-top: 1px solid #edf1f5; padding-top: 18px; } /* Container 6: In-page Release Notes Card */ .tn-ascii-notes-container { padding: 22px 24px; margin-bottom: 24px; background: #ffffff; border: 1px solid var(--tn-border); border-radius: 4px; } .tn-ascii-notes-head { margin-bottom: 16px; border-bottom: 1px solid #edf1f5; padding-bottom: 12px; } .tn-ascii-notes-title { margin: 0; font-size: 16px; font-weight: 700; color: var(--tn-navy-900); } .tn-ascii-notes-body { font-size: 13.5px; color: var(--tn-text); line-height: 1.75; max-height: 420px; overflow-y: auto; padding-right: 8px; } /* Modal Inner Card matching ASCII */ .tn-modal-card-box { background: #f8fafc; border: 1px solid var(--tn-border); border-radius: 4px; padding: 20px 24px; margin: 16px 0; } .tn-modal-card-title { 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; align-items: center; justify-content: space-between; gap: 16px; margin-top: 14px; font-size: 13px; color: var(--tn-text-secondary); padding-top: 12px; border-top: 1px solid #eef2f6; } .tn-modal-metrics-item strong { color: var(--tn-navy-900); margin-left: 4px; } .tn-modal-info-note { font-size: 12.5px; color: var(--tn-text-secondary); line-height: 1.6; margin: 12px 0 16px; display: flex; align-items: center; gap: 6px; } /* ============================================================ 方案二:平滑极光光流条 (Beam Bar / Shimmer) 全局动效规范 ============================================================ */ .tn-beam-loading { display: flex !important; flex-direction: column !important; align-items: center !important; justify-content: center !important; gap: 14px !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: 5px; background: var(--td-brand-color-1, #e8f0ff); border-radius: 9999px; overflow: hidden; position: relative; display: block; margin: 0 auto; box-shadow: inset 0 1px 2px rgba(23, 92, 211, 0.08); } .tn-beam-bar::after { content: ""; position: absolute; top: 0; left: 0; width: 50%; height: 100%; background: linear-gradient(90deg, rgba(23, 92, 211, 0) 0%, rgba(61, 123, 229, 0.95) 45%, var(--td-brand-color, #175cd3) 70%, rgba(23, 92, 211, 0) 100%); box-shadow: 0 0 10px rgba(23, 92, 211, 0.55), 0 0 4px rgba(61, 123, 229, 0.9); border-radius: 9999px; animation: tn-beam-flow 1.4s cubic-bezier(0.4, 0, 0.2, 1) infinite; will-change: transform; } .tn-beam-bar-sm { width: 60px !important; height: 3.5px !important; display: inline-block !important; vertical-align: middle; margin: 0 6px !important; } .tn-beam-bar-sm::after { width: 50%; animation: tn-beam-flow 1.2s cubic-bezier(0.4, 0, 0.2, 1) infinite; } @keyframes tn-beam-flow { 0% { transform: translateX(-150%); } 100% { transform: translateX(280%); } } .tn-beam-text { font-size: 13.5px; color: var(--tn-navy-700, #344054); font-weight: 500; letter-spacing: 0.3px; } /* 彻底隐去 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; }