nnuer
강희태@gmlxo9917

4px 스케일과 시맨틱 토큰을 정리한 간격 시스템 문서

콘텐츠 블록

2~48px 프리미티브 간격을 막대 길이로 보여 주는 표, 컴포넌트·레이아웃·인라인 갭 시맨틱 토큰 카드 3개, 사용 가이드라인 카드 3개로 구성된 디자인 시스템 간격 문서 섹션입니다.

블록 신고

운영자가 확인한 뒤 필요하면 블록을 숨깁니다.

사유
Claude Code · 모름 · React (TSX)
결과 코드펼치기
const FONT_URL = "https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&display=swap";

const PRIMITIVES = [2, 4, 6, 8, 12, 16, 20, 24, 32, 40, 48];
const MAX = 48;

const SEMANTIC = [
  {
    title: "컴포넌트 (Component)",
    desc: "버튼, 인풋, 카드 등 UI 내부 패딩·갭",
    color: "#6366f1",
    soft: "#efeffc",
    rows: [
      ["spacing/component-xs", 4],
      ["spacing/component-sm", 8],
      ["spacing/component-md", 16],
      ["spacing/component-lg", 24],
    ],
  },
  {
    title: "레이아웃 (Layout)",
    desc: "섹션·페이지 단위의 여백과 간격",
    color: "#229868",
    soft: "#e6f5ee",
    rows: [
      ["spacing/layout-xs", 16],
      ["spacing/layout-sm", 24],
      ["spacing/layout-md", 32],
      ["spacing/layout-lg", 48],
    ],
  },
  {
    title: "인라인 갭 (Gap)",
    desc: "아이콘·태그 사이, 리스트 아이템 간격",
    color: "#bd630e",
    soft: "#fcf2e9",
    rows: [
      ["spacing/gap-xs", 4],
      ["spacing/gap-sm", 8],
      ["spacing/gap-md", 12],
      ["spacing/gap-lg", 20],
    ],
  },
] as const;

const GUIDES = [
  { title: "4px 그리드 원칙", body: "모든 간격은 4의 배수를 사용합니다. 2px(spacing/2)는 보더·구분선 등 미세 조정에만 허용합니다." },
  {
    title: "Semantic 우선 사용",
    body: "컴포넌트 구현 시 spacing/N 프리미티브 대신 spacing/component-*, spacing/layout-*, spacing/gap-* 시맨틱 토큰을 사용하세요.",
  },
  { title: "일관된 리듬 유지", body: "동일 계층의 요소들은 같은 간격 토큰을 공유하여 시각적 리듬과 정렬을 유지합니다." },
];

function SectionTitle({ title, desc }: { title: string; desc: string }) {
  return (
    <div className="flex flex-col gap-2.5">
      <div className="flex items-center gap-3">
        <span className="h-6 w-1 shrink-0 rounded-[2px] bg-[#6366f1]" aria-hidden="true" />
        <h3 className="text-[18px] font-bold leading-normal text-[#111827] sm:text-[20px]">{title}</h3>
      </div>
      <p className="text-[14px] leading-normal text-[#6b7280]">{desc}</p>
    </div>
  );
}

