fix(auth): 다크 폼 입력·비밀번호 토글 스타일 보정
- .auth-form-input 전역 클래스(글자색·캐럿·placeholder·autofill) - 토글 버튼 scoped CSS로 고정, signup 패널 보더·배경·color-scheme - v0.0.62 문서 반영 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -196,4 +196,23 @@
|
||||
background: color-mix(in srgb, var(--site-panel) 72%, var(--site-text));
|
||||
}
|
||||
|
||||
/**
|
||||
* 다크 인증 폼(signin/signup) 텍스트 입력 — UA가 부모 color를 상속하지 않는 경우 대비
|
||||
*/
|
||||
.auth-form-input {
|
||||
color: #f5f7fa;
|
||||
caret-color: #2f6feb;
|
||||
}
|
||||
|
||||
.auth-form-input::placeholder {
|
||||
color: #5c6570;
|
||||
}
|
||||
|
||||
.auth-form-input:-webkit-autofill,
|
||||
.auth-form-input:-webkit-autofill:hover,
|
||||
.auth-form-input:-webkit-autofill:focus {
|
||||
-webkit-text-fill-color: #f5f7fa;
|
||||
transition: background-color 9999s ease-out;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ const props = defineProps({
|
||||
},
|
||||
/**
|
||||
* 스크린 리더용 필드 이름(예: 비밀번호 확인)
|
||||
* @type {string}
|
||||
*/
|
||||
fieldName: {
|
||||
type: String,
|
||||
@@ -44,33 +43,27 @@ const toggle = () => {
|
||||
|
||||
<template>
|
||||
<button
|
||||
class="auth-password-visibility-toggle flex h-10 shrink-0 items-center justify-center px-2.5 text-[#9ba3af] outline-none transition-opacity hover:opacity-80 focus-visible:ring-2 focus-visible:ring-[#2f6feb]/50"
|
||||
class="auth-password-visibility-toggle"
|
||||
type="button"
|
||||
:aria-label="modelValue ? labelFor('hide') : labelFor('show')"
|
||||
:aria-pressed="modelValue"
|
||||
@click="toggle"
|
||||
>
|
||||
<!-- 비밀번호 숨김 상태: 보기(눈 열림) -->
|
||||
<svg
|
||||
v-if="!modelValue"
|
||||
class="auth-password-visibility-toggle__icon h-5 w-5"
|
||||
class="auth-password-visibility-toggle__icon"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
height="24"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" />
|
||||
</svg>
|
||||
<!-- 비밀번호 표시 상태: 숨기기(눈 가림) -->
|
||||
<svg
|
||||
v-else
|
||||
class="auth-password-visibility-toggle__icon h-5 w-5"
|
||||
class="auth-password-visibility-toggle__icon"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
height="24"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
>
|
||||
@@ -78,3 +71,36 @@ const toggle = () => {
|
||||
</svg>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.auth-password-visibility-toggle {
|
||||
display: flex;
|
||||
height: 2.5rem;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-left: 0.625rem;
|
||||
padding-right: 0.625rem;
|
||||
margin: 0;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: #9ba3af;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.auth-password-visibility-toggle:hover {
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.auth-password-visibility-toggle:focus-visible {
|
||||
outline: 2px solid rgba(47, 111, 235, 0.55);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.auth-password-visibility-toggle__icon {
|
||||
display: block;
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
## 스타일
|
||||
|
||||
- TailwindCSS 기본 사용
|
||||
- 주요 요소: Tailwind + 고유 className 동시 적용
|
||||
- 다크 인증(`signin`/`signup`)의 텍스트 입력에는 `auth-form-input` 클래스를 붙여 `main.css`의 글자색·캐럿·placeholder를 적용한다(폼 컨트롤은 부모 `color`를 상속하지 않는 경우가 많음).
|
||||
- 관리자 글 에디터는 블록 단위 UI로 작성하되 저장 값은 기존 마크다운 문자열을 유지
|
||||
|
||||
```html
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# 의사결정 이력
|
||||
|
||||
## 2026-05-11 v0.0.62
|
||||
|
||||
### 인증 폼 다크 스타일이 안 보이던 현상
|
||||
|
||||
`layout/page.vue`의 `text-ink`는 본문에 전달되지만, 폼 컨트롤은 UA 스타일로 `color`를 상속하지 않는 경우가 많아 다크 배경에서 입력 글자와 `currentColor` SVG가 사실상 사라질 수 있다. 전역 `.auth-form-input`으로 텍스트·캐럿·placeholder·WebKit autofill 글자색을 고정하고, 토글 버튼은 SFC `scoped` 스타일로 동일하게 맞췄다. `color-scheme: dark`는 네이티브 컨트롤 테마를 맞추기 위해 섹션에 추가했다.
|
||||
|
||||
## 2026-05-11 v0.0.61
|
||||
|
||||
### 인증 폼 비밀번호 토글 아이콘화
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
| 파일 | 화면 위치 |
|
||||
|------|-----------|
|
||||
| components/auth/AuthPasswordVisibilityToggle.vue | 로그인·회원가입 비밀번호 표시/숨김 토글(SVG, `field-name`으로 접근성 레이블 구분) |
|
||||
| components/auth/AuthPasswordVisibilityToggle.vue | 로그인·회원가입 비밀번호 표시/숨김 토글(SVG, scoped 스타일·`field-name`으로 접근성 레이블 구분) |
|
||||
| components/site/SiteHeader.vue | 모든 공개 페이지 상단, 우측 사용자 아바타 드롭다운(Anonymous/Sign up/Sign in), `lg`~`xl` 헤더 여백·반응형 검색창 폭 |
|
||||
| components/site/LeftSidebar.vue | 왼쪽 사이드바, `lg+`는 `sticky`+고정 높이+내부 무스크롤바 스크롤, `lg` 미만은 고정 슬라이드 패널, 하단 푸터 `px-4`/`sm:px-5` |
|
||||
| components/site/RightSidebar.vue | 오른쪽 사이드바, `lg+`는 고정 열 높이·스티키, 모바일은 본문 아래 전체 너비, 하단 푸터 `pr-3` |
|
||||
@@ -98,8 +98,8 @@
|
||||
| pages/tags/[slug].vue | `/tag/:slug` 리다이렉트 |
|
||||
| pages/tag/[slug].vue | 태그별 글 목록, 상단 태그 헤더 + 리스트형 게시물 카드 |
|
||||
| pages/pages/[slug].vue | 고정 페이지 상세 |
|
||||
| pages/signup.vue | 회원가입 3단계(환영/입력/이메일 확인, 재전송), 2단계 비밀번호·확인에 각각 SVG 표시 토글 |
|
||||
| pages/signin.vue | 로그인(다크 폼), 비밀번호 SVG 표시 토글 |
|
||||
| pages/signup.vue | 회원가입 3단계, 2단계 입력에 `auth-form-input`, 패널 `auth-signup__panel`(보더·배경) |
|
||||
| pages/signin.vue | 로그인(다크 폼, `[color-scheme:dark]`, 입력 `auth-form-input`), 비밀번호 SVG 토글 |
|
||||
|
||||
## 서버 API
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
- 3단계는 인증 메일 발송 안내와 재전송 버튼(쿨다운)을 제공한다.
|
||||
- 이메일 링크 확인 전에는 회원가입이 완료되지 않으며, 인증 완료 액션 이후 로그인 화면으로 이동한다.
|
||||
- 로그인 화면은 동일한 다크 톤 폼 레이아웃을 사용한다.
|
||||
- 로그인·회원가입(2단계) 비밀번호 입력은 `AuthPasswordVisibilityToggle` SVG(눈 열림/가림) 토글로 표시 여부를 바꾼다. 스크린 리더용 `aria-label`은 필드별 `field-name`으로 구분한다.
|
||||
- 로그인·회원가입(2단계) 비밀번호 입력은 `AuthPasswordVisibilityToggle` SVG(눈 열림/가림) 토글로 표시 여부를 바꾼다. 스크린 리더용 `aria-label`은 필드별 `field-name`으로 구분한다. 텍스트 입력은 `.auth-form-input`으로 글자색·캐럿 등을 보정한다.
|
||||
- 인증 화면 상태 메시지는 오류/안내를 분리해 `aria-live`로 노출한다.
|
||||
- 회원가입 1단계의 타이틀/설명은 `GET /api/site-settings`의 `title`, `description` 값을 우선 사용한다.
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# 업데이트 이력
|
||||
|
||||
## v0.0.62
|
||||
|
||||
- 다크 인증 페이지에서 `input`이 UA 기본색으로 남아 글자·아이콘이 안 보이던 문제를 `main.css`의 `.auth-form-input`(글자색·캐럿·placeholder·autofill)로 보정.
|
||||
- `AuthPasswordVisibilityToggle`은 Tailwind 의존을 줄이고 `scoped` CSS로 버튼·아이콘 크기·포커스 링을 고정.
|
||||
- signin/signup 루트에 `[color-scheme:dark]`, signup 패널에 `border`·`bg-[#0d1116]`(`auth-signup__panel`)로 카드 대비 보강.
|
||||
|
||||
## v0.0.61
|
||||
|
||||
- 로그인·회원가입 비밀번호 표시 토글을 `AuthPasswordVisibilityToggle`(Material 스타일 SVG 눈 아이콘)으로 통일, 텍스트 보기/숨기기 제거.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "sori.studio",
|
||||
"version": "0.0.61",
|
||||
"version": "0.0.62",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"imports": {
|
||||
|
||||
@@ -51,7 +51,7 @@ const submitSignIn = async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="auth-signin min-h-screen bg-[#0a0b0d] text-[#f5f7fa]">
|
||||
<section class="auth-signin min-h-screen bg-[#0a0b0d] text-[#f5f7fa] [color-scheme:dark]">
|
||||
<div class="mx-auto flex min-h-screen w-full max-w-[1280px] items-center px-5 py-12 sm:px-10 lg:px-16">
|
||||
<div class="w-full max-w-[430px] p-5 sm:p-8">
|
||||
<p class="text-2xl font-semibold leading-tight">
|
||||
@@ -66,7 +66,7 @@ const submitSignIn = async () => {
|
||||
<label class="text-xs text-[#d8dee6]">이메일</label>
|
||||
<input
|
||||
v-model="form.email"
|
||||
class="h-10 w-full rounded-[8px] border border-[#1a212a] bg-transparent px-3 text-sm outline-none transition-colors focus:border-[#2f6feb]"
|
||||
class="auth-form-input h-10 w-full rounded-[8px] border border-[#1a212a] bg-transparent px-3 text-sm outline-none transition-colors focus:border-[#2f6feb]"
|
||||
type="email"
|
||||
autocomplete="email"
|
||||
>
|
||||
@@ -77,7 +77,7 @@ const submitSignIn = async () => {
|
||||
<div class="flex items-center rounded-[8px] border border-[#1a212a] transition-colors focus-within:border-[#2f6feb]">
|
||||
<input
|
||||
v-model="form.password"
|
||||
class="h-10 min-w-0 flex-1 bg-transparent px-3 text-sm outline-none"
|
||||
class="auth-form-input h-10 min-w-0 flex-1 bg-transparent px-3 text-sm outline-none"
|
||||
:type="showPassword ? 'text' : 'password'"
|
||||
autocomplete="current-password"
|
||||
>
|
||||
|
||||
@@ -166,9 +166,9 @@ onBeforeUnmount(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="auth-signup min-h-screen bg-[#0a0b0d] text-[#f5f7fa]">
|
||||
<section class="auth-signup min-h-screen bg-[#0a0b0d] text-[#f5f7fa] [color-scheme:dark]">
|
||||
<div class="mx-auto flex min-h-screen w-full max-w-[1280px] items-start px-5 py-12 sm:px-10 sm:py-16 lg:px-16 lg:py-24">
|
||||
<div class="flex min-h-[calc(100vh-6rem)] w-full max-w-[430px] flex-col rounded-2xl p-5 sm:min-h-[calc(100vh-8rem)] sm:p-8 lg:min-h-[calc(100vh-12rem)]">
|
||||
<div class="auth-signup__panel flex min-h-[calc(100vh-6rem)] w-full max-w-[430px] flex-col rounded-2xl border border-[#1a212a] bg-[#0d1116] p-5 sm:min-h-[calc(100vh-8rem)] sm:p-8 lg:min-h-[calc(100vh-12rem)]">
|
||||
<div>
|
||||
<template v-if="currentStep === 1">
|
||||
<p class="text-[32px] font-semibold leading-tight sm:text-[40px]">
|
||||
@@ -192,7 +192,7 @@ onBeforeUnmount(() => {
|
||||
<label class="text-xs text-[#d8dee6]">사용자명</label>
|
||||
<input
|
||||
v-model="form.username"
|
||||
class="h-10 w-full rounded-[8px] border bg-transparent px-3 text-sm outline-none transition-colors"
|
||||
class="auth-form-input h-10 w-full rounded-[8px] border bg-transparent px-3 text-sm outline-none transition-colors"
|
||||
:class="errors.username ? 'border-[#b03b43]' : 'border-[#1a212a] focus:border-[#2f6feb]'"
|
||||
type="text"
|
||||
autocomplete="username"
|
||||
@@ -206,7 +206,7 @@ onBeforeUnmount(() => {
|
||||
<label class="text-xs text-[#d8dee6]">이메일</label>
|
||||
<input
|
||||
v-model="form.email"
|
||||
class="h-10 w-full rounded-[8px] border bg-transparent px-3 text-sm outline-none transition-colors"
|
||||
class="auth-form-input h-10 w-full rounded-[8px] border bg-transparent px-3 text-sm outline-none transition-colors"
|
||||
:class="errors.email ? 'border-[#b03b43]' : 'border-[#1a212a] focus:border-[#2f6feb]'"
|
||||
type="email"
|
||||
autocomplete="email"
|
||||
@@ -224,7 +224,7 @@ onBeforeUnmount(() => {
|
||||
>
|
||||
<input
|
||||
v-model="form.password"
|
||||
class="h-10 min-w-0 flex-1 bg-transparent px-3 text-sm outline-none"
|
||||
class="auth-form-input h-10 min-w-0 flex-1 bg-transparent px-3 text-sm outline-none"
|
||||
:type="showSignupPassword ? 'text' : 'password'"
|
||||
autocomplete="new-password"
|
||||
>
|
||||
@@ -243,7 +243,7 @@ onBeforeUnmount(() => {
|
||||
>
|
||||
<input
|
||||
v-model="form.passwordConfirm"
|
||||
class="h-10 min-w-0 flex-1 bg-transparent px-3 text-sm outline-none"
|
||||
class="auth-form-input h-10 min-w-0 flex-1 bg-transparent px-3 text-sm outline-none"
|
||||
:type="showSignupPasswordConfirm ? 'text' : 'password'"
|
||||
autocomplete="new-password"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user