File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
// 개발 전용 테스트 페이지 스타일.
//
// 이 파일 자체가 토큰 규율의 첫 소비처다 — 여기 있는 모든 값은 `fox.*()` 함수를 거치므로,
// 없는 토큰을 쓰면 빌드가 실패한다. 페이지가 그려진다는 것은 사용된 토큰이 전부 실재한다는
// 뜻이기도 하다.
@use "@fox/styles/abstracts" as fox;
.shell {
display: grid;
grid-template-columns: 1fr;
min-block-size: 100vh;
background: fox.color(background-default);
color: fox.color(font-neutral-default);
@include fox.pc {
grid-template-columns: 26rem 1fr;
}
}
.loading {
padding: fox.padding(8);
color: fox.color(font-neutral-subtle);
font-size: fox.font-size(body-md);
}
// ── 사이드바 ────────────────────────────────────────────────────────────────
.sidebar {
display: flex;
flex-direction: column;
gap: fox.gap(5);
padding: fox.padding(7);
border-block-end: fox.border(1) solid fox.color(border-neutral-subtle);
background: fox.color(surface-neutral-gray);
@include fox.pc {
position: sticky;
inset-block-start: 0;
block-size: 100vh;
overflow-y: auto;
border-block-end: 0;
border-inline-end: fox.border(1) solid fox.color(border-neutral-subtle);
}
}
.brand {
display: flex;
flex-direction: column;
gap: fox.gap(1);
}
.brandTitle {
font-size: fox.font-size(heading-sm);
font-weight: fox.font-weight(bold);
}
.brandNote {
color: fox.color(font-neutral-subtler);
font-size: fox.font-size(label-xsm);
}
.themeSwitch {
display: flex;
gap: fox.gap(1);
padding: fox.padding(1);
border: fox.border(1) solid fox.color(border-neutral-default);
border-radius: fox.radius(max);
background: fox.color(surface-neutral-default);
}
.themeButton {
flex: 1;
padding: fox.padding(3) fox.padding(4);
border-radius: fox.radius(max);
color: fox.color(font-neutral-subtle);
font-size: fox.font-size(label-xsm);
font-weight: fox.font-weight(medium);
&[aria-pressed="true"] {
background: fox.color(button-primary-surface);
color: fox.color(button-primary-font);
}
&:focus-visible {
outline: fox.border(2) solid fox.color(border-theme-primary);
outline-offset: fox.border(2);
}
}
.nav {
display: flex;
flex-direction: column;
gap: fox.gap(6);
}
.navGroup {
display: flex;
flex-direction: column;
gap: fox.gap(2);
}
.navGroupTitle {
padding-inline: fox.padding(3);
color: fox.color(font-neutral-subtler);
font-size: fox.font-size(label-xsm);
font-weight: fox.font-weight(bold);
letter-spacing: 0.04em;
}
.navList {
display: flex;
flex-direction: column;
gap: fox.gap(1);
margin: 0;
padding: 0;
list-style: none;
}
.navItem {
display: flex;
inline-size: 100%;
align-items: center;
justify-content: space-between;
gap: fox.gap(3);
padding: fox.padding(3) fox.padding(4);
border-radius: fox.radius(3);
color: fox.color(font-neutral-subtle);
font-size: fox.font-size(label-sm);
text-align: start;
&:hover {
background: fox.color(button-default-surface-hover);
color: fox.color(font-neutral-default);
}
&[aria-current="page"] {
background: fox.color(button-primary-surface);
color: fox.color(button-primary-font);
}
&:focus-visible {
outline: fox.border(2) solid fox.color(border-theme-primary);
outline-offset: fox.border(1);
}
}
.navCount {
color: currentcolor;
font-size: fox.font-size(label-xsm);
opacity: 0.7;
}
// ── 본문 ────────────────────────────────────────────────────────────────────
.content {
min-inline-size: 0;
padding: fox.spacing(top-md) fox.padding(7) fox.spacing(bottom-xlg);
@include fox.pc {
padding: fox.spacing(top-lg) fox.padding(11) fox.spacing(bottom-xlg);
}
}
.section {
display: flex;
flex-direction: column;
}
.sectionTitle {
font-size: fox.font-size(heading-md);
font-weight: fox.font-weight(bold);
}
.sectionNote {
margin-block: fox.gap(2) fox.gap(6);
color: fox.color(font-neutral-subtle);
font-size: fox.font-size(body-sm);
}
.code {
overflow-x: auto;
margin-block-start: fox.gap(4);
padding: fox.padding(6);
border: fox.border(1) solid fox.color(border-neutral-subtle);
border-radius: fox.radius(3);
background: fox.color(surface-neutral-gray);
color: fox.color(font-neutral-default);
font-size: fox.font-size(body-sm);
}
// ── 색상 스와치 ─────────────────────────────────────────────────────────────
.swatchGrid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(22rem, 1fr));
gap: fox.gap(4);
}
.swatch {
overflow: hidden;
border: fox.border(1) solid fox.color(border-neutral-subtle);
border-radius: fox.radius(3);
background: fox.color(surface-neutral-default);
}
.swatchChip {
block-size: fox.icon(7);
border-block-end: fox.border(1) solid fox.color(border-neutral-overlay);
}
.swatchMeta {
padding: fox.padding(5);
}
.tokenName {
display: block;
color: fox.color(font-neutral-default);
font-size: fox.font-size(label-sm);
font-weight: fox.font-weight(medium);
word-break: break-all;
}
.tokenValue {
display: block;
margin-block-start: fox.gap(1);
color: fox.color(font-neutral-subtler);
font-size: fox.font-size(body-xsm);
word-break: break-all;
}
// ── 값 테이블 ───────────────────────────────────────────────────────────────
.table {
inline-size: 100%;
border-collapse: collapse;
text-align: start;
}
.table th,
.table td {
padding: fox.padding(3) fox.padding(5);
border-block-end: fox.border(1) solid fox.color(border-neutral-subtle);
}
.table th {
color: fox.color(font-neutral-subtler);
font-size: fox.font-size(label-xsm);
font-weight: fox.font-weight(medium);
}
.table td {
color: fox.color(font-neutral-default);
font-size: fox.font-size(body-sm);
}
.tdValue {
color: fox.color(font-neutral-subtle);
}
// 미리보기 칸은 내용만큼만 차지하게 두어 토큰/값 열이 밀리지 않게 한다.
.tdDemo {
inline-size: 1%;
white-space: nowrap;
}
// ── 서체 미리보기 ───────────────────────────────────────────────────────────
.typeList {
display: flex;
flex-direction: column;
}
.typeRow {
display: flex;
flex-wrap: wrap;
gap: fox.gap(2) fox.gap(7);
align-items: baseline;
padding-block: fox.padding(5);
border-block-end: fox.border(1) solid fox.color(border-neutral-subtle);
}
.typeMeta {
display: flex;
flex: 0 0 22rem;
flex-direction: column;
gap: fox.gap(1);
}
.typeSample {
min-inline-size: 20rem;
flex: 1;
margin: 0;
color: fox.color(font-neutral-default);
}
// ── 패딩 · 간격 미리보기 ────────────────────────────────────────────────────
// 점선 테두리와 옅은 바탕이 "토큰이 만든 공간"이고, 흰 칩이 문단이다.
.demoPadBox,
.demoGapBox {
border: fox.border(1) dashed fox.color(border-theme-primary);
background: fox.color(surface-theme-primary);
}
.demoPadBox {
display: inline-block;
}
.demoGapBox {
display: inline-flex;
align-items: center;
}
.demoText {
margin: 0;
padding: fox.padding(1) fox.padding(3);
background: fox.color(surface-neutral-default);
color: fox.color(font-neutral-default);
font-size: fox.font-size(label-xsm);
white-space: nowrap;
}
// ── 모서리 반경 · 테두리 두께 미리보기 ──────────────────────────────────────
.demoRadius,
.demoBorder {
inline-size: fox.icon(7);
block-size: fox.icon(7);
border-color: fox.color(border-theme-primary);
border-style: solid;
background: fox.color(surface-neutral-gray);
}
.demoRadius {
border-width: fox.border(2);
}
// ── 아이콘 크기 미리보기 ────────────────────────────────────────────────────
// 브라우저 기본 체크박스를 토큰 크기로 키운다 — 별도 에셋 없이 크기만 비교한다.
.demoIcon {
display: block;
margin: 0;
accent-color: fox.color(surface-theme-primary);
}
// ── 그림자 미리보기 ─────────────────────────────────────────────────────────
// 그림자 색은 Figma에 토큰이 없어 중립 알파 토큰을 데모용으로 쓴다.
// 인라인 style이 참조할 수 있도록 여기서 커스텀 프로퍼티로 내려둔다.
.demoShadow {
--demo-shadow-color: #{fox.color(alpha-default-inverse25)};
inline-size: fox.icon(7);
block-size: fox.icon(6);
border-radius: fox.radius(2);
background: fox.color(surface-neutral-default);
}
// ── 배경 흐림 미리보기 ──────────────────────────────────────────────────────
// 캔버스 크기는 디자인 값이 아니라 데모용 지면이라 토큰을 두지 않는다.
.demoBackdrop {
position: relative;
overflow: hidden;
inline-size: 20rem;
block-size: 12rem;
border-radius: fox.radius(2);
}
.demoBackdropImage {
display: block;
inline-size: 100%;
block-size: 100%;
object-fit: cover;
}
.demoBackdropOverlay {
position: absolute;
inset-block: 0;
inset-inline-end: 0;
inline-size: 50%;
border-inline-start: fox.border(1) solid fox.color(border-neutral-overlay);
}
// ── 컴포넌트 예제 ───────────────────────────────────────────────────────────
.variantList {
display: flex;
flex-direction: column;
gap: fox.gap(5);
}
.variant {
display: flex;
flex-direction: column;
gap: fox.gap(2);
}
.variantLabel {
color: fox.color(font-neutral-subtler);
font-size: fox.font-size(label-xsm);
font-weight: fox.font-weight(medium);
}
// 예제를 얹는 무대. 컴포넌트 자체의 배경·여백과 섞이지 않도록 중립 표면 위에 올린다.
.variantStage {
display: flex;
flex-wrap: wrap;
gap: fox.gap(4);
align-items: center;
padding: fox.padding(7);
border: fox.border(1) solid fox.color(border-neutral-subtle);
border-radius: fox.radius(3);
background: fox.color(surface-neutral-default);
}