Communitygithub.com

floorvanriet/wireframe

단어로 설명된 화면이나 흐름을 기반으로, 자체 포함된 HTML/CSS 파일로 중간 수준 와이어프레임을 생성합니다.

wireframe란 무엇인가요?

이 스킬은 사용자가 텍스트로 설명하는 화면이나 사용자 흐름, UI 아이디어를 중간 수준의 와이어프레임(mid-fi wireframe)으로 변환하는 강력한 기술 에이전트 도구입니다. AI 어시스턴트(예: Claude Code, Cursor 등)와 함께 사용하도록 설계되었으며, 단일 자체 포함 HTML 파일을 생성하여 복잡한 설정 없이도 미리보기와 공유가 가능합니다. 스킬의 핵심은 단순히 레이아웃을 그리는 것을 넘어 창의적인 협업 파트너 역할을 합니다. 와이어프레임을 '생각 도구'로 활용하여, 사용자가 '무엇을', '왜' 만들 것인지 명확히 하도록 돕습니다. 그레이스케일 팔레트와 하나의 액센트 색상만 사용하여 주요 상호작용을 강조하며, 'Lorem ipsum' 대신 실제 카피를 사용하여 생성된 결과물을 바로 관계자에게 보여줄 수 있습니다. 여러 화면을 동시에 보여주거나, 여러 제품 부분을 포괄하는 '컨셉 사이트'를 구축하여 메뉴로 연결하는 고급 기능도 지원합니다. 또한 사용자 요청이 모호하거나 복잡할 경우, AI가 먼저 간단한 토론(sparring)을 통해 방향성을 제시하고 최적의 옵션을 선택한 후 와이어프레임을 제작합니다. 이는 사용자가 명확한 결정을 내리기 전에 여러 대안을 시각적으로 비교해볼 수 있게 하여, 더 나은 UX 결정을 돕습니다.

지원 대상~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/floorvanriet/wireframe-skill/tree/HEAD/wireframe

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Wireframe (와이어프레임)

단일 자체 포함 HTML 파일로 중간 수준(mid-fi)의 와이어프레임을 생성합니다. 여러 화면을 나란히 배치하고, 반응형이며, 그레이스케일에 하나의 액센트 색상과 실제 카피를 사용합니다.


핵심 원칙

중간 수준(mid-fi)이란:

  • 그레이스케일 팔레트(아래 토큰 참조)에 하나의 액센트 색상(--accent)을 추가하여 주요 액션과 활성 상태를 표시합니다. 이를 통해 주요 액션을 한눈에 파악할 수 있으며, 다른 색상은 사용하지 않습니다.
  • 실제 레이블, 제목, 헤딩을 사용하며 'Lorem ipsum'은 사용하지 않습니다. 제품의 최종 사용자가 볼 언어로 카피를 작성합니다. 명확하지 않은 경우, 요청의 언어를 사용합니다. 이렇게 하면 대화가 다른 언어로 이루어지더라도 생성된 와이어프레임을 관계자에게 그대로 보여줄 수 있습니다.
  • 이미지용 플레이스홀더 블록 (실제 에셋 없음)
  • 아이콘이 의미를 전달하는 곳에는 Lucide 라인 아이콘 사용 (아이콘 섹션 참조)
  • 클릭 가능한 모든 요소에 호버 상태 적용 (호버 상태 섹션 참조)
  • 명확한 타이포그래피 계층 구조
  • 장식, 그림자 없음, 미세한 테두리만 사용

절대 하지 말아야 할 것:

  • 브랜드 색상 또는 액센트 이외의 색상 사용
  • 실제 이미지, 사진, 로고 또는 일러스트레이션 사용
  • 이모지 또는 텍스트 기호(☰, ×, ›)를 아이콘으로 사용: Lucide 사용
  • 애니메이션 (호버 시 짧은 transition은 괜찮음)
  • 와이어프레임 내부에 설명 추가 (주석은 와이어프레임 외부에 배치)

창의적 프로세스 지원

와이어프레임은 생각 도구입니다. 사용자가 소리 내어 추론하고, 의심하며, 반복함으로써 무엇을, 왜 만들지 명확히 하도록 돕습니다. 당신의 역할은 그 프로세스를 지원하는 것이지, 대체하는 것이 아닙니다. 이는 양방향으로 적용됩니다: 토론 없이 그냥 만들지만 말고, 캔버스에 아무것도 나타나기 전에 사용자를 대화로 묻어두지도 마세요. 화면은 전달물이 아닌 대화의 소재입니다.

