임동욱 임동욱 07-28
style: 테마 전환 색상 트랜지션 추가
Co-Authored-By: Claude Opus 5 
@f38d15fecfc99a6e048a50b6b11d0da34c689964
app/globals.css
--- app/globals.css
+++ app/globals.css
@@ -253,6 +253,39 @@
    정확히 일치한다: xs→p-1, sm→p-2, md→p-3, lg→p-4, xl→p-5, xxl→p-6,
    xxxl→p-8, xxxxl→p-10. */
 
+/* 테마 수동 전환 — feature 소비처(예: 헤더 테마 토글)를 위한 CSS 구동 변형자.
+   design 계획 §9 게이트 교차 검증에서 feature 안(아이콘 3개를 모두 DOM에 렌더하고
+   CSS만으로 하나를 표시)을 채택했다 — 서버/클라 출력이 항상 동일해 hydration
+   불일치 표면적이 0이다. `theme-light`/`theme-dark`는 명시적 선택에만 매칭되고,
+   `theme-system`은 data-theme 부재 **및** 명시적 data-theme="system" 값 둘 다
+   커버해야 하므로(둘은 동일하게 동작 — feature 전달 사양) 부정 선택자 두 개로
+   "light도 dark도 아님"을 표현한다(속성 부재 시에도 :not()은 매칭된다). */
+@custom-variant theme-system (&:where(html:not([data-theme="light"]):not([data-theme="dark"]) *));
+@custom-variant theme-light (&:where(html[data-theme="light"] *));
+@custom-variant theme-dark (&:where(html[data-theme="dark"] *));
+
+/* 테마 전환 색상 트랜지션 — feature가 토글 직전 <html>에 [data-theme-transition]을
+   부여하고 ~200ms 후 제거하는 시간 한정 opt-in이다(상시 트랜지션이 아니므로 다른
+   hover/트랜지션 유틸과 경쟁하지 않는다). prefers-reduced-motion: no-preference로
+   게이팅해 감소 모션 환경에서는 아무 트랜지션도 걸리지 않는다(전환 없이 즉시 반영).
+   !important는 유틸리티의 transition 계열 클래스(transition-none 포함)가 이 200ms
+   동안만 존재하는 규칙을 덮어쓰지 않도록 한다. box-shadow는 제외 — --shadow 토큰은
+   테마별로 값이 바뀌지 않아 전환할 대상이 없다. */
+@media (prefers-reduced-motion: no-preference) {
+  html[data-theme-transition],
+  html[data-theme-transition] *,
+  html[data-theme-transition] *::before,
+  html[data-theme-transition] *::after {
+    transition:
+      background-color 200ms var(--ease-out),
+      border-color 200ms var(--ease-out),
+      color 200ms var(--ease-out),
+      fill 200ms var(--ease-out),
+      stroke 200ms var(--ease-out),
+      outline-color 200ms var(--ease-out) !important;
+  }
+}
+
 body {
   background: var(--background);
   color: var(--foreground);
Add a comment
List