Skip to content

[Design] Liquid Glass를 컨트롤 계층으로 정리하고 표면을 시스템 위계로 옮긴다 - #239

Merged
MinHeokChoi merged 5 commits into
mainfrom
design/#238-liquid-glass-surface-hierarchy
Sep 24, 2026
Merged

MinHeokChoi merged 5 commits into
mainfrom
design/#238-liquid-glass-surface-hierarchy

Conversation

@MinHeokChoi

Copy link
Copy Markdown
Contributor

Liquid Glass가 배경과 겉돌던 문제를 계층과 표면 위계 두 축에서 정리한다.

왜

유리를 콘텐츠(카드·목록)에 썼던 것이 첫 번째 원인이다. Apple은 유리를 콘텐츠
위에 떠 있는 내비게이션 계층 전용으로 규정한다. 이 선을 넘으면 무엇이 누를 수
있는 것이고 무엇이 내용인지 구별이 무너진다.

두 번째는 표면 위계다. 모루가 바탕(#F3F6FC)과 카드(흰색 + 1px 테두리)의 명도
관계를 직접 발명하고 있었는데, 시스템이 그리는 탭바 유리는 시스템 위계를
기준으로 자기를 그린다. 두 규칙이 어긋나니 유리가 겉돌 수밖에 없었다.

무엇을

표면을 시스템 위계로 — canvas/cardSurface/tileSurface를 각각
systemGroupedBackground/secondarySystemGroupedBackground/tertiarySystemFill로
옮기고, 표면을 한곳에서 정하는 MoruCard·MoruCanvasBackground를 세워 호출부를
이관했다. 위계가 이미 카드를 세우므로 테두리는 없앴다.

유리는 컨트롤 계층에만 — 카드에서 유리를 빼고, 대신 그동안 색면이나 카드로
그려져 있던 진짜 컨트롤에 유리를 줬다.

컨트롤 이전 이후
요일 선택기 평평한 회색 원 유리 원, 7개를 GlassEffectContainer로 묶음
온보딩 칩 회색 캡슐 유리 캡슐
"새 루틴 추가하기" 흰 카드 유리 버튼
토글 직접 그린 캡슐 시스템 Toggle
CTA 버튼 윤곽 없음 윤곽 추가

선택 상태에만 accent 틴트를 얹는다 — 틴트는 의미를 담을 때만 쓴다.

홈 바탕 — 파란 그라데이션(#E6EDFF→#F3F6FC) 위에 주황 글로우가 얹혀
서로 밀어내고 있었다. 글로우와 같은 계열(#FAF6F3)에서 시작해 아래로 내려가며
시스템 바탕과 만나게 했다.

옮기고 나서야 원인이 배경만이 아니었다는 것이 드러났다. 글로우 PNG 자체에 주황
중심 둘레로 회색-보라 링(#CBC7CD, 알파 0.46)이 박혀 있었다. 푸른 바탕에서는
섞여 보이지 않았지만 따뜻한 바탕에서는 얼룩으로 보였다. 브랜드 주황 하나에서
퍼지도록 코드로 그리는 MoruBrandGlow로 바꿨다. 완료 화면이 같은 자산을 쓰고
있어 함께 고쳐졌다.

테스트 쪽 변경 두 가지

색 게이트를 hex 핀에서 명도 위계 단언으로. 시스템 색의 hex를 못 박으면 값을
애플이 정하므로 다음 OS에서 이 테스트가 먼저 깨진다. "카드가 바탕보다 충분히
밝다"를 확인하도록 바꿨고, 예전 프로필 표면 버그(#F5F8FC vs #F3F6FC,
명도 차 1.9)도 이 검사에 걸린다.

시각 회귀 반복 임계값 8 → 14. 유리를 넓히자 같은 화면을 두 번 그린 결과가
9~11만큼 달라지기 시작했다. 대기 시간을 0.6→1.2초로 늘려도 그대로라 안정화
문제가 아니다. 유리를 새로 넣지 않은 완료 화면도 바탕색을 밝은 중립으로 옮긴
것만으로 넘쳤다 — 유리가 밝고 채도 낮은 배경을 샘플링할 때 디더링이 커진다.

감으로 올리지 않고 임계값을 0으로 두고 전체 시각 스위트를 3회 돌려 실측했다.
0이 아닌 비교 84건 중 절반이 1, 꼬리는 8·9·10에 9건, 관측 최대는 11이다. 같은
회차에서 실제 디자인 변경은 28~136으로 나와 잡음과 겹치지 않는다. 회귀 임계값
24는 그대로 두어 잡음(≤11)과 실제 변경(≥28) 사이에 선이 남는다.

검증

  • 전체 플랜 1,072개 통과 (3 skip, 0 실패)
  • 시각 기준선 10건 재승인 (거리 28~136)
  • 정적 게이트: 폴더 규약·iPhone 세로 기능·SwiftData 경계 통과
  • git diff --check 통과
  • 시뮬레이터(iOS 26.5) 4개 탭 + 루틴 수정 시트 육안 확인

실기기 확인은 아직이다. iPhone이 unavailable 상태라 연결되는 대로 올려서
확인한다.

알려진 남은 것

GlassEffectContainer는 요일 선택기 한 곳에서만 쓴다. 한 화면에 유리가 여럿
겹치는 다른 자리는 아직 없다.


Closes #238

🤖 Generated with Claude Code

MinHeokChoi and others added 4 commits September 16, 2026 13:36
화면마다 카드 배경·모서리·테두리를 직접 그리고 있었다. 표면을 한곳에서
정하는 MoruCard와 MoruCanvasBackground를 세우고 호출부를 옮긴다.

표면 값은 시스템이 정한 위계를 그대로 받는다.

  canvas      → systemGroupedBackground
  cardSurface → secondarySystemGroupedBackground
  tileSurface → tertiarySystemFill

브랜드 색으로 바탕과 카드의 명도 관계를 직접 발명하면, 시스템이 그리는 탭바
유리와 어긋난다. 탭바 유리는 시스템 위계를 기준으로 자기를 그리기 때문이다.
두 규칙이 다르면 유리가 겉돈다. 위계가 이미 카드를 세우므로 테두리는 두지
않는다.

유리를 어디에 쓸지도 정했다. 유리는 탭바·툴바·시트·버튼처럼 콘텐츠 위에 떠서
조작하는 것에만 쓴다. 목록·표·카드는 읽는 것이라 유리가 아니다. 이 선을
넘으면 무엇이 누를 수 있는 것이고 무엇이 내용인지 구별이 무너진다. 대신 유리
버튼에는 윤곽을 준다 — 없으면 배경이 밝을 때 경계가 녹아 어디까지가 누를 수
있는 곳인지 흐려진다.

색 게이트는 hex 핀 대신 명도 위계 단언으로 바꾼다. 시스템 색의 hex를 못 박으면
값을 애플이 정하므로 다음 OS에서 테스트가 먼저 깨진다. "카드가 바탕보다 충분히
밝다"를 확인하면 예전 프로필 표면 버그(#F5F8FC vs #F3F6FC, 명도 차 1.9)도
걸린다.

근거와 판단 기준은 docs/LiquidGlassRules.md에 남긴다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
같은 화면을 두 번 그린 결과의 허용 거리가 8이었다. 유리를 컨트롤 계층
전반으로 넓히자 9~11이 나오기 시작했다.

대기 시간을 0.6→1.2초로 늘려도 그대로라 안정화 문제가 아니다. 유리를 새로
넣지 않은 완료 화면도 바탕색을 밝은 중립으로 옮긴 것만으로 넘쳤다. 유리가
밝고 채도 낮은 배경을 샘플링할 때 디더링이 커진다 — 유리를 쓰는 한 계속
겪을 잡음이지 이번 변경만의 문제가 아니다.

감으로 올리지 않고 임계값을 0으로 두고 전체 시각 스위트를 3회 돌려 쟀다.
0이 아닌 비교 84건 중 절반이 1이고, 꼬리는 8·9·10에 9건, 관측 최대는 11이다.
같은 회차에서 실제 디자인 변경은 28~136으로 나와 잡음과 겹치지 않는다.
관측 최대에 여유를 둔 14로 잡는다. 회귀 임계값 24는 그대로 두어 잡음(≤11)과
실제 변경(≥28) 사이에 선이 남는다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
홈 바탕은 푸른 그라데이션(#E6EDFF → #F3F6FC)이었는데 그 위에 깔리는 인사말
글로우는 주황이다. 두 색이 서로 밀어내 겉돌았다. 글로우와 같은 계열로 아주
살짝만 기울인 중립(#FAF6F3)에서 시작해 아래로 내려가며 시스템 바탕과 만나게
했다. 글로우가 바탕을 밝히는 광원처럼 읽히고, 아래쪽은 다른 탭과 이어진다.

바탕을 옮기고 나서야 원인이 배경만이 아니었다는 것이 드러났다. 글로우 PNG
자체에 주황 중심 둘레로 회색-보라 링(#CBC7CD, 알파 0.46)이 박혀 있었다.
푸른 바탕에서는 섞여 보이지 않았지만 따뜻한 바탕에서는 얼룩으로 보였다.
브랜드 주황 하나에서 퍼지도록 코드로 그리는 MoruBrandGlow로 바꾼다. 바탕색이
무엇이든 회색이 끼어들지 않고 세기도 한곳에서 조절된다.

완료 화면이 같은 자산과 같은 푸른 그라데이션을 쓰고 있어 함께 옮겼다.

기준선 8건을 재승인한다(거리 52~136).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
유리 어휘가 탭바와 CTA 버튼에만 있었다. 누르는 것인데 색면이나 카드로
그려진 컨트롤이 남아 있어, 무엇이 조작하는 것이고 무엇이 내용인지 화면마다
다르게 말하고 있었다.

- 요일 선택기: 일곱 개가 나란한 세그먼트 컨트롤이다. 유리는 다른 유리를
  샘플링하지 못하므로 GlassEffectContainer로 묶어 샘플링 영역을 공유시킨다.
  선택 상태만 accent 틴트를 얹는다.
- 칩: 캡슐 유리. 선택 상태만 틴트.
- "새 루틴 추가하기": 읽는 카드가 아니라 누르는 것이다. 카드 표면 대신 유리로
  그린다. 유리 위에서는 disabled 회색이 사라져 글자를 한 단계 진하게 뒀다.
- 토글: 캡슐과 손잡이를 직접 그리던 것을 시스템 Toggle로 바꾼다. 탭바 유리와
  같은 출처에서 외형을 받아야 OS가 바뀔 때 함께 따라간다.

틴트는 의미를 담을 때만 쓴다는 규칙에 따라 선택 상태에만 색을 얹었다.
카드는 그대로 둔다 — 유리는 콘텐츠 위에 떠 있는 것에만 쓴다.

기준선 2건을 재승인한다(거리 28).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 926dafa5-f931-4562-a60d-141aaa4900b7


Comment @coderabbitai help to get the list of available commands.

@MinHeokChoi
MinHeokChoi merged commit 09d00d8 into main Sep 24, 2026
4 checks passed
@MinHeokChoi
MinHeokChoi deleted the design/#238-liquid-glass-surface-hierarchy branch September 24, 2026 00:30
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.

🎨 Design: Liquid Glass를 컨트롤 계층으로 정리하고 표면을 시스템 위계로 옮긴다

1 participant