입력 유형별

  • 새 요청: 짧은 스파링 블록으로 답변을 시작하세요: 가장 중요한 2-3가지 선택지와 각각의 옵션, 그리고 당신의 선호도와 그 이유를 포함하세요. 레이아웃뿐만 아니라 상호작용도 포함하세요: 탭하거나 클릭하면 무엇이 발생하는지, 피드백이 어디에 표시되는지, 무엇을 취소할 수 있는지, 모달인지 별도 페이지인지, 인라인인지 추가 단계인지. 그런 다음 선호하는 옵션을 구축하여 구체적으로 반응할 수 있는 무언가를 제공하세요. 몇 개의 글머리 기호, 에세이는 안 됩니다. (모호한 요청에 복잡한 범위라면? 먼저 최적화 의도에서 한 가지 질문을 하세요.)
  • 탐색적 요청 ("~ 사이에서 고민 중입니다...", "~가 작동할까요?", 생각을 소리 내어 말하는 경우): 스파링만 하세요. 각 옵션의 장단점과 당신의 선호도를 제시한 후, 그중 하나를 구축할지, 그리고 어떤 것을 구축할지 물어보세요.
  • 후속 입력: 먼저 본질에 대해 응답하세요: 함께 생각하고, 추가하고, 약점이나 대안을 제시하세요. 무언가 결정된 후에만 와이어프레임을 변경하고, 모든 지나가는 생각마다 변경하지 마세요. 스파링인지 결정인지 확실하지 않나요? 간단히 물어보세요: "이것을 적용할까요, 아니면 먼저 더 생각해볼까요?"

스파링 방법

  • 소리 내어 반박하세요. 패턴이 이 맥락에서 작동하지 않을 수 있다면(예: 항목이 2개뿐인데 shortlist를 사용하는 경우), 맹목적으로 구축하지 말고 그렇게 말하세요.
  • 완성된 결정이 아닌 방향을 제시하세요. 선택지가 진정으로 열려 있을 때는, 설명만 하지 말고 와이어프레임에서 A와 B를 나란히 보여주고 당신이 선호하는 것을 말하세요.
  • 작은 단계로 반복하세요. 요소별로 변경을 예상하세요. 사용자가 선택하거나 가리키는 것을 기반으로 구축하세요.
  • 결정을 강요하지 마세요. 목표는 명확성입니다. 선택은 나중에 올 수 있습니다.
  • 가볍게 유지하세요. 옵션당 한 줄, 총 몇 개의 글머리 기호, 그리고 최대 한 가지 집중된 질문. 와이어프레임은 스스로 설명하므로, 그 안에 있는 내용을 설명하지 말고 사용자가 볼 수 없는 것만 언급하세요(예: 가정 또는 클릭 시 발생하는 일).

UX 원칙

  • 레이아웃뿐만 아니라 개념 자체에 질문을 던지세요. 기본 기능이 실제로 유효한지 계속 확인하고 도전하세요. 단순히 "어떻게 생겼는가"만 보지 마세요.
  • 시스템이 알 수 없는 상태를 주장하지 마세요. 사용 가능한 데이터에 기반하여 UI를 구성하세요. 어떤 것을 알 수 없다면, 상태 대신 액션을 보여주거나 사용자가 직접 표시하도록 하세요.
  • 콘텐츠 충실도를 화면의 목적에 맞추세요. 구조나 탐색이 핵심이라면 콘텐츠를 낮은 충실도(플레이스홀더 라인)로 만들어 주제에 집중하도록 하세요.
  • 핵심 상태를 나란히 와이어프레임으로 작성하세요. 로그인/로그아웃, 비어있음/채워짐, 열림/닫힘: 이렇게 하면 실제 결정 사항이 보입니다.
  • 작은 화면에 맞게 탐색을 의도적으로 변환하세요. 전환이 어색하지 않도록 하나의 영구 앵커를 유지하고, 모든 것을 보여주는 대신 우선순위를 정하고 그룹화하세요. 하나의 탐색 구조, 여러 개의 셸, 하나의 출처.

