style: improve login form styling with proper text colors and transparency
- MudTextField input fields: white text on semi-transparent background - Improve readability on dark gradient background - MudTextField labels: light white text - MudButton: improved blue primary styling - Form validation: MudAlert error styling - CSS enhancements for better contrast Visual improvements: ✅ Input field text visibility (black → white) ✅ Background transparency (opaque → semi-transparent) ✅ Primary button styling (blue gradient) ✅ Label and checkbox colors (white text) Testing: ✅ Playwright E2E: 1 passed ✅ API endpoint: 200 OK ✅ CSS loading: 200 OK (app.css, MudBlazor.min.css) Screenshots: - test-results/login-page-full.png (improved styling) - test-results/login-card-closeup.png (closeup detail) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -295,3 +295,83 @@ body {
|
||||
background: white;
|
||||
}
|
||||
}
|
||||
|
||||
/* =============================================
|
||||
로그인 페이지 MudTextField 스타일 개선
|
||||
============================================= */
|
||||
|
||||
/* MudTextField 입력 필드 */
|
||||
.mud-input-slot {
|
||||
color: #ffffff !important;
|
||||
background-color: rgba(255, 255, 255, 0.08) !important;
|
||||
}
|
||||
|
||||
.mud-input-slot::placeholder {
|
||||
color: rgba(255, 255, 255, 0.5) !important;
|
||||
}
|
||||
|
||||
.mud-input-slot:focus {
|
||||
background-color: rgba(255, 255, 255, 0.12) !important;
|
||||
border-color: rgba(63, 81, 181, 0.8) !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
/* MudTextField 라벨 */
|
||||
.mud-input-label {
|
||||
color: rgba(255, 255, 255, 0.8) !important;
|
||||
}
|
||||
|
||||
/* MudTextField 아웃라인 */
|
||||
.mud-input-outlined {
|
||||
border-color: rgba(255, 255, 255, 0.3) !important;
|
||||
}
|
||||
|
||||
.mud-input-outlined:hover {
|
||||
border-color: rgba(255, 255, 255, 0.5) !important;
|
||||
}
|
||||
|
||||
.mud-input-outlined:focus-within {
|
||||
border-color: rgba(63, 81, 181, 0.8) !important;
|
||||
}
|
||||
|
||||
/* MudCheckBox */
|
||||
.mud-button-label {
|
||||
color: rgba(255, 255, 255, 0.9) !important;
|
||||
}
|
||||
|
||||
/* MudButton (로그인) */
|
||||
.mud-button-filled-primary {
|
||||
background-color: rgba(63, 81, 181, 0.9) !important;
|
||||
}
|
||||
|
||||
.mud-button-filled-primary:hover {
|
||||
background-color: rgba(63, 81, 181, 1) !important;
|
||||
box-shadow: 0 8px 24px rgba(63, 81, 181, 0.4) !important;
|
||||
}
|
||||
|
||||
/* MudAlert (에러) */
|
||||
.mud-alert {
|
||||
background-color: rgba(244, 67, 54, 0.15) !important;
|
||||
color: #ff7675 !important;
|
||||
}
|
||||
|
||||
/* HTML input 요소 */
|
||||
input[type="text"].login-input,
|
||||
input[type="password"].login-input {
|
||||
background-color: rgba(255, 255, 255, 0.08) !important;
|
||||
color: #ffffff !important;
|
||||
border-color: rgba(255, 255, 255, 0.3) !important;
|
||||
}
|
||||
|
||||
input[type="text"].login-input::placeholder,
|
||||
input[type="password"].login-input::placeholder {
|
||||
color: rgba(255, 255, 255, 0.5) !important;
|
||||
}
|
||||
|
||||
input[type="text"].login-input:focus,
|
||||
input[type="password"].login-input:focus {
|
||||
background-color: rgba(255, 255, 255, 0.12) !important;
|
||||
border-color: rgba(63, 81, 181, 0.8) !important;
|
||||
color: #ffffff !important;
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 33 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 286 KiB |
@@ -0,0 +1,127 @@
|
||||
import { test } from '@playwright/test';
|
||||
|
||||
test('로그인 페이지 스타일 진단 - 스크린샷 캡처', async ({ page }) => {
|
||||
console.log('\n╔════════════════════════════════════════════════════╗');
|
||||
console.log('║ 로그인 페이지 스타일 진단 ║');
|
||||
console.log('╚════════════════════════════════════════════════════╝\n');
|
||||
|
||||
// 1️⃣ 페이지 로드
|
||||
console.log('1️⃣ 로그인 페이지 로드 중...');
|
||||
await page.goto('http://localhost:5265/login', { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(2000);
|
||||
console.log(' ✓ 페이지 로드 완료');
|
||||
|
||||
// 2️⃣ HTML 요소 확인
|
||||
console.log('\n2️⃣ 페이지 요소 확인...');
|
||||
|
||||
const loginShell = await page.locator('.login-shell').count();
|
||||
const loginCard = await page.locator('.login-card').count();
|
||||
const inputFields = await page.locator('input[type="text"], input[type="password"]').count();
|
||||
const buttons = await page.locator('button:has-text("로그인")').count();
|
||||
|
||||
console.log(` login-shell: ${loginShell > 0 ? '✅' : '❌'}`);
|
||||
console.log(` login-card: ${loginCard > 0 ? '✅' : '❌'}`);
|
||||
console.log(` 입력 필드: ${inputFields}개 ${inputFields >= 2 ? '✅' : '❌'}`);
|
||||
console.log(` 로그인 버튼: ${buttons > 0 ? '✅' : '❌'}`);
|
||||
|
||||
// 3️⃣ CSS 로드 확인
|
||||
console.log('\n3️⃣ CSS 로드 상태...');
|
||||
|
||||
const stylesheets = await page.evaluate(() => {
|
||||
const links = Array.from(document.querySelectorAll('link[rel="stylesheet"]'));
|
||||
return links.map(link => ({
|
||||
href: (link as HTMLLinkElement).href,
|
||||
loaded: (link as HTMLLinkElement).sheet !== null
|
||||
}));
|
||||
});
|
||||
|
||||
stylesheets.forEach(style => {
|
||||
const filename = style.href.split('/').pop();
|
||||
console.log(` ${filename}: ${style.loaded ? '✅' : '❌'}`);
|
||||
});
|
||||
|
||||
// 4️⃣ 계산된 스타일 확인
|
||||
console.log('\n4️⃣ 로그인 카드 계산된 스타일...');
|
||||
|
||||
const cardStyle = await page.locator('.login-card').evaluate((el: any) => ({
|
||||
display: window.getComputedStyle(el).display,
|
||||
backgroundColor: window.getComputedStyle(el).backgroundColor,
|
||||
color: window.getComputedStyle(el).color,
|
||||
borderRadius: window.getComputedStyle(el).borderRadius,
|
||||
width: window.getComputedStyle(el).width,
|
||||
visibility: window.getComputedStyle(el).visibility,
|
||||
opacity: window.getComputedStyle(el).opacity
|
||||
}));
|
||||
|
||||
console.log(` Display: ${cardStyle.display}`);
|
||||
console.log(` BG Color: ${cardStyle.backgroundColor}`);
|
||||
console.log(` Text Color: ${cardStyle.color}`);
|
||||
console.log(` Border Radius: ${cardStyle.borderRadius}`);
|
||||
console.log(` Width: ${cardStyle.width}`);
|
||||
console.log(` Visibility: ${cardStyle.visibility}`);
|
||||
console.log(` Opacity: ${cardStyle.opacity}`);
|
||||
|
||||
// 5️⃣ 입력 필드 스타일
|
||||
console.log('\n5️⃣ 입력 필드 스타일...');
|
||||
|
||||
const inputStyle = await page.locator('input[type="text"]').first().evaluate((el: any) => ({
|
||||
display: window.getComputedStyle(el).display,
|
||||
padding: window.getComputedStyle(el).padding,
|
||||
borderColor: window.getComputedStyle(el).borderColor,
|
||||
backgroundColor: window.getComputedStyle(el).backgroundColor,
|
||||
color: window.getComputedStyle(el).color,
|
||||
fontSize: window.getComputedStyle(el).fontSize,
|
||||
visibility: window.getComputedStyle(el).visibility
|
||||
}));
|
||||
|
||||
console.log(` Display: ${inputStyle.display}`);
|
||||
console.log(` Padding: ${inputStyle.padding}`);
|
||||
console.log(` Border Color: ${inputStyle.borderColor}`);
|
||||
console.log(` BG Color: ${inputStyle.backgroundColor}`);
|
||||
console.log(` Text Color: ${inputStyle.color}`);
|
||||
console.log(` Font Size: ${inputStyle.fontSize}`);
|
||||
console.log(` Visibility: ${inputStyle.visibility}`);
|
||||
|
||||
// 6️⃣ 뷰포트 별 스크린샷
|
||||
console.log('\n6️⃣ 스크린샷 캡처 중...');
|
||||
|
||||
// 전체 페이지 스크린샷
|
||||
await page.screenshot({
|
||||
path: 'test-results/login-page-full.png',
|
||||
fullPage: true
|
||||
});
|
||||
console.log(' ✅ 전체 페이지: test-results/login-page-full.png');
|
||||
|
||||
// 로그인 카드만 확대
|
||||
const loginCardLocator = page.locator('.login-card').first();
|
||||
const box = await loginCardLocator.boundingBox();
|
||||
|
||||
if (box) {
|
||||
await page.screenshot({
|
||||
path: 'test-results/login-card-closeup.png',
|
||||
clip: {
|
||||
x: Math.max(0, box.x - 20),
|
||||
y: Math.max(0, box.y - 20),
|
||||
width: box.width + 40,
|
||||
height: box.height + 40
|
||||
}
|
||||
});
|
||||
console.log(' ✅ 로그인 카드 확대: test-results/login-card-closeup.png');
|
||||
}
|
||||
|
||||
// 7️⃣ 콘솔 에러 확인
|
||||
console.log('\n7️⃣ 브라우저 콘솔 메시지...');
|
||||
|
||||
page.on('console', msg => {
|
||||
if (msg.type() === 'error' || msg.type() === 'warning') {
|
||||
console.log(` [${msg.type().toUpperCase()}] ${msg.text()}`);
|
||||
}
|
||||
});
|
||||
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
console.log('\n╔════════════════════════════════════════════════════╗');
|
||||
console.log('║ 스크린샷 캡처 완료 ║');
|
||||
console.log('║ test-results/ 폴더에서 확인하세요 ║');
|
||||
console.log('╚════════════════════════════════════════════════════╝\n');
|
||||
});
|
||||
Reference in New Issue
Block a user