fix(frontend): scope the credits button skins to the user-center shell

The user-center route rendered a 4px top-nav publish chip while every other
route kept the 50px pill. assets/css/routes/user-center/credits.css restated
border-radius on bare legacy colour modifiers (.but.jb-blue, .but.b-blue-2,
.but.c-blue-2.hollow, .but.c-green.hollow). Those rules are (0,2,0) and load
after public.css, so they out-rank .but.radius's 50px and flatten the publish
chip, which is newadd-btns but jb-blue radius, down to 4px.

The same leak also repainted every site-wide .but.jb-blue outside the panel
with the flat #3b82f6 skin instead of the legacy gradient, so login, submit,
badge and cashier buttons lost their reference surface on that route too.

Scope the four rules to .uc-content, the shell every credits panel and its
modals render inside (templates/pages/page-profile.php wraps
templates/parts/user-center/panel.php). The panel keeps its own button skins
and the top-nav chips get the reference pill back.

The .btn-block restatement that sat in the same block is byte-identical to
the one in core/buttons.css, which loads earlier on every page, so it could
never win; it is dropped rather than scoped.

Verified: node --test across tests/ (604 passing), plus a stubbed navbar
rendered against each route's real stylesheet set measuring the computed
border-radius of the publish chip and of the panel's own buttons. A new
contract test fails on the previous stylesheet and passes on this one.
This commit is contained in:
kate522 committed 2026-10-15 23:22:18 +08:00
1 parent ee39024549
commit 4d69aaee50
2 files changed
+51 -10

No files matched your search

@@ -180,6 +180,35 @@ test('guest account member VIP and publish contracts share reference header DOM'
assert.match(userboxCss, /\.aksrt-header-userbox\s*>\s*\.mt6\.em09\s*>\s*\.but\.block\s*\{[^}]*display:\s*block;[^}]*box-sizing:\s*border-box;[^}]*width:\s*100%;/s);
});
test('route and feature modules do not restyle the legacy top-nav chips', () => {
// Route and feature modules may not restyle the legacy .but colour modifiers
// without an enclosing scope. The top-nav chips ride the legacy geometry
// verbatim (newadd-btns but <skin> radius and pay-vip but jb-red radius
// payvip-icon), so their pill comes from .but.radius at (0,2,0). A later,
// equally specific rule that restates border-radius on a bare .but.<colour>
// out-ranks it and flattens the pill: user-center/credits.css did exactly that
// with .but.jb-blue, so the user-center route rendered a 4px publish chip while
// every other route kept the 50px one. Such rules must be scoped to their own
// shell, as credits.css now is with .uc-content.
const moduleCss = [
...listFiles('assets/css/routes', new Set(['.css'])),
...listFiles('assets/css/frontend', new Set(['.css'])),
].filter((file) => file !== 'assets/css/frontend/header-userbox.css');
for (const file of moduleCss) {
const css = read(file);
for (const [, selector, declarations] of css.matchAll(/([^{}]+)\{([^{}]*)\}/g)) {
if (!/border-radius/.test(declarations)) continue;
for (const part of selector.split(',')) {
assert.doesNotMatch(
part.trim(),
/^\.but\./,
`${file} restates border-radius on an unscoped legacy .but modifier (${part.trim()}); scope it to the module's own shell so the top-nav chips keep the reference pill`
);
}
}
}
})
test('the account popover rows match the reference user box structure', () => {
const identity = read('inc/helpers/aksrt-identity.php');
const legacyMainCss = read('assets/css/main.css');