전달

  • 각 와이어프레임을 하나의 자체 포함 HTML 파일로 유지하세요. 별도의 JS/CSS 파일을 옆에 두지 마세요: 미리보기에서는 종종 파일을 단독으로 렌더링하며, 형제 파일 없이 로드합니다. 기본 템플릿의 두 CDN 링크(Google Fonts의 IBM Plex Sans, jsDelivr의 Lucide)는 예외이며, 미리보기에서 잘 로드됩니다. 재사용을 원하시나요? 마스터 템플릿을 인라인으로 포함하고 복사본을 동기화하세요.
  • 대규모 화면 세트의 경우, 고정 화면 전환기(예: 드롭다운)를 추가하여 화면 간에 이동하세요.
  • 여러 제품 부분에 걸친 컨셉의 경우, 컨셉 사이트를 구축하세요 (아래 참조).

컨셉 사이트

컨셉이 제품의 여러 부분(온보딩, 검색, 계정 등)을 다루고 사용자가 전체를 보여주거나 검토하려는 경우, 컨셉 사이트를 구축하세요: 부분별로 하나의 페이지, 동일한 메뉴 바로 연결됩니다. 관계자는 전체 컨셉을 살펴볼 수 있는 하나의 장소를 얻게 되며, 나머지 부분에 영향을 주지 않고 한 부분을 반복할 수 있습니다.

  • 메뉴 바: 모든 페이지 상단, 캔버스 위, 프레임 위에 위치. 왼쪽: 컨셉 이름과 버전, 날짜, 한 줄 설명을 툴팁으로 가진 info 아이콘. 그 다음 구분선, 부분별 링크 하나씩. 현재 페이지에는 aria-current="page"를 지정하고 --text-primary/600 스타일을 적용하며, 나머지는 --text-secondary 스타일을 적용합니다. 링크가 맞지 않으면, 줄 바꿈 대신 막대가 수평으로 스크롤됩니다. 대규모 컨셉(약 15개 이상 화면)의 경우, 막대 오른쪽 끝에 'Go to screen' 드롭다운을 추가하여 모든 페이지의 모든 화면으로 이동할 수 있게 합니다. 소규모 컨셉의 경우 메뉴만으로 충분합니다.
  • IA 먼저. 첫 번째 링크는 IA 페이지입니다: 모든 부분에 대한 링크가 있는 제품 구조 페이지이며, 진입 페이지이기도 합니다.
  • 각 부분 페이지는 일반 와이어프레임입니다: 프레임을 나란히 배치하고, 프레임 레이블, 점선 캔버스.
  • 함께 열릴 경우 별도 파일로. 사용자가 브라우저에서 열거나 호스팅할 폴더(로컬 작업, 저장소 내)를 작성할 수 있다면, index.html을 IA용으로 만들고 각 부분에 대해 짧은 슬러그를 사용한 파일(onboarding.html)을 만들어 상대적으로 링크합니다.
  • 단독으로 미리보기 될 경우 하나의 파일로. 단일 아티팩트 또는 채팅 미리보기는 하나의 파일을 단독으로 렌더링하므로, 다른 파일로의 링크가 깨집니다. 모든 부분을 섹션으로 하나의 파일에 넣고, 메뉴에서 #hash 링크(#onboarding)를 통해 전환합니다.
  • 모든 곳에서 메뉴를 동일하게 유지하세요. 하나의 마스터 복사본에서 모든 파일에 인라인으로 포함하여 각 페이지가 독립적으로 작동하도록 하세요. 부분이 추가, 이름 변경 또는 제거되면 모든 파일의 메뉴를 동시에 업데이트하세요.

디자인 토큰

:root {
  --bg:        #F5F5F5;   /* 페이지 배경 */
  --surface:   #FFFFFF;   /* 카드, 패널 */
  --border:    #D1D1D1;   /* 테두리 */
  --muted:     #E8E8E8;   /* 플레이스홀더 블록 */
  --text-primary:   #1A1A1A;
  --text-secondary: #595959;   /* 메타, 플레이스홀더, 이미지 블록 내 레이블 */
  --text-disabled:  #AAAAAA;   /* 비활성화된 컨트롤에만 */
  --accent:       #1560D0;   /* 유일한 색상: 주요 액션, 활성 상태 */
  --accent-hover: #1250B0;
  --hover-bg:     #F0F0F0;   /* 밝거나 투명한 요소의 호버 */
  --border-hover: #AAAAAA;   /* 테두리가 있는 요소의 호버 */
  --font: 'IBM Plex Sans', system-ui, sans-serif;
}

이 토큰들은 WCAG AA(4.5:1)에 맞게 조정되었습니다: --text-primary와 --text-secondary는 여기의 모든 표면 색상(--surface, --bg, --hover-bg, --muted, --border)에 대해 통과합니다. --accent는 텍스트로서 --border를 제외한 모든 표면에서 통과합니다. 흰색은 --accent에서 통과합니다. 접근성은 와이어프레임에서 시작되므로, 이 상태를 유지하세요: 텍스트에 더 밝은 회색을 추가하지 마세요. 유일한 예외는 --text-disabled(2.3:1)입니다: WCAG에서 면제되는 비활성화된 컨트롤에만 사용하고, 메타데이터와 같은 읽을 수 있는 텍스트에는 절대 사용하지 마세요.


HTML 구조

기본 템플릿

lang을 카피의 언어로 설정하세요.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Wireframe: [주제]</title>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&display=swap" rel="stylesheet">
  <style>
    /* 토큰 */
    *, *::before, *::after { box-sizing: border-box; }
    body { margin: 0; -webkit-font-smoothing: antialiased; }
    button, input, select, textarea { font: inherit; }  /* 폼 컨트롤은 기본적으로 글꼴을 상속받지 않음 */
    /* 레이아웃 + 컴포넌트 */
  </style>
</head>
<body>
  <div class="wireframe-canvas">
    <div class="frame-row">
      <!-- 여기에 프레임들 -->
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/lucide@1/dist/umd/lucide.min.js"></script>
  <script>lucide.createIcons();</script>
</body>
</html>

여러 프레임 레이아웃

이 캔버스는 출력물을 한눈에 와이어프레임으로 읽히게 만드는 요소이므로, 그대로 사용하세요.

.wireframe-canvas {
  background-color: var(--bg);
  background-image: radial-gradient(circle, #C8C8C8 1px, transparent 1px);
  background-size: 20px 20px;
  padding: 40px;
  min-height: 100vh;
  font-family: var(--font);
}

.frame-row {
  display: flex;
  gap: 32px;
  align-items: flex-start;
  flex-wrap: wrap;
}

.frame {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  flex-shrink: 0;
}

/* 기기별 너비 */
.frame.mobile  { width: 375px; }
.frame.tablet  { width: 768px; }
.frame.desktop { width: 1280px; }
.frame.auto    { width: 100%; max-width: 1280px; }

프레임 레이블 (각 화면 위)

<div class="frame-label">화면 1: [이름]</div>
<div class="frame mobile">
  <!-- 콘텐츠 -->
</div>
.frame-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-secondary);
  margin-bottom: 8px;
}

컴포넌트

컴포넌트의 HTML과 CSS를 직접 작성하되, 아래 값을 고수하여 세션 간에 와이어프레임이 일관되게 보이도록 하세요. 버튼과 입력에는 min-height를 inline-flex 중앙 정렬과 함께 사용하여 패딩에만 의존하지 마세요. 패딩만으로는 40px에 약간 못 미치며, 40px이 최소 클릭 대상입니다.

컴포넌트스펙
기본 버튼--accent 채움, 흰색 텍스트, 14px/600, min-height: 40px, 패딩 0 20px, radius 6px
보조 버튼투명, --accent 텍스트, 1.5px --accent 테두리, 그 외 기본 버튼과 동일
텍스트 버튼 / 인라인 액션"편집", "상태 설정", "변경": --accent 텍스트, 14px/500, 테두리 없음. 여전히 40px 대상: min-height: 40px와 inline-flex, 또는 라인 안에 있을 때 동일한 음수 마진과 함께 패딩 사용
입력위에 레이블 (13px/500, --text-primary, 4px 간격). 필드: 1px --border, radius 6px, min-height: 40px, 패딩 0 12px, 14px, 플레이스홀더 텍스트는 --text-secondary
이미지 플레이스홀더고정 aspect-ratio를 가진 --muted 블록, 중앙에 --text-secondary 13px 레이블로 콘텐츠와 비율 표시("제품 사진 16:9")
카드--surface, 1px --border, radius 8px, overflow: hidden. 본문 패딩 16px, 간격 4px: 오버라인 11px 대문자 --text-secondary, 제목 15px/600, 메타 12px --text-secondary
태그12px/500, 패딩 2px 8px, radius 4px(카드보다 작음), --muted 배경, --text-secondary 텍스트
모바일 네비게이션 바패딩 12px 16px, 하단 테두리. 왼쪽 로고 텍스트 16px/600, 오른쪽 Lucide menu를 40×40 버튼 안에, aria-label 포함
데스크탑 네비게이션 바패딩 16px 32px, 하단 테두리. 로고, 링크(14px, --text-secondary, 간격 24px, 활성 --text-primary/500), 오른쪽 기본 버튼
스테퍼28px 원 안에 13px/600 숫자, --border의 32px 연결선. 할 일: --muted/--text-secondary. 활성: --accent/흰색. 완료: --border/--text-secondary

목록에 없는 컴포넌트가 필요하신가요? 새로운 값을 발명하지 말고, 이 값들(동일한 반경, 글꼴 크기 규모 및 상태)에서 파생하세요.


최적화 의도

요청에 방향성("단계 줄이기", "스캔하기 쉽게", "덜 복잡하게", "더 빨리 이해할 수 있게")이 포함된 경우, 이를 렌즈로 사용하세요: 해당 방향성을 강화하는 컴포넌트, 계층 구조 및 카피 구조를 선택하세요.

요청이 모호하고 범위가 복잡한(3개 이상의 화면 또는 흐름) 경우, 한 가지 집중된 질문을 하세요: "개선하고 싶은 것은 무엇인가요? 개요, 속도, 신뢰, 아니면 다른 것인가요?"

단일 화면이거나 의도가 이미 명확한 경우에는 질문하지 마세요.


입력 유형별 접근 방식

단어로 설명된 화면 또는 흐름

  1. 설명에서 화면 식별 (각 화면 = 하나의 프레임)
  2. 기기 유형 결정 (명시되지 않은 경우 앱은 모바일, 웹은 데스크탑)
  3. 모든 프레임을 하나의 파일에 나란히 배치
  4. 맥락에 맞는 실제 카피를 최종 사용자의 언어로 사용 (핵심 원칙 참조)

프레임 수

  • 1개 화면: 기기 너비로 표시
  • 2-4개 화면: 한 행에 나란히 배치
  • 5개 이상 화면: 두 행 또는 수평 스크롤

호버 상태

항상 추가하세요. 와이어프레임은 클릭 가능하도록 설계되었으며, 호버는 무엇이 상호작용 가능한지 보여줍니다. 세 가지 패턴이 있습니다. 고정된 목록이 아니라 이 와이어프레임에서 생성하는 클래스에 적용하세요:

/* 1. 액센트 채움: 기본 버튼, 활성 칩 또는 탭, FAB */
.btn-primary:hover   { background: var(--accent-hover); cursor: pointer; }

/* 2. 밝거나 투명: 보조 버튼, 아이콘 버튼, 목록 항목 */
.btn-secondary:hover,
.nav-menu:hover      { background: var(--hover-bg); cursor: pointer; }

/* 3. 테두리 있음: 클릭 가능한 카드, 칩, 선택 옵션 */
.card:hover          { border-color: var(--border-hover); cursor: pointer; }

모든 상호작용 요소는 cursor: pointer를 받습니다. 비상호작용 요소(텍스트, 레이블, 플레이스홀더, 클릭 가능하지 않은 카드 등)는 cursor: default로 유지됩니다.


아이콘

lucide에서 제공하는 Lucide 아이콘만 사용하세요. 사용자 정의 SVG나 다른 라이브러리는 사용하지 마세요. 아이콘은 완전히 이해하기 쉬운 경우에만 사용하세요. 24px 크기, --text-secondary 색상, stroke-width: 1.5.

아이콘으로만 된 버튼에는 항상 aria-label을 추가하고, 가능한 경우 텍스트 레이블도 함께 추가하세요.


접근성

와이어프레임은 접근성 테스트가 아닌 콘셉트 테스트를 위한 것이므로, WCAG AA 준수를 완전히 구현할 필요는 없습니다(예: 초점 표시기, 건너뛰기 링크, ARIA 라이브 지역). 하지만 다음 사항을 항상 준수하세요:

  • 의미 있는 Lucide 아이콘 버튼에는 aria-label 사용
  • 소리 내어 읽기와 시각적 스캔 모두를 위한 명확한 타이포그래피 계층 구조
  • 컨셉 사이트의 현재 페이지에는 aria-current="page" 사용
  • --text-disabled는 비활성화된 컨트롤에만 사용, 읽을 수 있는 텍스트에는 사용하지 않음
  • 프레임이 HTML에서 논리적 읽기 순서를 따르도록 함 (화면 상의 순서가 반드시 DOM 순서일 필요는 없지만, 와이어프레임의 일반적인 왼쪽에서 오른쪽, 위에서 아래로의 읽기 흐름과 일치해야 함)

관련 스킬