export default function SpacingSystemDoc() {
  return (
    <section className="w-full bg-white px-4 py-12 font-['Geist',sans-serif] sm:px-10 sm:py-20 lg:px-20">
      <link rel="stylesheet" href={FONT_URL} precedence="default" />
      <div className="mx-auto flex w-full max-w-[1280px] flex-col gap-12">
        <h2 className="border-b border-[#eceef1] pb-5 text-[24px] font-bold leading-normal text-[#111827] sm:text-[28px]">06 · SPACING SYSTEM</h2>

        <div className="flex flex-col gap-6">
          <SectionTitle title="프리미티브 스케일 (Primitive Scale)" desc="4px 기반 스케일 — 모든 간격은 이 값을 기초로 합니다." />
          <div className="flex flex-col">
            <div className="grid grid-cols-[88px_64px_1fr] items-center gap-3 border-b border-[#eceef1] pb-2 text-[11px] font-medium leading-normal text-[#a5a9b2] sm:grid-cols-[208px_100px_1fr]">
              <span>TOKEN</span>
              <span>VALUE</span>
              <span>VISUAL SCALE</span>
            </div>
            <ul className="mt-2 flex flex-col">
              {PRIMITIVES.map((v, i) => (
                <li
                  key={v}
                  className={`-mx-2 grid h-[46px] grid-cols-[88px_64px_1fr] items-center gap-3 rounded px-2 sm:grid-cols-[208px_100px_1fr] ${i % 2 === 0 ? "bg-[#f9fafc]" : ""}`}
                >
                  <span className="text-[13px] font-medium leading-normal text-[#111827]">spacing/{v}</span>
                  <span className="w-[58px] rounded bg-[#efeffc] px-2 py-1 text-[12px] font-medium leading-normal text-[#6366f1]">{v}px</span>
                  <span className="flex min-w-0 items-center gap-2">
                    <span
                      className="h-3 rounded-[3px] bg-[#6366f1] transition-[width] duration-500 ease-out"
                      style={{ width: `${(v / MAX) * 100}%`, maxWidth: "calc(100% - 28px)", opacity: 0.35 + (0.65 * i) / (PRIMITIVES.length - 1) }}
                    />
                    <span className="text-[11px] leading-normal text-[#a5a9b2]">{v}</span>
                  </span>
                </li>
              ))}
            </ul>
          </div>
        </div>

        <div className="flex flex-col gap-6 pt-6">
          <SectionTitle title="시맨틱 토큰 (Semantic Tokens)" desc="목적에 따라 분류된 간격 토큰 — 실제 컴포넌트·레이아웃 개발 시 이 토큰을 사용하세요." />
          <div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3 lg:gap-10">
            {SEMANTIC.map((g) => (
              <div key={g.title} className="overflow-hidden rounded-lg border border-[#eceef1] bg-white">
                <div className="h-[3px] w-full" style={{ background: g.color }} />
                <div className="flex flex-col gap-1.5 px-5 pb-4 pt-4">
                  <p className="text-[14px] font-bold leading-normal text-[#111827]">{g.title}</p>
                  <p className="text-[12px] leading-normal text-[#6b7280]">{g.desc}</p>
                </div>
                <div className="grid grid-cols-[1fr_auto_auto] gap-3 border-b border-[#eceef1] px-5 pb-2 text-[10px] font-medium leading-normal text-[#a5a9b2]">
                  <span>SEMANTIC</span>
                  <span className="w-[92px]">PRIMITIVE</span>
                  <span className="w-10 text-center">PX</span>
                </div>
                <ul className="flex flex-col gap-5 px-5 py-5">
                  {g.rows.map(([name, px]) => (
                    <li key={name} className="flex flex-col gap-1.5">
                      <div className="grid grid-cols-[1fr_auto_auto] items-center gap-3">
                        <span className="truncate text-[12px] font-medium leading-normal text-[#111827]">{name}</span>
                        <span className="flex w-[92px] items-center gap-1.5 text-[11px] leading-normal">
                          <span className="text-[#a5a9b2]" aria-hidden="true">
                            →
                          </span>
                          <span className="text-[#6b7280]">spacing/{px}</span>
                        </span>
                        <span className="w-10 rounded py-0.5 text-center text-[11px] font-medium leading-normal" style={{ background: g.soft, color: g.color }}>
                          {px}px
                        </span>
                      </div>
                      <span className="h-1 rounded-[2px] opacity-55" style={{ width: (px / 24) * 70, background: g.color }} aria-hidden="true" />
                    </li>
                  ))}
                </ul>
              </div>
            ))}
          </div>
        </div>

        <div className="flex flex-col gap-6 pt-6">
          <div className="flex items-center gap-3">
            <span className="h-6 w-1 shrink-0 rounded-[2px] bg-[#6366f1]" aria-hidden="true" />
            <h3 className="text-[18px] font-bold leading-normal text-[#111827] sm:text-[20px]">사용 가이드라인 (Usage Guidelines)</h3>
          </div>
          <div className="grid grid-cols-1 gap-6 md:grid-cols-3 lg:gap-10">
            {GUIDES.map((g) => (
              <div key={g.title} className="flex min-h-[120px] flex-col gap-2.5 rounded-lg border border-[#eceef1] border-l-4 border-l-[#6366f1] bg-[#f9fafc] p-5">
                <p className="text-[13px] font-bold leading-normal text-[#111827]">{g.title}</p>
                <p className="text-[12px] leading-[1.6] text-[#6b7280]">{g.body}</p>
              </div>
            ))}
          </div>
        </div>

        <p className="whitespace-pre border-t border-[#eceef1] pt-4 text-[12px] leading-normal text-[#a5a9b2]">{"Design System  ·  Spacing System  ·  v1.0"}</p>
      </div>
    </section>
  );
}

적용 사이트 0

이 블록이 실제로 쓰인 사이트입니다.

로그인하고 내 사이트 추가

아직 등록된 사이트가 없습니다. 이 블록을 쓴 사이트가 있다면 알려 주세요.

로그인하고 재현 결과 올리기

재현 후기

v1 · 0개

아직 이 버전의 프롬프트로 직접 만들어 본 사람이 없습니다. 첫 번째로 재현해 보세요.