diff --git a/.gitignore b/.gitignore index 19fd0c96..0acd1d6d 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,7 @@ !/tests/widget-system/message-center-pagination-harness.php !/tests/widget-system/asset-ledger-contract.test.cjs !/tests/widget-system/financial-flow-contract.test.cjs +!/tests/widget-system/user-assets-layout-contract.test.cjs !/tests/widget-system/pay-orders-filter-contract.test.cjs !/tests/widget-system/front-submit-editor-contract.test.cjs !/tests/widget-system/front-submit-attachment-contract.test.cjs diff --git a/assets/css/frontend/credits.css b/assets/css/frontend/credits.css index 51a6a1d7..04f2b703 100644 --- a/assets/css/frontend/credits.css +++ b/assets/css/frontend/credits.css @@ -99,72 +99,6 @@ color: #ef4444; } -/* ============ 余额卡片(profile 头部) ============ */ -.credits-card { - display: flex; - flex-wrap: wrap; - align-items: center; - justify-content: space-between; - gap: 16px; - padding: 20px 24px; - border-radius: var(--radius-lg); - background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-active) 100%); - color: var(--color-on-primary); - margin-bottom: 20px; -} - -.credits-card__info { - display: flex; - flex-direction: column; - gap: 6px; -} - -.credits-card__label { - font: 500 13px/1 var(--font-ui); - opacity: .85; -} - -.credits-card__value { - font: 700 32px/1 var(--font-ui); - display: flex; - align-items: baseline; - gap: 6px; -} - -.credits-card__unit { - font: 500 14px/1 var(--font-ui); - opacity: .85; -} - -.credits-card__sign { - display: flex; - align-items: center; - gap: 12px; - flex-shrink: 0; -} - -.credits-card__sign-status { - font: 500 13px/1.4 var(--font-ui); - opacity: .9; - max-width: 160px; - text-align: right; -} - -.credits-card__sign .btn-primary { - background: rgba(255, 255, 255, .2); - border: 1px solid rgba(255, 255, 255, .3); - backdrop-filter: blur(4px); -} - -.credits-card__sign .btn-primary:hover:not(:disabled) { - background: rgba(255, 255, 255, .35); -} - -.credits-card__sign .btn-primary:disabled { - opacity: .5; - cursor: default; -} - /* ============ 签到 panel ============ */ .aksrt-signin-status { margin: 0 0 16px; diff --git a/assets/css/routes/user-center/credits.css b/assets/css/routes/user-center/credits.css index 8c37dada..4300d002 100644 --- a/assets/css/routes/user-center/credits.css +++ b/assets/css/routes/user-center/credits.css @@ -2,9 +2,6 @@ * User Center — assets (wallet + points) legacy parity */ -.uc-balance-card { - box-shadow: none; -} /* The asset cards and the records card are sibling surfaces, not one nested card. */ .uc-content #panel-credits.dashboard-panel { @@ -27,7 +24,25 @@ box-shadow: none; } .uc-assets-row--dual { - grid-template-columns: 1fr 1fr; + grid-template-columns: repeat(2, minmax(0, 1fr)); + grid-template-rows: auto auto; +} +.uc-assets-row--dual > .uc-assets-col { + display: contents; +} +.uc-assets-row--dual > .uc-assets-col:first-child > .uc-asset-card, +.uc-assets-row--dual > .uc-assets-col:first-child > .uc-card-pass { + grid-column: 1; +} +.uc-assets-row--dual > .uc-assets-col:last-child > .uc-asset-card, +.uc-assets-row--dual > .uc-assets-col:last-child > .uc-card-pass { + grid-column: 2; +} +.uc-assets-row--dual > .uc-assets-col > .uc-asset-card { + grid-row: 1; +} +.uc-assets-row--dual > .uc-assets-col > .uc-card-pass { + grid-row: 2; } .uc-assets-col { min-width: 0; @@ -38,6 +53,17 @@ @media (max-width: 767px) { .uc-assets-row--dual { grid-template-columns: 1fr; + grid-template-rows: none; + } + .uc-assets-row--dual > .uc-assets-col { + display: flex; + grid-column: auto; + grid-row: auto; + } + .uc-assets-row--dual > .uc-assets-col > .uc-asset-card, + .uc-assets-row--dual > .uc-assets-col > .uc-card-pass { + grid-column: auto; + grid-row: auto; } } @@ -50,12 +76,6 @@ padding: 16px 20px; margin-bottom: 0; } -.uc-assets-row .uc-asset-card.aksrt-panel { - /* defensive if class reintroduced */ - margin-bottom: 0; - clear: none; -} - /* Card-pass under a col must not look like a second stacked card */ .uc-assets-col > .uc-card-pass { margin: 0; @@ -310,26 +330,21 @@ body.uc-modal-open { } /* Asset records sit in their own card below the wallet and points cards. */ -.uc-asset-tabs, -.uc-asset-tabs.aksrt-panel { +.uc-asset-tabs { margin: 0; padding: 20px; background: var(--surface-1, #fff); - border: 1px solid var(--color-line-soft, rgba(0, 0, 0, 0.06)); + border: 1px solid var(--color-line-soft, rgba(0,0,0,0.06)); border-radius: var(--main-radius, var(--radius, 8px)); box-shadow: 0 1px 4px rgba(15, 23, 42, 0.04); } @media (max-width: 480px) { - .uc-asset-tabs, - .uc-asset-tabs.aksrt-panel { + .uc-asset-tabs { padding: 14px; } } -.uc-asset-tabs.aksrt-panel { - margin-bottom: 0; -} .uc-asset-tabs__nav { display: flex; gap: 18px; @@ -391,131 +406,6 @@ body.uc-modal-open { vertical-align: middle; } -/* ==================== 账户余额面板 ==================== */ - -/* 余额卡片 */ -.uc-balance-card { - position: relative; - border-radius: var(--radius); - overflow: hidden; - margin-bottom: 20px; - box-shadow: 0 4px 20px rgba(var(--color-primary-rgb, 59, 130, 246), 0.2); -} - -.uc-balance-card__bg { - position: absolute; - inset: 0; - background: linear-gradient(135deg, var(--color-primary) 0%, #4facfe 50%, #00f2fe 100%); - z-index: 0; -} - -.uc-balance-card__bg::after { - content: ''; - position: absolute; - top: -50%; - right: -30%; - width: 200px; - height: 200px; - border-radius: 50%; - background: rgba(255,255,255,0.08); -} - -.uc-balance-card__bg::before { - content: ''; - position: absolute; - bottom: -60%; - left: -20%; - width: 160px; - height: 160px; - border-radius: 50%; - background: rgba(255,255,255,0.05); -} - -.uc-balance-card__content { - position: relative; - z-index: 1; - padding: 24px; - color: #fff; -} - -.uc-balance-card__header { - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 8px; -} - -.uc-balance-card__label { - font-size: 14px; - font-weight: 500; - opacity: 0.9; -} - -.uc-balance-card__currency { - font-size: 12px; - padding: 3px 10px; - background: rgba(255,255,255,0.15); - border-radius: 100px; - backdrop-filter: blur(4px); -} - -.uc-balance-card__amount { - margin-bottom: 16px; -} - -.uc-balance-card__value { - font-size: 2.5rem; - font-weight: 800; - line-height: 1.2; - letter-spacing: -0.02em; - font-variant-numeric: tabular-nums; -} - -.uc-balance-card__actions { - display: flex; - align-items: center; - justify-content: space-between; - padding-top: 16px; - border-top: 1px solid rgba(255,255,255,0.15); -} - -.uc-balance-card__sign-status { - font-size: 13px; - opacity: 0.85; -} - -.uc-balance-card__sign-btn { - display: inline-flex; - align-items: center; - gap: 6px; - padding: 8px 20px; - border: none; - border-radius: 100px; - background: rgba(255,255,255,0.2); - color: #fff; - font-size: 14px; - font-weight: 600; - cursor: pointer; - transition: all 0.2s ease; - backdrop-filter: blur(4px); -} - -.uc-balance-card__sign-btn:hover { - background: rgba(255,255,255,0.3); - transform: translateY(-1px); -} - -.uc-balance-card__sign-btn:disabled { - background: rgba(255,255,255,0.1); - color: rgba(255,255,255,0.5); - cursor: not-allowed; - transform: none; -} - -.uc-balance-card__sign-btn i { - font-size: 14px; -} - /* 积分流水 */ .uc-transactions { background: var(--surface-1); @@ -986,12 +876,6 @@ body.uc-modal-open { padding-top: 8px; border-top: 1px dashed var(--muted-border-color, rgba(0,0,0,.08)); } -.uc-asset-card__foot button { - background: none; - border: 0; - padding: 0; - cursor: pointer; -} .uc-asset-card__head-action { background: none; border: 0; diff --git a/assets/css/routes/user-center/responsive.css b/assets/css/routes/user-center/responsive.css index c3c7f562..e1add844 100644 --- a/assets/css/routes/user-center/responsive.css +++ b/assets/css/routes/user-center/responsive.css @@ -154,12 +154,6 @@ .uc-content .dashboard-panel { padding: 16px; } - - .uc-content .credits-card { - flex-direction: column; - text-align: center; - gap: 12px; - } } /* ==================== 焦点状态(无障碍)==================== */ @@ -242,25 +236,6 @@ padding: 14px; } - .uc-balance-card__content { - padding: 18px; - } - - .uc-balance-card__value { - font-size: 2rem; - } - - .uc-balance-card__actions { - flex-direction: column; - gap: 10px; - align-items: flex-start; - } - - .uc-balance-card__sign-btn { - width: 100%; - justify-content: center; - } - .uc-transactions__item { padding: 12px 14px; } @@ -271,13 +246,6 @@ font-size: 12px; } - .uc-content .credits-card { - padding: 16px; - } - - .uc-content .credits-card__value { - font-size: 1.5rem; - } } @media (max-width: 640px) { diff --git a/tests/widget-system/user-assets-layout-contract.test.cjs b/tests/widget-system/user-assets-layout-contract.test.cjs new file mode 100644 index 00000000..f240b70d --- /dev/null +++ b/tests/widget-system/user-assets-layout-contract.test.cjs @@ -0,0 +1,51 @@ +const test = require('node:test') +const assert = require('node:assert/strict') +const fs = require('node:fs') +const path = require('node:path') + +const root = path.resolve(__dirname, '..', '..') + +function read(relative) { + return fs.readFileSync(path.join(root, relative), 'utf8') +} + +test('dual asset cards use an independent equal-height grid row', () => { + const css = read('assets/css/routes/user-center/credits.css') + const profile = read('inc/helpers/user-center-renderers/profile-credits.php') + + assert.match(css, /\.uc-assets-row--dual\s*\{[\s\S]*?grid-template-columns:\s*repeat\(2,\s*minmax\(0,\s*1fr\)\);[\s\S]*?grid-template-rows:\s*auto auto;/) + assert.match(css, /\.uc-assets-row--dual\s*>\s*\.uc-assets-col\s*\{[\s\S]*?display:\s*contents;/) + assert.match(css, /\.uc-assets-row--dual\s*>\s*\.uc-assets-col:first-child\s*>\s*\.uc-asset-card[\s\S]*?grid-column:\s*1;/) + assert.match(css, /\.uc-assets-row--dual\s*>\s*\.uc-assets-col:last-child\s*>\s*\.uc-asset-card[\s\S]*?grid-column:\s*2;/) + assert.match(css, /\.uc-assets-row--dual\s*>\s*\.uc-assets-col\s*>\s*\.uc-asset-card\s*\{[\s\S]*?grid-row:\s*1;/) + assert.match(css, /\.uc-assets-row--dual\s*>\s*\.uc-assets-col\s*>\s*\.uc-card-pass\s*\{[\s\S]*?grid-row:\s*2;/) + assert.match(profile, /