// 디자인 시스템 카탈로그 스타일. // // 토큰 목록은 이 파일이 아니라 **CSSOM에서 런타임에 읽는다**(`_components/token-catalog.tsx`). // SCSS 값을 JS로 내보내는 CSS Modules의 `:export`를 처음 썼으나, Next.js 16의 기본 // 번들러인 Turbopack은 Lightning CSS로 CSS를 파싱해 `:export`(webpack css-loader 시절의 // ICSS 확장)를 인식하지 못한다 — 빌드는 통과하지만 규칙이 통째로 버려져 값이 `undefined`가 // 된다. `--fox-*` 커스텀 프로퍼티를 CSSOM에서 직접 열거하면 같은 "목록을 두 곳에 두지 // 않는다"는 목적을 번들러 의존 없이 달성한다. @use "@fox/styles/abstracts" as fox; .page { flex: 1; padding: fox.space(8) fox.space(6); @include fox.container(xl, 6); } .header { display: flex; flex-wrap: wrap; gap: fox.space(4); align-items: baseline; justify-content: space-between; padding-block-end: fox.space(6); border-block-end: 1px solid fox.color(border); } .title { @include fox.typo(headline-lg); } .lede { margin-block-start: fox.space(2); color: fox.color(foreground-muted); @include fox.typo(body-md); } // ── 테마 전환 ─────────────────────────────────────────────────────────────── .themeSwitch { display: flex; gap: fox.space(1); padding: fox.space(1); border: 1px solid fox.color(border); border-radius: fox.radius(full); background: fox.color(surface-muted); } .themeButton { padding: fox.space(2) fox.space(4); border-radius: fox.radius(full); color: fox.color(foreground-muted); @include fox.typo(label-md); @include fox.focus-ring; @include fox.transition((background-color, color)); &[aria-pressed="true"] { background: fox.color(primary); color: fox.color(on-primary); } } .section { padding-block: fox.space(8); border-block-end: 1px solid fox.color(border-subtle); } .sectionTitle { margin-block-end: fox.space(1); @include fox.typo(title-lg); } .sectionNote { margin-block-end: fox.space(5); color: fox.color(foreground-muted); @include fox.typo(body-sm); } .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr)); gap: fox.space(4); } // ── 색상 ──────────────────────────────────────────────────────────────────── .swatch { overflow: hidden; border: 1px solid fox.color(border); border-radius: fox.radius(md); background: fox.color(surface); } .swatchChip { block-size: 6.4rem; } .swatchMeta { padding: fox.space(3); } .name { display: block; color: fox.color(foreground); word-break: break-all; @include fox.typo(label-lg); } .ref { display: block; margin-block-start: fox.space(1); color: fox.color(foreground-subtle); font-family: fox.font(mono); word-break: break-all; @include fox.typo(body-sm); } // ── 타이포 ────────────────────────────────────────────────────────────────── .typoRow { display: flex; flex-wrap: wrap; gap: fox.space(2) fox.space(6); align-items: baseline; padding-block: fox.space(3); border-block-end: 1px solid fox.color(border-subtle); } .typoName { flex: 0 0 14rem; color: fox.color(foreground-subtle); font-family: fox.font(mono); @include fox.typo(body-sm); } .typoSample { flex: 1; min-inline-size: 20rem; } // ── 간격 ──────────────────────────────────────────────────────────────────── .spaceRow { display: flex; gap: fox.space(4); align-items: center; padding-block: fox.space(2); } .spaceBar { block-size: 1.6rem; border-radius: fox.radius(xs); background: fox.color(primary); } // ── radius · shadow ───────────────────────────────────────────────────────── .tile { display: flex; block-size: 9.6rem; align-items: center; justify-content: center; border: 1px solid fox.color(border); background: fox.color(surface); color: fox.color(foreground-muted); @include fox.typo(label-md); } .shadowTile { display: flex; block-size: 9.6rem; align-items: center; justify-content: center; border-radius: fox.radius(lg); background: fox.color(surface); color: fox.color(foreground-muted); @include fox.typo(label-md); } .shadowCell { padding: fox.space(4); } // ── 값 테이블 ─────────────────────────────────────────────────────────────── .table { inline-size: 100%; text-align: start; } .table th, .table td { padding: fox.space(2) fox.space(3); border-block-end: 1px solid fox.color(border-subtle); } .table th { color: fox.color(foreground-muted); @include fox.typo(label-md); } .table td { font-family: fox.font(mono); @include fox.typo(body-sm); }