feat(ui): 营销站 UI/UE/UX 治理 P0→P3 + 数字口径 basis 机制 #28

Closed
zhangxiang wants to merge 30 commits from refactor/optimize-ui into dev
3 changed files with 68 additions and 1 deletions
Showing only changes of commit 2a8b81f042 - Show all commits
@@ -0,0 +1,42 @@
// 验证 darkMode selector 配置生效
import { chromium } from 'playwright';
const browser = await chromium.launch();
async function probe(theme) {
const ctx = await browser.newContext({ viewport: { width: 1280, height: 800 } });
const page = await ctx.newPage();
// 先建立 origin
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
await page.evaluate((t) => {
if (t === 'dark') localStorage.setItem('novalon-theme', 'dark');
else localStorage.removeItem('novalon-theme');
}, theme);
// 重新加载让内联脚本读 localStorage 设置 data-theme
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
await page.waitForTimeout(1500);
const out = await page.evaluate(() => {
const probe = document.createElement('div');
probe.className = 'bg-white dark:bg-blue-500';
probe.style.cssText = 'position:fixed;top:-9999px;width:50px;height:50px;';
document.body.appendChild(probe);
const bg = getComputedStyle(probe).backgroundColor;
const htmlTheme = document.documentElement.getAttribute('data-theme');
probe.remove();
return { bg, htmlTheme };
});
await ctx.close();
return out;
}
const light = await probe('light');
const dark = await probe('dark');
await browser.close();
console.log('light:', JSON.stringify(light));
console.log('dark :', JSON.stringify(dark));
const lightOk = light.bg === 'rgb(255, 255, 255)' && light.htmlTheme !== 'dark';
const darkOk = dark.bg === 'rgb(59, 130, 246)' && dark.htmlTheme === 'dark';
console.log(`\n[assert] light bg=white, no data-theme: ${lightOk}`);
console.log(`[assert] dark bg=blue, data-theme=dark: ${darkOk}`);
console.log(`[result] ${lightOk && darkOk ? 'PASS' : 'FAIL'}`);
+25
View File
@@ -0,0 +1,25 @@
// 验证 home 本地 CTASection 实际渲染(含 BrandStamp 的是 src/components/sections/cta-section.tsx
import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1280, height: 800 } });
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
await page.waitForTimeout(2000);
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
await page.waitForTimeout(2000);
const dump = await page.evaluate(() => {
// home 本地简化版的特征 className
const homeCta = document.querySelector('section.relative.py-24.sm\\:py-32');
// 公开 cta-section 的特征 id
const srcCta = document.querySelector('section#cta');
// BrandStamp 容器特征(inline-block px-3 py-1.5 border-2 border-[var(--color-brand)] rounded-sm
const stamp = document.querySelector('.inline-block.px-3.py-1\\.5.border-2');
return {
homeCtaPresent: !!homeCta,
homeCtaText: homeCta ? (homeCta.textContent || '').slice(0, 60) : null,
srcCtaPresent: !!srcCta,
brandStampPresent: !!stamp,
};
});
await browser.close();
console.log(JSON.stringify(dump, null, 2));
+1 -1
View File
@@ -5,7 +5,7 @@ module.exports = {
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
],
darkMode: 'class',
darkMode: ['variant', '[data-theme="dark"] &'],
theme: {
extend: {
colors: {