designpaca 초기 구현 — 스킬 · 설치 CLI · 배포 파이프라인
웹 디자인 파이프라인 스킬과 이를 5개 에이전트에 설치하는 CLI 를 담은 모노레포. 스킬 (packages/skill) - SKILL.md 261줄 + 참조 문서 16개 3,349줄. progressive disclosure 로 본문은 절차와 인덱스만, 지식은 references/ 로 분리 - 0~6단계 파이프라인. 규모에 따라 전체·연장·국소 세 경로로 분기 - 하드 게이트 12개는 grep·카운트로 검증 가능한 것만. 취향 판단은 제외 - 미학 프리셋 5종, AI 슬롭 지문 목록, 한글 조판 규칙, SVG 필터·three.js·인터랙티브 모션·HTML-in-Canvas 실전 지침 설치 CLI (packages/cli, packages/core) - npx designpaca 온보딩 TUI. Claude Code · Codex · Cursor · Windsurf · AGENTS.md - 매니페스트에 설치 시점 해시를 기록해 사용자가 고친 파일은 update 가 건너뛴다 - 타깃별로 본문의 references/ 경로를 실제 설치 위치로 재작성 - AGENTS.md 는 항상 로드되므로 본문 대신 303자 포인터만 주입 - Windsurf 는 12,000자 상한 초과 시 설치를 차단 배포 (build/ci, .forgejo/workflows) - 태그 v* → 검사·테스트·빌드 → npmjs 배포 + Forgejo 레지스트리 미러 → draft 릴리스 → Cloudflare Pages. 재실행 멱등 근거 (research/) - 약 250개 웹 소스 조사 결과와 도그푸딩 검증 2건. 스킬의 모든 수치는 여기서 나온다 테스트 22개 통과 (core 16 · cli 6)
This commit is contained in:
commit
8808c672dc
135 changed files with 38838 additions and 0 deletions
216
research/dogfood-saas/hero/src/styles/hero.css
Normal file
216
research/dogfood-saas/hero/src/styles/hero.css
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
/* 히어로. 값은 전부 tokens.css 에서 온다. */
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html { -webkit-text-size-adjust: 100%; }
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background: var(--surface);
|
||||
color: var(--ink);
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--step-0);
|
||||
line-height: var(--leading-normal);
|
||||
letter-spacing: var(--tracking-body);
|
||||
font-variant-numeric: tabular-nums; /* dark-instrument: 수치가 흔들리면 계기판이 아니다 */
|
||||
}
|
||||
|
||||
/* layout.md §1 — 하나의 그리드에서 전부 나온다 */
|
||||
.page {
|
||||
display: grid;
|
||||
grid-template-columns:
|
||||
[full-start] minmax(var(--gutter), 1fr)
|
||||
[main-start] minmax(0, var(--container)) [main-end]
|
||||
minmax(var(--gutter), 1fr) [full-end];
|
||||
}
|
||||
.page > * { grid-column: main; }
|
||||
.page > .full { grid-column: full; }
|
||||
|
||||
/* ---------------------------------------------------------------- 내비 */
|
||||
.nav {
|
||||
display: flex;
|
||||
flex-wrap: wrap; /* 320px 에서 밀려 가로 스크롤이 생겼다 */
|
||||
align-items: center;
|
||||
gap: var(--space-2) var(--space-4);
|
||||
padding-block: var(--space-4);
|
||||
}
|
||||
.nav__mark {
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--step-2);
|
||||
letter-spacing: var(--tracking-display);
|
||||
margin: 0;
|
||||
margin-inline-end: auto;
|
||||
}
|
||||
.nav__link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 44px; /* 터치 타깃 44×44 */
|
||||
min-width: 44px;
|
||||
color: var(--ink-muted);
|
||||
font-size: var(--step--1);
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
.nav__link:hover { color: var(--ink); border-bottom-color: var(--line); }
|
||||
|
||||
/* ---------------------------------------------------------------- 히어로 */
|
||||
.hero {
|
||||
/* 100vh 금지(하드게이트 #9). dvh 를 쓰고 min-height 로만 잡는다 */
|
||||
min-height: min(84dvh, 46rem);
|
||||
display: grid;
|
||||
/* 비대칭 7:5. layout.md — 중앙 정렬 히어로는 쓰지 않는다 */
|
||||
grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
|
||||
gap: var(--space-6) var(--space-7);
|
||||
align-items: start;
|
||||
padding-block: var(--space-7) var(--space-8);
|
||||
}
|
||||
|
||||
.hero__headline {
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--display-1);
|
||||
line-height: var(--leading-tight);
|
||||
letter-spacing: var(--tracking-display);
|
||||
font-weight: 400;
|
||||
margin: 0 0 var(--space-4);
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
.hero__sub {
|
||||
max-width: var(--measure);
|
||||
color: var(--ink-muted);
|
||||
font-size: var(--step-1);
|
||||
margin: 0 0 var(--space-5);
|
||||
}
|
||||
|
||||
.hero__actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: var(--space-4);
|
||||
}
|
||||
|
||||
/* 주 CTA — 감수한 리스크: 강조색을 쓰지 않고 잉크 반전으로만 만든다 */
|
||||
.cta {
|
||||
display: inline-block;
|
||||
background: var(--cta-bg);
|
||||
color: var(--cta-ink);
|
||||
font-size: var(--step-0);
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
text-decoration: none;
|
||||
padding: var(--space-3) var(--space-5);
|
||||
border: 0;
|
||||
border-radius: var(--radius-md);
|
||||
white-space: nowrap; /* 하드게이트 #6 — 라벨이 2줄로 접히지 않는다 */
|
||||
/* 하드게이트 #8 — transform/opacity 만 트랜지션한다 */
|
||||
transition: transform var(--dur-instant) var(--ease-out);
|
||||
}
|
||||
.cta:hover { transform: translateY(-1px); }
|
||||
.cta:active { transform: translateY(0); }
|
||||
|
||||
.link-quiet {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 44px; /* 터치 타깃 */
|
||||
color: var(--accent); /* 강조색은 오직 글자에만 */
|
||||
font-size: var(--step-0);
|
||||
text-decoration: underline; /* 색만으로 구분하지 않는다 */
|
||||
text-underline-offset: 0.25em;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- 제품 화면
|
||||
* 하드게이트 #12 — div 로 만든 가짜 스크린샷 금지.
|
||||
* 브리프가 실제 스크린샷을 제공하므로 <img> 를 쓴다.
|
||||
* aspect-ratio 로 자리를 미리 잡아 CLS 를 막는다.
|
||||
*/
|
||||
.shot {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
aspect-ratio: 4 / 3;
|
||||
object-fit: cover;
|
||||
object-position: left top;
|
||||
background: var(--surface-raised); /* 로드 전/실패 시의 자리 */
|
||||
border-radius: var(--radius-md);
|
||||
}
|
||||
.shot-caption {
|
||||
display: block;
|
||||
margin-top: var(--space-2);
|
||||
color: var(--ink-muted);
|
||||
font-size: var(--step--1);
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- 설치 명령 */
|
||||
.install {
|
||||
grid-column: main;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: var(--space-3);
|
||||
background: var(--surface-raised);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-3) var(--space-4);
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--step-0);
|
||||
}
|
||||
.install__prompt { color: var(--ink-muted); user-select: none; }
|
||||
.install__cmd { color: var(--ink); }
|
||||
.install__copy {
|
||||
margin-inline-start: auto;
|
||||
min-height: 44px;
|
||||
min-width: 44px;
|
||||
background: transparent;
|
||||
color: var(--ink-muted);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius-sm);
|
||||
font: inherit;
|
||||
font-size: var(--step--1);
|
||||
padding: var(--space-1) var(--space-3);
|
||||
cursor: pointer;
|
||||
transition: transform var(--dur-instant) var(--ease-out);
|
||||
}
|
||||
.install__copy:hover { color: var(--ink); transform: translateY(-1px); }
|
||||
|
||||
/* ---------------------------------------------------------------- 테마 토글 */
|
||||
.theme-toggle {
|
||||
min-height: 44px;
|
||||
min-width: 44px;
|
||||
background: transparent;
|
||||
color: var(--ink-muted);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius-sm);
|
||||
font: inherit;
|
||||
font-size: var(--step--1);
|
||||
padding: var(--space-1) var(--space-3);
|
||||
cursor: pointer;
|
||||
}
|
||||
.theme-toggle:hover { color: var(--ink); }
|
||||
|
||||
.visually-hidden {
|
||||
position: absolute;
|
||||
width: 1px; height: 1px;
|
||||
padding: 0; margin: -1px;
|
||||
overflow: hidden;
|
||||
clip-path: inset(50%);
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- 포커스 */
|
||||
:where(a, button):focus-visible {
|
||||
outline: 2px solid var(--accent);
|
||||
outline-offset: 3px;
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- 반응형 */
|
||||
/* 콘텐츠가 깨지는 지점에서만. 기기 크기를 가정하지 않는다 */
|
||||
@media (max-width: 54rem) {
|
||||
.hero { grid-template-columns: minmax(0, 1fr); }
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*, *::before, *::after { transition-duration: 1ms !important; animation-duration: 1ms !important; }
|
||||
}
|
||||
100
research/dogfood-saas/hero/src/styles/tokens.css
Normal file
100
research/dogfood-saas/hero/src/styles/tokens.css
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/* 3단계에서 확정한 토큰. 하드코딩된 값은 이 파일 밖에 존재하지 않는다. */
|
||||
|
||||
:root {
|
||||
/* ---- 타입: 본문 스케일 (비율 1.250, 5단계) ---- */
|
||||
--step--1: 0.8125rem;
|
||||
--step-0: 1rem;
|
||||
--step-1: 1.25rem;
|
||||
--step-2: 1.5625rem;
|
||||
--step-3: 1.9531rem;
|
||||
|
||||
/* ---- 타입: 디스플레이 (스케일 밖. 위계를 만드는 유일한 장치) ---- */
|
||||
--display-2: clamp(2rem, 1.4rem + 3vw, 2.5rem);
|
||||
--display-1: clamp(2.75rem, 1.8rem + 4.8vw, 4rem);
|
||||
|
||||
--leading-tight: 1.05;
|
||||
--leading-snug: 1.3;
|
||||
--leading-normal: 1.55;
|
||||
--measure: 68ch;
|
||||
|
||||
--font-display: 'Newsreader', Georgia, 'Times New Roman', serif;
|
||||
--font-body: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
|
||||
--font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
|
||||
|
||||
--tracking-display: -0.025em;
|
||||
--tracking-body: 0;
|
||||
|
||||
/* ---- 간격: 4px 그리드 ---- */
|
||||
--space-1: 0.25rem;
|
||||
--space-2: 0.5rem;
|
||||
--space-3: 1rem;
|
||||
--space-4: 1.5rem;
|
||||
--space-5: 2.5rem;
|
||||
--space-6: 4rem;
|
||||
--space-7: 6rem;
|
||||
--space-8: 10rem;
|
||||
--container: 70rem;
|
||||
--gutter: clamp(1rem, 4vw, 5rem);
|
||||
|
||||
/* ---- 형태: 어휘 2종 ---- */
|
||||
--radius-sm: 2px;
|
||||
--radius-md: 4px;
|
||||
|
||||
/* ---- 모션 ---- */
|
||||
--dur-instant: 100ms;
|
||||
--dur-quick: 200ms;
|
||||
--dur-normal: 350ms;
|
||||
--dur-slow: 600ms;
|
||||
--ease-out: cubic-bezier(0.22, 1, 0.36, 1);
|
||||
--ease-in: cubic-bezier(0.64, 0, 0.78, 0);
|
||||
--ease-soft: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
|
||||
/* ---- 색: 다크가 저작 기준 (2단계에서 정당화) ---- */
|
||||
color-scheme: dark light;
|
||||
--surface: #0D0F12;
|
||||
--surface-raised: #151A20;
|
||||
--line: #262E37;
|
||||
--ink: #E6E8E6;
|
||||
--ink-muted: #9BA6B2;
|
||||
--accent: #7FA6FF;
|
||||
--accent-ink: #0D0F12;
|
||||
--cta-bg: #E6E8E6;
|
||||
--cta-ink: #0D0F12;
|
||||
--ok: #4FA97A;
|
||||
--warn: #C9A227;
|
||||
--fail: #D46A55;
|
||||
}
|
||||
|
||||
/* OS가 라이트를 선호하면 라이트. 토글이 명시적으로 다크를 잡으면 무시한다. */
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root:not([data-theme='dark']) {
|
||||
--surface: #F7F5F0;
|
||||
--surface-raised: #FDFCF9;
|
||||
--line: #DCD8CF;
|
||||
--ink: #16181A;
|
||||
--ink-muted: #5C646E;
|
||||
--accent: #1B4FD8;
|
||||
--accent-ink: #FAF9F6;
|
||||
--cta-bg: #16181A;
|
||||
--cta-ink: #FAF9F6;
|
||||
--ok: #2F7D57;
|
||||
--warn: #8A6D14;
|
||||
--fail: #A8432E;
|
||||
}
|
||||
}
|
||||
|
||||
/* 토글이 라이트를 잡으면 OS와 무관하게 라이트 */
|
||||
:root[data-theme='light'] {
|
||||
--surface: #F7F5F0;
|
||||
--surface-raised: #FDFCF9;
|
||||
--line: #DCD8CF;
|
||||
--ink: #16181A;
|
||||
--ink-muted: #5C646E;
|
||||
--accent: #1B4FD8;
|
||||
--accent-ink: #FAF9F6;
|
||||
--cta-bg: #16181A;
|
||||
--cta-ink: #FAF9F6;
|
||||
--ok: #2F7D57;
|
||||
--warn: #8A6D14;
|
||||
--fail: #A8432E;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue