diff --git a/.Jules/palette.md b/.Jules/palette.md index 7fb6a23..d302348 100644 --- a/.Jules/palette.md +++ b/.Jules/palette.md @@ -17,3 +17,7 @@ ## 2024-07-10 - prefers-reduced-motion 지원 추가 **Learning:** 시스템 레벨에서 애니메이션 줄이기(prefers-reduced-motion)를 설정한 사용자를 위해 과도한 애니메이션과 부드러운 스크롤을 비활성화하는 것이 필요합니다. 이때 `0s` 대신 `0.01ms`를 사용하여 `transitionend`와 같은 브라우저 이벤트가 정상적으로 발생하도록 해야 자바스크립트 콜백이 멈추는(hanging) 문제를 방지할 수 있습니다. **Action:** 항상 `styles.css` 하단에 `prefers-reduced-motion: reduce` 미디어 쿼리를 추가하여 모든 요소의 `animation-duration`과 `transition-duration`을 `0.01ms`로 설정하고 `scroll-behavior: auto`를 적용합니다. + +## 2026-08-02 - 버튼 클릭 시 시각적(촉각적) 피드백 제공 +**Learning:** 인터랙티브 요소(버튼, 언어 전환기 등)를 클릭할 때 상태 변화(active state)가 없으면 사용자가 클릭이 성공적으로 입력되었는지 직관적으로 인지하기 어렵습니다. +**Action:** 사용자와 상호작용하는 버튼이나 링크 요소에는 `:active` 가상 클래스를 활용해 `transform: scale(...)`과 같은 미세하고 부드럽게 축소되는 애니메이션을 적용하여 확실한 촉각적/시각적 피드백을 제공합니다. diff --git a/CHANGELOG.md b/CHANGELOG.md index 56ad628..28daac5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # CHANGELOG ## [Unreleased] +- **UX/접근성 개선**: 버튼(`.button`) 및 언어 전환 버튼(`.language-switch button`) 클릭 시 미세하게 축소되는 시각적 피드백(`:active` 상태)을 추가하여 인터랙션의 직관성을 높였습니다. - **보안 개선**: 컴포넌트 갤러리의 인라인 스크립트와 스타일을 외부 파일로 분리하고, 엄격한 Content-Security-Policy를 적용해 XSS 방어를 강화했습니다. - **성능 회귀 복원**: 오프스크린 `.section` 렌더링을 `content-visibility: auto`로 지연하고, 일반 섹션은 600px·콘텐츠가 큰 DIKW/projects 섹션은 1000px의 `contain-intrinsic-size` placeholder를 유지해 초기 렌더링 비용과 스크롤바 이동을 함께 줄였습니다. - **보안 개선**: Trusted Types 기반 CSP 강화: 잠재적인 DOM 기반 XSS 공격을 방지하기 위해 `require-trusted-types-for 'script'` 지시어 추가 diff --git a/styles.css b/styles.css index 02cfeb6..a6060ba 100644 --- a/styles.css +++ b/styles.css @@ -108,7 +108,11 @@ a { font-size: 13px; font-weight: 850; cursor: pointer; - transition: opacity 0.2s; + transition: opacity 0.2s, transform 0.1s cubic-bezier(0.4, 0, 0.2, 1); +} + +.language-switch button:active { + transform: scale(0.96); } .language-switch button:not([aria-pressed="true"]):hover { @@ -218,7 +222,11 @@ h1 { text-decoration: none; font-size: 15px; font-weight: 800; - transition: opacity 0.2s; + transition: opacity 0.2s, transform 0.1s cubic-bezier(0.4, 0, 0.2, 1); +} + +.button:active { + transform: scale(0.96); } .button:hover { diff --git a/tests/test_ux_styles.py b/tests/test_ux_styles.py new file mode 100644 index 0000000..5edf8fd --- /dev/null +++ b/tests/test_ux_styles.py @@ -0,0 +1,13 @@ +"""Regression tests for UX-focused CSS styles.""" + +import re +from pathlib import Path + +STYLES = Path(__file__).resolve().parents[1] / "styles.css" + +def test_buttons_have_active_state_for_tactile_feedback(): + """Ensure buttons provide tactile feedback on click.""" + css = STYLES.read_text(encoding="utf-8") + assert ".button:active" in css + assert ".language-switch button:active" in css + assert "transform: scale(0.96);" in css