@use "sass:map"; @use "functions"; @use "tokens"; /// PC 이상(>= 768px). 미디어 쿼리 조건부는 `var()`를 해석하지 못해 브레이크포인트만 /// 컴파일타임 값이고, 그래서 이 믹스인 경유가 강제된다. @mixin pc { @media (min-width: tokens.$breakpoint-pc) { @content; } } /// PC 미만. `pc`와 경계가 겹치지 않도록 0.02px을 뺀다. @mixin mobile { @media (max-width: tokens.$breakpoint-pc - 0.02px) { @content; } } /// 이름 붙은 브레이크포인트 이상에서 적용 — `xsm`(768) · `sm`(1024) · `default`(1440). /// 같은 이름의 `grid-wrap-*`이 그 폭의 컨테이너다. @mixin from($name) { @if not map.has-key(tokens.$breakpoints, $name) { @error "[@fox] 알 수 없는 브레이크포인트: `#{$name}` — 사용 가능한 값: #{map.keys(tokens.$breakpoints)}"; } @media (min-width: map.get(tokens.$breakpoints, $name)) { @content; } } /// 스크롤바 외형 — 시안 `scroll`(7341:2675). 스크롤이 생기는 요소에 붙인다. 넘침 여부는 /// 정하지 않는다 — `overflow`는 붙이는 쪽이 이미 갖고 있다. /// /// 막대는 4px이고 둘레에 4px 여백이 있다. 여백을 트랙 `padding`으로 주면 막대가 끝까지 /// 가지 못해, 막대에 투명 테두리를 둘러 안쪽으로만 들어가게 한다. /// /// 웹킷 계열은 `::-webkit-scrollbar`로 시안대로 그리고, 그 의사요소가 없는 Firefox는 표준 /// 속성으로 근사한다(두께가 `thin` 한 단계뿐이고 모서리는 정할 수 없다). 두 경로를 같이 쓰면 /// Chrome 121+가 표준 속성을 보고 웹킷 규칙을 통째로 무시하므로 `@supports`로 갈라 놓는다. /// /// 웹킷 의사요소는 표준이 아니라 논리 속성(`inline-size`)을 받지 않아 물리 속성으로 적는다. @mixin scroll { &::-webkit-scrollbar { width: calc(#{functions.number(3)} + #{functions.padding(2)} * 2); height: calc(#{functions.number(3)} + #{functions.padding(2)} * 2); } &::-webkit-scrollbar-track, &::-webkit-scrollbar-corner { background: transparent; } &::-webkit-scrollbar-thumb { border: functions.padding(2) solid transparent; border-radius: functions.radius(max); background-color: functions.color(element-neutral-alpha); background-clip: padding-box; } @supports not selector(::-webkit-scrollbar) { scrollbar-width: thin; scrollbar-color: functions.color(element-neutral-alpha) transparent; } }