깊이

무엇이 무엇 위에 놓이는지 정한다. 면의 층과 그림자, 쌓임 순서 셋이 같은 이야기를 다른 수단으로 한다.

layer-* 는 컨테이너의 표면색만 정의한다. 글자나 아이콘 같은 개별 요소가 아니라 화면의 캔버스를 만든다.

떠 있는 면 — layer-floating

바깥부터 basement → default → floating. 안쪽으로 갈수록 위에 있다.

토큰쓰는 곳
바닥--nui-layer-basement화면의 바닥. 앱이 쓰는 층이고 컴포넌트는 쓰지 않는다
기본--nui-layer-default카드 · 리스트 · 입력 컨트롤 표면. 대부분의 콘텐츠가 여기 놓인다
떠 있음--nui-layer-floating팝업 · Select 메뉴 · Datepicker 팝업
반전--nui-layer-inverse토스트 · 툴팁. 글자는 text-on-inverse
--nui-layer-overlay모달 뒤를 덮는 어두운 면
surface-* 는 층이 아니다. 콘텐츠 위에 얹는 톤(강조면 · 구분면)이라 역할이 다르다. 혼용하면 어느 것이 위인지 알 수 없게 된다.
라이트에서 같고 다크에서 갈리는 쌍이 있다. control-bglayer-floating 은 라이트에서 둘 다 gray-1 이라 헷갈려 써도 안 보이지만, 다크에서는 gray-2 와 gray-3 으로 갈린다. 그래서 자리로 정한다 — 입력 컨트롤 본체는 control-bg, 메뉴·팝업·달력은 layer-floating. 다크에서는 층이 올라갈수록 밝아진다.

그림자

1
2
3
press
토큰쓰는 곳
--nui-shadow-1낮게 뜸 — 카드, 인라인 드롭다운
--nui-shadow-2중간 — 팝오버, 메뉴, 달력
--nui-shadow-3최상단 — 모달, 토스트
--nui-shadow-press눌렸을 때 — 아래로 내려간 느낌
토큰비고
--nui-shadow-10 0.75rem 1.75rem rgb(17 24 39 / 6%)카드·인라인 드롭다운
--nui-shadow-20 1.125rem 2.5rem rgb(17 24 39 / 8%)팝오버·메뉴·달력
--nui-shadow-30 1.125rem 3rem rgb(17 24 39 / 14%)모달·토스트
--nui-shadow-ring-brand0 0 0 0.25rem var(--nui-color-brand-a4)
--nui-shadow-ring-error0 0 0 0.25rem var(--nui-color-danger-a4)
--nui-shadow-press0 0.5rem 1rem rgb(17 24 39 / 12%)
--nui-shadow-thumb0 0.125rem 0.375rem rgb(15 23 42 / 18%)
--nui-shadow-inset-softinset 0 1px 0 rgb(255 255 255 / 76%)
--nui-shadow-inset-inverseinset 0 1px 0 rgb(255 255 255 / 8%)
shadow-ring-* · shadow-thumb · shadow-inset-* 은 컴포넌트 내부 전용이다. 고도를 나타내지 않으므로 위 미리보기에 없다.
포커스 링은 그림자가 아니다. 생김새가 비슷하지만 그림자는 높이를, 링은 상태를 나타낸다. 그래서 shadow-* 가 아니라 focus-ring-* 이다. 고르는 기준은 접근성 문서에 있다.

쌓임 순서

z-index 를 직접 쓰지 않고 이 다섯 개 안에서 고른다. 값을 직접 쓰기 시작하면 숫자 경쟁이 벌어진다.

토큰비고
--nui-z-tooltip20제자리 툴팁 — 자기 부모 안에서만
--nui-z-overlay-layer1030
--nui-z-portal-menu1031portal 로 body 에 붙는 드롭다운·달력 — 팝업(1030) 안에서도 보여야 한다
--nui-z-toast1031팝업보다 위 — 팝업 안에서 띄운 토스트도 보여야 한다
--nui-z-tooltip-portal1032
토큰왜 그 값인가
--nui-z-tooltip제자리 툴팁 — 자기 부모 안에서만 떠 있으면 된다
--nui-z-overlay-layer팝업과 그 딤
--nui-z-portal-menu팝업보다 위. 팝업 안에서 연 셀렉트와 달력이 팝업에 가리면 안 된다
--nui-z-toast팝업 안에서 띄운 토스트도 보여야 한다
--nui-z-tooltip-portal가장 위. hasPortal 로 body 에 나간 툴팁이다. 지금 가리키고 있는 것의 설명이라 무엇에도 가리면 안 된다
팝업끼리는 나중에 연 것이 위다. 값을 나누지 않는다. Alert 이 열린 BottomSheet 위에 오는 것은 이 순서의 결과다. 반대로 Alert 위로 시트를 여는 것은 흐름 오류다.
body 로 나가는 것끼리는 서로를 죽이지 않는다. 팝업이 열리면 배경을 격리하려고 body 의 직계 자식을 전부 inert 처리한다. 토스트 · 툴팁 · 로딩 알림 컨테이너도 body 의 직계 자식이라, 표시가 없으면 z 는 팝업 위인데 눌리지도 읽히지도 않는 상태가 된다. 우리 컨테이너에는 data-nui-portal-root 가 붙어 격리에서 빠진다.
겹친다고 값을 올리지 않는다. 새 값이 필요해 보이면 대개는 쌓임 맥락(stacking context)이 잘못 잡힌 것이다. 부모에 transform 이나 opacity 가 걸려 있으면 자식의 z-index 는 그 맥락 안에 갇힌다. 숫자를 키워도 소용없다.