Skip to content

feat: 라이트 모드 도입과 디자인 토큰 테마 분리 - #148

Open
eun-yeon wants to merge 11 commits into
mainfrom
feat/light-theme
Open

feat: 라이트 모드 도입과 디자인 토큰 테마 분리#148
eun-yeon wants to merge 11 commits into
mainfrom
feat/light-theme

Conversation

@eun-yeon

Copy link
Copy Markdown
Member

개요

앱 UI에 라이트 모드를 넣음. 색을 반전한 것이 아니라 다크 팔레트의 실측 단차를 밝은 쪽에서 재현했고, 그 과정에서 토큰 체계를 테마별로 나눠 라이트 값 누락이 조용히 다크로 새지 않게 구조로 막음. 설정 미리보기 클립도 라이트 한 벌을 렌더해 붙임

변경 내용

토큰 구조

  • tokens.css를 배럴로 바꾸고 tokens/{base,dark,light}.css 3분할
  • 다크를 bare :root 폴백으로 두지 않음. 라이트 토큰이 빠지면 미정의가 되어 즉시 드러나고, 세 창 html의 data-theme 정적 속성이 미정의를 막음
  • 선택자를 :root:where([data-theme='...'])로 잡아 뒤에 주입되는 사용자 CSS의 :root 재정의와 특이도 동률 유지
  • 파리티 계약 테스트로 두 테마의 키 집합과 선언 순서 일치, base에 색 없음, tailwind와 소스가 참조하는 모든 --ui-*가 양쪽에 존재함을 고정

라이트 팔레트

면 관계를 다크 실측 ΔL*로 맞춤

면 관계 다크 라이트
상하단 크롬 -> 캔버스 +3.9 +5.7
패널 유리 -> 카드 +4.0 +3.4
캔버스 -> 격자선 +6.9 -6.0
유리 -> 둘레 링 +8.2 -7.7
유리 -> 상단 립 +3.3 +2.9
  • 크롬과 캔버스만 폭을 넓힘. 다크는 두 면의 휘도비가 1.67배라 작은 ΔL*로도 갈리는데 밝은 쪽은 1.1배도 안 나옴
  • 카드가 뜨는 방향이 유일한 구조적 반전. --ui-fill-faint만 흰 알파를 쓰고, 조작면인 --ui-fill 계열은 라이트에서도 잉크가 늘어나는 방향을 유지
  • 유리의 밝기 바닥은 틴트 알파가 소유. brightness(>1)은 대응물이 아님. sRGB 곱연산이라 검정은 곱해도 검정이고 밝은 쪽만 먼저 포화하므로, 범위를 좁히는 contrast(<1) 항을 필터 체인에 추가
  • 립은 하이브리드. 둘레 링은 어두운 잉크로 뒤집고 상단 하이라이트는 흰색 유지. 테마가 바뀐다고 광원 방향이 뒤집히지는 않음
  • 읽어야 하는 --ui-fg-caption과 장식용 --ui-fg-faint 분리. 밝은 바탕에서는 대비비가 빠르게 압축돼 한 값으로 묶으면 앱 바닥의 작은 글자를 살릴 때 muted와 뭉침

테마 전환

  • system, light, dark 3단이고 기본값은 system
  • 부트 스크립트가 첫 페인트 전에 테마를 확정하고, store 초기값도 같은 캐시를 읽어 첫 렌더에서 어긋나지 않음
  • 분리 패널 자식 문서에 테마 전파. 스타일 미러링은 head 노드만 옮기고 html 속성은 따라가지 않음
  • 네이티브 패널 크롬 재동기화. head 옵저버는 html 속성 변경을 보지 못함
  • 파형처럼 토큰을 구워 그리는 캔버스는 전환 시 재드로우

백엔드

  • ui_theme 스칼라 설정. 프리셋 화이트리스트와 히스토리 스냅샷에서 제외해 프리셋 로드와 Undo가 테마를 건드리지 않음
  • 창별 set_theme. 메인과 분리 패널만 적용하고 투명 창인 오버레이는 제외
  • 첫 페인트 배경색은 숨긴 창을 만든 뒤 테마를 해석해 지정하고 표시. OS 테마 변경도 추종
  • Windows 첫 프레임 씨앗 색 테마 분기

설정 미리보기 클립

  • 라이트 9종 렌더. 구성과 모션과 길이는 다크와 완전히 같고 색만 다름
  • 무대 바닥만 중간 회색. 흰 무대에서는 눌림 피드백 대비가 ΔL* 80.7에서 8.8로 무너져 키를 눌러도 아무 일도 안 일어난 것처럼 보임
  • 무대 위에 그리는 윤곽선은 주변 콘텐츠와 반대 방향으로 감. 대비비만 맞추면 어두운 키 무리에 섞여 배경 무늬로 읽힘
  • 렌더 워크스페이스는 .gitignore 규약대로 로컬 전용이라 결과 mp4만 포함

접근성

  • 아이콘 버튼에 접근성 이름 추가. ariaLabel을 필수 prop으로 만들어 누락을 컴파일 단계에서 막음
  • 최신 버전 모달의 화면 제목과 dialog 이름 불일치 수정

검증

  • Vitest 3,145 통과, 18 스킵, 실패 0
  • Rust lib 935 통과, main 933 통과, 실패 0
  • 타입, 포맷, 린트, cargo check, clippy, cargo fmt --check 통과
  • 팔레트 값은 계산으로 끝내지 않고 실제 토큰 파일을 불러오는 화면을 렌더해 눈으로 확인하며 세 차례 재보정

남은 것

  • macOS 트래픽 라이트 외관과 OS 테마 실시간 전환 실기 확인
  • Windows 첫 프레임 씨앗 색 실기 확인. 해당 테스트는 Windows 전용이라 macOS에서는 실행되지 않음
  • 라이트 클립 재생 확인

@eun-yeon

Copy link
Copy Markdown
Member Author

리베이스 필수

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant