// 개발 전용 테스트 페이지 스타일. // // 이 파일 자체가 토큰 규율의 첫 소비처다 — 여기 있는 모든 값은 `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); } // 크기 토큰을 눈으로 비교하기 위한 막대. 폭은 인라인 style이 토큰을 참조해 넣는다. .bar { display: block; block-size: fox.icon(2); border-radius: fox.radius(1); background: fox.color(surface-theme-primary); } // ── 컴포넌트 예제 ─────────────────────────────────────────────────────────── .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); }