Skip to content

Setting(design-system): 디자인 시스템 설정 & shadcn/ui 추가#7

Merged
constantly-dev merged 14 commits intodevelopfrom
setting/#4/tailwind-config
Aug 19, 2025
Merged

Setting(design-system): 디자인 시스템 설정 & shadcn/ui 추가#7
constantly-dev merged 14 commits intodevelopfrom
setting/#4/tailwind-config

Conversation

@constantly-dev
Copy link
Member

@constantly-dev constantly-dev commented Aug 19, 2025

📌 Related Issues

관련된 Issue를 태그해주세요. (e.g. - close #25)

✅ 체크 리스트

  • PR 제목의 형식을 잘 작성했나요? e.g. Feat(client): PR 템플릿 작성
  • 빌드가 성공했나요? (pnpm build)

📄 Tasks

  • design-system: token (color, typography) 설정
  • tailwind config 설정
  • shadcn/ui 추가 및 설정
  • twMerge 함수 커스텀 (extendTailwindMerge)

⭐ PR Point (To Reviewer)

1️⃣ token (color, typography) 설정 (+아키텍쳐 도입 근거)

pinback 디자인 시스템 token을 설정했어요. 모노레포 구조에서 3개의 서비스가 모두 같은 디자인 시스템을 공유하기 때문에 tailwind의 설정을 의미하는 packages/tailwind-config 에 css 파일을 만들어줬어요. 그렇게 초기 아키텍쳐를 설계하는데 고민이 되는 점이 있었어요.

일단 tailwind css v4는 vanilla-extract와 같은 다른 css 라이브러리처럼 Object 기반이 아닌 유틸리티 클래스 기반이에요. 따라서 디자인 시스템 토큰을 어떤 방식으로 구성해야 할지 고민이 됐어요.
특히 tailwind css v4.1 버전에는 이전 v3와 같이 tailwind.config.ts 설정 파일이 아닌 @theme이나 @utility 등의 키워드를 통해 css 파일을 적용할 파일에 import만 하는 구조였기 때문에 토큰화를 한다는 의미가 약하다고 생각했어요.

그래서 최대한 tailwind의 유틸리티 클래스를 분리해서 작성을 해서 토큰을 분리하려고 했어요.
확실히 css 기반으로 config를 작성하다 보니 따로 재사용 가능하게 token으로 분리하는 의미는 적어진다고 생각했어요. 그래서 처음에는 token(theme)을 지정하는 설정 부분만 tailwind의 버전을 v3로 사용하고, apps에서 v4를 사용할까 고민했지만, 공통의 의미인 tailwind config를 v3로 하는데 사용하는 곳에서 tailwind v4를 쓰게 되면 혹시나 버전 충돌 관련 문제가 생길까 걱정돼서 일단 모두 4.1버전으로 진행했어요!

나중에 이 토큰을 조금 더 분리할 수 있는 방법이 생기면 따로 작업해볼게요!!


🤔 토큰 계층 세분화?
이렇게 설정을 하고 나서 이전에 봤던 당근 디자인 시스템 문서가 생각나서 해당 구조를 참고해보려고 해봤어요.
당근 디자인 시스템에서는 token을 실제 값을 사용한 Raw values를 통해 총 2단계 계층 구조를 가지도록 설정했어요.

  • Raw value = 어떤 디스플레이 장치에 그릴 수 있는 실제 값
  • Scale Token = Raw value Scale 하나에 이름을 부여한 것
  • Semantic Token = Scale Token의 조합(Composition)으로 디자인 의도를 표현한 단위

[참고 자료] https://github.com/daangn/seed-design/tree/dev/packages/design-token

이렇게 구조를 짜게 되면 디자인 의도, 환경에 따라 다양한 조합을 토큰 만으로 쉽게 표현이 가능하고 재사용성을 높일 수 있다고 생각했어요. 하지만 와이어 프레임, GUI와 전체 서비스의 규모를 생각했을 때 이러한 토큰 계층화가 현재로는 복잡성만 높일 수 있다고 판단했어요.

따라서 이후에 서비스 규모가 커지고, 조금 더 확실한 상황/배경에 따른 토큰 조합이 필요하다고 느끼는 경우에 해당 아키텍쳐를 도입하는 것이 좋다고 판단하여 기존의 아키텍쳐를 그대로 쓰기로 결정했습니다.


2️⃣ Shadcn/ui 추가

shadcn/ui를 도입한 이유를 설명 전에 shadcn/ui를 간단하게 요약하자면 재사용 가능한 컴포넌트를 의미해요.
여기서 주의할 점은 컴포넌트 라이브러리 가 아니에요. 기존 라이브러리는 패키지 매니저를 통해서 의존성을 추가하는 설치 과정이 필요하지만, shadcn/ui는 라이브러리가 아닌 필요한 컴포넌트 코드만 파일로 추가하는 과정을 사용해요.

이렇게 사용하면 다음과 같은 장점이 있어요.

  • 필요한 코드만 추가하기 때문에 번들 크기 감소
  • 코드를 제공하여 사용자에게 권한을 넘기기 때문에 커스텀 활용성 증가

권한 자체를 shadcn이 가지는 것이 아니라 추가한 이후로는 사용자에게 위임이 되기 때문에 스타일을 수정하는 것이 자유롭게 돼요. 또한 계속 언급한 것처럼 필요한 코드만 추가하여 불필요한 의존이나 번들 크기를 줄일 수 있어요.

image

물론 다양한 컴포넌트 관련 패키지가 있지만 의존성이 추가되지 않고 사용하고 싶은 UI 코드만 추가해서 사용할 수 있다는 점이 큰 장점인 것 같아요!


🤔 왜 도입하게 되었는가?

앞서 말한 이유들이 결국 도입 근거가 되었긴 하지만, 우리 팀에 도입하게 된 더 핏한 이유는 아래와 같아요.

  • PinBack이 데스크탑 기반이기는 하지만 공통으로 뺄 컴포넌트가 있다는 점.
  • shadcn/ui가 tailwind css와 호환성이 좋다는 점.
  • 짧은 앱잼 작업 기간 내에 공통 컴포넌트부터 GUI 전체를 작업해야 한다는 점.

따라서 짧은 기간 내에 보일러 플레이트 코드를 제공해주고 tailwind와 호환성이 잘 되는 shadcn/ui를 도입하게 되었고, 모든 공통 컴포넌트를 shadcn을 통해서 구현하는 것이 아닌 필요한 부분만 가져다 쓰면 더 좋은 결과물이 나올 것이라고 생각했어요!


사용 방법

사용 방법은 간단해요! 이미 config는 다 작성했기 때문에 필요한 UI 컴포넌트 명령어만 찾아서 입력해주면 packages/design-system/components/ 아래 관련 폴더 및 코드가 자동 생성돼요! 이후 원하는 스타일로 수정하면 됩니다!!

  1. cd packages/design-system (디자인 시스템 root로로 이동)
  2. 원하는 UI 추가 명령어 작성
  3. 만들어진 파일 이름과 동일하게 folder 생성 후 해당 UI 파일 이동 (button/button.tsx)

ex) Accordion 예시
pnpm dlx shadcn@latest add accordion

[ shadcn/ui components 참고 ]
https://ui.shadcn.com/docs/components


3️⃣twMerge 함수 커스텀

shadcn/ui를 사용하면 자동으로 tailwind-merge와 clsx를 포함한 cn utils함수를 추가해줘요,

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

clsx는 두 개 이상의 className을 합쳐주기 위함이고, tailwind-merge는 기존 클래스와 충돌하게 되는 클래스를 override해줘요. 그러한 목적을 동시에 가진 것이 바로 이 cn 유틸 함수인 것이죠.

하지만 단순히 저렇게 쓰게 되면 약간의 문제가 있어요. 단순 tailwind가 제공하는 클래스가 아니라 커스텀한, 즉 우리 팀에서는 ds에서 추가한 color, typo 등의 토큰(유틸리티 클래스)을 사용하게 되면 문제가 생기게 돼요.

따라서 커스텀한 유틸리티 클래스라는 것을 twMerge함수에게 알려줘야 제대로 작동하는 것이죠. 그래서 tailwind-merge라이브러리에서는 이를 위한 목적의 extendTailwindMerge를 제공해줘요. 그래서 extendTailwindMerge 내부로 커스텀 클래스들을 전달해주고 있는 것이죠.


🤔 정적인 커스텀 클래스 입력

물론 커스텀 값의 충돌 문제는 해결되었지만, 약간 마음에 걸리는게 있었어요. 지금 코드를 보면 'head1', 'head2 등의 값들이 정적인 문자열로 그냥 들어가있는 것을 볼 수 있어요. 이렇게 되면 나중에 디자인 시스템의 토큰이 바뀌게 되면, tailwind-config에서도 값을 바꾸고, 해당 cn 함수에 와서도 바꿔야 하는 불편함이 생길 거라고 생각했어요.

즉 theme 관련 token을 중앙화해서 한 곳에만 둬야 유지보수가 쉽다는 것이죠. 하지만 결국 위에서 언급했듯이 tailwind v4버전 부터는 config를 css파일로 설정하기 때문에 Object형식이 아니에요.

그래서 제가 생각한 방법들은 아래와 같았어요.

  1. 프로젝트 전체를 tailwind v3로 버전을 바꾼다.
  2. 기존 css 형태의 config를 js object로 바꾸는 헬퍼 함수를 따로 만들어 사용한다.

1번은 v4의 장점을 사용해보고 싶어서 생각을 안했고, 2번은 현재로는 조금 리소스가 들 것 같다고 생각했고 일단 디자인 시스템의 큰 변화가 없을 거라 생각해 일단 정적인 값을 사용하기로 결정했어요.

이후에 2번의 헬퍼 함수를 더 고민해보고 싶어요!!~ 더 좋은 방법이 있다면 의견 내주세요!!!

📷 Screenshot

Summary by CodeRabbit

  • 새 기능
    • 공용 디자인 시스템을 도입하고 기본 Button 컴포넌트를 제공했습니다.
    • 앱들이 공유 Tailwind 스타일을 사용하도록 통합했습니다.
  • 스타일
    • 전역 타이포그래피, 색상 토큰, 그라데이션, 섀도우를 일관되게 적용해 UI 일체감을 강화했습니다.
  • 작업(Chores)
    • 디자인 시스템과 Tailwind 설정 관련 개발 의존성을 추가했습니다.
    • 레거시 UI 패키지를 정리해 패키지 구성을 단순화했습니다.

@constantly-dev constantly-dev self-assigned this Aug 19, 2025
@coderabbitai
Copy link

coderabbitai bot commented Aug 19, 2025

Warning

Rate limit exceeded

@constantly-dev has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 3 minutes and 15 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 202d73b and f4f5f3e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • packages/design-system/package.json (1 hunks)
  • packages/design-system/src/components/index.ts (1 hunks)
  • packages/design-system/src/lib/index.ts (1 hunks)
  • packages/design-system/styles.css (1 hunks)

Walkthrough

모노레포에 새로운 디자인 시스템(@pinback/design-system)과 공용 Tailwind 스타일 패키지(@pinback/tailwind-config)를 추가하고, 앱(App.css)에서 공용 스타일을 참조하도록 변경했습니다. 기존 @pinback/ui 패키지를 제거했으며, 디자인 시스템 초기 구성(컴포넌트, 유틸, 스타일, 설정 파일들)을 도입했습니다.

Changes

Cohort / File(s) Summary of edits
앱 공용 스타일 도입
apps/client/package.json, apps/client/src/App.css, apps/landing/package.json, apps/landing/src/App.css
각 앱에 devDependencies로 @pinback/tailwind-config, @pinback/design-system 추가. App.css의 로컬 규칙을 제거하고 @pinback/tailwind-config/shared-styles.css를 import하도록 변경.
Tailwind 공용 패키지 신설
packages/tailwind-config/package.json, packages/tailwind-config/shared-styles.css
새 패키지 생성. ESM 패키지로 공용 CSS(shared-styles.css)를 exports. 공용 스타일/토큰/유틸리티를 Tailwind 지시문과 @theme/@layer로 정의.
디자인 시스템 패키지 신설(설정/스타일)
packages/design-system/package.json, packages/design-system/tsconfig.json, packages/design-system/eslint.config.mjs, packages/design-system/components.json, packages/design-system/styles.css
디자인 시스템 패키지 생성 및 빌드/린트/타입 설정 추가. shadcn UI schema 및 alias/tailwind 설정 파일 추가. 공용 스타일을 내부 styles.css에서 재노출(import). ESLint 설정의 import 경로를 @pinback/eslint-config/...로 갱신.
디자인 시스템 컴포넌트/유틸
packages/design-system/src/components/button/Button.tsx, packages/design-system/src/components/index.tsx, packages/design-system/src/lib/utils.ts
기본 Button 컴포넌트 추가 및 인덱스에서 명명 재익스포트. Tailwind 클래스 병합 유틸 cn 추가(clsx+tailwind-merge 확장).
레거시 UI 패키지 제거
packages/ui/package.json, packages/ui/tsconfig.json, packages/ui/src/button.tsx, packages/ui/src/card.tsx, packages/ui/src/code.tsx
@pinback/ui 패키지와 포함 컴포넌트(Button, Card, Code) 및 tsconfig 삭제.

Sequence Diagram(s)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

⚙️ Setting, config, needs-review, frontend

Suggested reviewers

  • jllee000
  • karnelll
  • jjangminii

Poem

새 깃털 고운 바람 타고, 스타일을 묶어오네 ✨
꼬깃꼬깃 로컬 CSS, 이제는 한데 모아 휙—
버튼 하나 톡 튀어나와, 디자인 숲에 인사하고
오래된 굴은 정리하고, 새 굴로 폴짝!
꼬리로 머지 누르고, 오늘도 예쁜 빛깔로 🐇🎨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch setting/#4/tailwind-config

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

🧹 Nitpick comments (6)
packages/tailwind-config/package.json (1)

1-14: 공유 CSS 패키지 스캐폴딩 좋습니다 — 배포 표면 축소와 트리셰이킹 신호 추가 제안
private 패키지라도 지금 메타데이터를 정리해두면 향후 publish 전환 시 안전합니다. CSS 패키지 특성상 sideEffects 표시와 파일 화이트리스트를 추천합니다.

제안(diff):

 {
   "name": "@pinback/tailwind-config",
   "version": "0.0.0",
   "type": "module",
   "private": true,
+  "description": "Shared Tailwind CSS tokens and utilities for the Pinback monorepo",
   "exports": {
     ".": "./shared-styles.css",
     "./shared-styles.css": "./shared-styles.css"
   },
+  "sideEffects": ["*.css"],
+  "files": ["shared-styles.css"],
+  "peerDependencies": {
+    "tailwindcss": "^4.1.0"
+  },
   "devDependencies": {
     "postcss": "^8.5.6",
     "tailwindcss": "^4.1.12"
   }
 }
  • sideEffects: CSS가 트리셰이킹으로 제거되는 것을 방지
  • files: 패키지에 포함될 파일을 최소화
  • peerDependencies: 모노레포 내 Tailwind 버전 정합성 보조(실제 처리는 각 앱에서 이루어짐)
apps/landing/package.json (1)

20-21: design-system/tailwind-config를 devDependencies가 아닌 dependencies로 이동 고려

런타임에 직접 import되는 패키지들은 일반적으로 dependencies로 두는 것이 안전합니다(특히 SSR/서버 빌드 환경에서 devOnly 설치가 생략될 수 있음). 프론트 전용 번들링 워크플로라면 현재도 동작하겠지만, 배포 파이프라인/SSR 계획이 있다면 이동을 권장합니다.

가능한 변경 예시:

   "dependencies": {
     "react": "^19.1.1",
-    "react-dom": "^19.1.1"
+    "react-dom": "^19.1.1",
+    "@pinback/tailwind-config": "workspace:*",
+    "@pinback/design-system": "workspace:*"
   },
   "devDependencies": {
     "@eslint/js": "^9.33.0",
     "@pinback/eslint-config": "workspace:*",
     "@pinback/typescript-config": "workspace:*",
-    "@pinback/tailwind-config": "workspace:*",
-    "@pinback/design-system": "workspace:*",
packages/design-system/src/lib/utils.ts (1)

108-110: 가독성을 위해 clsx 스프레드 호출 권장

현재 구현도 동작하지만, 관용적으로 clsx(...inputs) 형태가 읽기 쉽습니다.

-export const cn = (...inputs: ClassValue[]) => {
-  return twMerge(clsx(inputs));
-};
+export const cn = (...inputs: ClassValue[]) => {
+  return twMerge(clsx(...inputs));
+};
packages/design-system/package.json (1)

1-10: CSS가 tree-shaking에 의해 제거되지 않도록 sideEffects 선언 추가

패키지에서 CSS(./src/styles.css)를 공개 API로 노출하므로 sideEffects 설정으로 보존을 명시하는 것이 안전합니다.

아래처럼 상단 필드에 추가하세요:

 {
   "name": "@pinback/design-system",
   "version": "0.0.0",
   "private": true,
+  "sideEffects": [
+    "./src/styles.css",
+    "*.css"
+  ],
   "exports": {
     "./ui": "./src/components/index.ts",
     "./icons": "./src/icons/index.ts",
     "./styles": "./src/styles.css",
     "./utils": "./src/lib/index.ts"
   },
packages/tailwind-config/shared-styles.css (1)

1-1: Biome 파서/룰 무시 설정 검토

Tailwind v4의 @theme/@utility는 일부 도구에서 미지원입니다. 위 와일드카드 라인 제거 후에도 Biome가 noUnknownTypeSelector 등으로 경고한다면, 해당 파일에 한해 룰 비활성화(overrides) 또는 파일 헤더에 /* biome-ignore ... */ 주석을 고려하세요.

예시(biome 설정 override):

{
  "overrides": [
    {
      "include": ["packages/tailwind-config/shared-styles.css"],
      "linter": {
        "rules": {
          "correctness/noUnknownPseudoClass": "off",
          "correctness/noUnknownTypeSelector": "off"
        }
      }
    }
  ]
}
packages/design-system/src/components/badge.tsx (1)

28-44: forwardRef 미사용 — ref 전달/호환성 개선 제안

외부에서 ref를 사용할 수 있도록 React.forwardRef로 감싸는 것을 권장합니다(shadcn 관례와도 일치).

적용 패치:

-function Badge({
-  className,
-  variant,
-  asChild = false,
-  ...props
-}: React.ComponentProps<"span"> &
-  VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
-  const Comp = asChild ? Slot : "span"
-
-  return (
-    <Comp
-      data-slot="badge"
-      className={cn(badgeVariants({ variant }), className)}
-      {...props}
-    />
-  )
-}
+const Badge = React.forwardRef<
+  React.ElementRef<"span">,
+  React.ComponentProps<"span"> & VariantProps<typeof badgeVariants> & { asChild?: boolean }
+>(({ className, variant, asChild = false, ...props }, ref) => {
+  const Comp = asChild ? Slot : "span"
+  return (
+    <Comp
+      ref={ref}
+      data-slot="badge"
+      className={cn(badgeVariants({ variant }), className)}
+      {...props}
+    />
+  )
+})
+
+Badge.displayName = "Badge"
 
 export { Badge, badgeVariants }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled
  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5117bb9 and ca7ce44.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (18)
  • apps/client/package.json (1 hunks)
  • apps/client/src/App.css (1 hunks)
  • apps/landing/package.json (1 hunks)
  • apps/landing/src/App.css (1 hunks)
  • packages/design-system/components.json (1 hunks)
  • packages/design-system/eslint.config.mjs (1 hunks)
  • packages/design-system/package.json (1 hunks)
  • packages/design-system/src/components/badge.tsx (1 hunks)
  • packages/design-system/src/lib/utils.ts (1 hunks)
  • packages/design-system/src/styles.css (1 hunks)
  • packages/design-system/tsconfig.json (1 hunks)
  • packages/tailwind-config/package.json (1 hunks)
  • packages/tailwind-config/shared-styles.css (1 hunks)
  • packages/ui/package.json (0 hunks)
  • packages/ui/src/button.tsx (0 hunks)
  • packages/ui/src/card.tsx (0 hunks)
  • packages/ui/src/code.tsx (0 hunks)
  • packages/ui/tsconfig.json (0 hunks)
💤 Files with no reviewable changes (5)
  • packages/ui/tsconfig.json
  • packages/ui/src/button.tsx
  • packages/ui/src/code.tsx
  • packages/ui/src/card.tsx
  • packages/ui/package.json
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#2
File: pnpm-workspace.yaml:3-3
Timestamp: 2025-08-18T13:48:59.021Z
Learning: constantly-dev는 docs 디렉터리를 컨벤션 문서 추가용으로 사용할 예정이라고 명시했습니다.
📚 Learning: 2025-07-04T10:12:01.690Z
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#10
File: apps/landing/src/index.css:1-1
Timestamp: 2025-07-04T10:12:01.690Z
Learning: In TailwindCSS v4, the import "tailwindcss"; syntax is the new recommended approach that replaces the three separate tailwind directives (tailwind base;, tailwind components;, tailwind utilities;). This single import pulls in all of Tailwind's preflight, components, and utilities in one step and is used with the tailwindcss/vite plugin.

Applied to files:

  • packages/design-system/src/styles.css
  • apps/client/package.json
  • apps/landing/package.json
  • apps/client/src/App.css
  • apps/landing/src/App.css
  • packages/tailwind-config/shared-styles.css
  • packages/tailwind-config/package.json
📚 Learning: 2025-07-04T10:12:01.690Z
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#10
File: apps/landing/src/index.css:1-1
Timestamp: 2025-07-04T10:12:01.690Z
Learning: In TailwindCSS v4, the import "tailwindcss"; syntax is the new recommended approach that replaces the three separate tailwind directives (tailwind base;, tailwind components;, tailwind utilities;). This is used with the tailwindcss/vite plugin.

Applied to files:

  • packages/design-system/src/styles.css
  • apps/client/src/App.css
  • apps/landing/src/App.css
  • packages/tailwind-config/shared-styles.css
  • packages/tailwind-config/package.json
🪛 Biome (2.1.2)
packages/tailwind-config/shared-styles.css

[error] 161-161: expected , but instead found *

Remove *

(parse)


[error] 161-161: expected , but instead found ;

Remove ;

(parse)


[error] 164-164: expected , but instead found --color-main0

Remove --color-main0

(parse)


[error] 164-164: Unexpected value or character.

Expected one of:

(parse)


[error] 164-164: expected , but instead found ;

Remove ;

(parse)


[error] 165-165: expected , but instead found --color-main100

Remove --color-main100

(parse)


[error] 165-165: Unexpected value or character.

Expected one of:

(parse)


[error] 165-165: expected , but instead found ;

Remove ;

(parse)


[error] 166-166: expected , but instead found --color-main200

Remove --color-main200

(parse)


[error] 166-166: Unexpected value or character.

Expected one of:

(parse)


[error] 166-166: Expected an identifier but instead found '99'.

Expected an identifier here.

(parse)


[error] 166-166: expected , but instead found dfc2

Remove dfc2

(parse)


[error] 166-166: expected , but instead found ;

Remove ;

(parse)


[error] 167-167: expected , but instead found --color-main300

Remove --color-main300

(parse)


[error] 167-167: Unexpected value or character.

Expected one of:

(parse)


[error] 167-167: Expected an identifier but instead found '75'.

Expected an identifier here.

(parse)


[error] 167-167: expected , but instead found d8af

Remove d8af

(parse)


[error] 167-167: expected , but instead found ;

Remove ;

(parse)


[error] 168-168: expected , but instead found --color-main400

Remove --color-main400

(parse)


[error] 168-168: Unexpected value or character.

Expected one of:

(parse)


[error] 168-168: Expected an identifier but instead found '54'.

Expected an identifier here.

(parse)


[error] 168-168: expected , but instead found d19d

Remove d19d

(parse)


[error] 168-168: expected , but instead found ;

Remove ;

(parse)


[error] 169-169: expected , but instead found --color-main500

Remove --color-main500

(parse)


[error] 169-169: Unexpected value or character.

Expected one of:

(parse)


[error] 169-169: Expected an identifier but instead found '2'.

Expected an identifier here.

(parse)


[error] 169-169: expected , but instead found aa971

Remove aa971

(parse)


[error] 169-169: expected , but instead found ;

Remove ;

(parse)


[error] 170-170: expected , but instead found --color-main600

Remove --color-main600

(parse)


[error] 170-170: Unexpected value or character.

Expected one of:

(parse)


[error] 170-170: Expected an identifier but instead found '1'.

Expected an identifier here.

(parse)


[error] 170-170: expected , but instead found f7f55

Remove f7f55

(parse)


[error] 170-170: expected , but instead found ;

Remove ;

(parse)


[error] 173-173: expected , but instead found --color-gradient-start

Remove --color-gradient-start

(parse)


[error] 173-173: Unexpected value or character.

Expected one of:

(parse)


[error] 173-173: expected , but instead found ;

Remove ;

(parse)


[error] 174-174: expected , but instead found --color-gradient-end

Remove --color-gradient-end

(parse)


[error] 174-174: Unexpected value or character.

Expected one of:

(parse)


[error] 174-174: Expected an identifier but instead found '33'.

Expected an identifier here.

(parse)


[error] 174-174: expected , but instead found d08f

Remove d08f

(parse)


[error] 174-174: expected , but instead found ;

Remove ;

(parse)


[error] 177-177: expected , but instead found --color-secondary

Remove --color-secondary

(parse)


[error] 177-177: Unexpected value or character.

Expected one of:

(parse)


[error] 177-177: expected , but instead found ;

Remove ;

(parse)


[error] 180-180: expected , but instead found --color-gray0

Remove --color-gray0

(parse)


[error] 180-180: Unexpected value or character.

Expected one of:

(parse)


[error] 180-180: expected , but instead found ;

Remove ;

(parse)


[error] 181-181: expected , but instead found --color-gray100

Remove --color-gray100

(parse)


[error] 181-181: Unexpected value or character.

Expected one of:

(parse)


[error] 181-181: expected , but instead found ;

Remove ;

(parse)


[error] 182-182: expected , but instead found --color-gray200

Remove --color-gray200

(parse)


[error] 182-182: Unexpected value or character.

Expected one of:

(parse)


[error] 182-182: expected , but instead found ;

Remove ;

(parse)


[error] 183-183: expected , but instead found --color-gray300

Remove --color-gray300

(parse)


[error] 183-183: Unexpected value or character.

Expected one of:

(parse)


[error] 183-183: expected , but instead found ;

Remove ;

(parse)


[error] 184-184: expected , but instead found --color-gray400

Remove --color-gray400

(parse)


[error] 184-184: Unexpected value or character.

Expected one of:

(parse)


[error] 184-184: expected , but instead found ;

Remove ;

(parse)


[error] 185-185: expected , but instead found --color-gray500

Remove --color-gray500

(parse)


[error] 185-185: Unexpected value or character.

Expected one of:

(parse)


[error] 185-185: expected , but instead found ;

Remove ;

(parse)


[error] 186-186: expected , but instead found --color-gray600

Remove --color-gray600

(parse)


[error] 186-186: Unexpected value or character.

Expected one of:

(parse)


[error] 186-186: Expected an identifier but instead found '848491'.

Expected an identifier here.

(parse)


[error] 187-187: expected , but instead found --color-gray700

Remove --color-gray700

(parse)


[error] 187-187: Unexpected value or character.

Expected one of:

(parse)


[error] 187-187: Expected an identifier but instead found '5'.

Expected an identifier here.

(parse)


[error] 187-187: expected , but instead found c5c64

Remove c5c64

(parse)


[error] 187-187: expected , but instead found ;

Remove ;

(parse)


[error] 188-188: expected , but instead found --color-gray800

Remove --color-gray800

(parse)


[error] 188-188: Unexpected value or character.

Expected one of:

(parse)


[error] 188-188: Expected an identifier but instead found '404048'.

Expected an identifier here.

(parse)


[error] 189-189: expected , but instead found --color-gray900

Remove --color-gray900

(parse)


[error] 189-189: Unexpected value or character.

Expected one of:

(parse)


[error] 189-189: Expected an identifier but instead found '28282'.

Expected an identifier here.

(parse)


[error] 189-189: expected , but instead found f

Remove f

(parse)


[error] 189-189: expected , but instead found ;

Remove ;

(parse)


[error] 192-192: expected , but instead found --color-white-bg

Remove --color-white-bg

(parse)


[error] 192-192: Unexpected value or character.

Expected one of:

(parse)


[error] 192-192: expected , but instead found ;

Remove ;

(parse)


[error] 193-193: expected , but instead found --color-gray-bg

Remove --color-gray-bg

(parse)


[error] 193-193: Unexpected value or character.

Expected one of:

(parse)


[error] 193-193: expected , but instead found ;

Remove ;

(parse)


[error] 196-196: expected , but instead found --color-font-black-1

Remove --color-font-black-1

(parse)


[error] 196-196: Unexpected value or character.

Expected one of:

(parse)


[error] 196-196: Expected an identifier but instead found '111111'.

Expected an identifier here.

(parse)


[error] 197-197: expected , but instead found --color-font-gray-2

Remove --color-font-gray-2

(parse)


[error] 197-197: Unexpected value or character.

Expected one of:

(parse)


[error] 197-197: Expected an identifier but instead found '505050'.

Expected an identifier here.

(parse)


[error] 198-198: expected , but instead found --color-font-gray-3

Remove --color-font-gray-3

(parse)


[error] 198-198: Unexpected value or character.

Expected one of:

(parse)


[error] 198-198: Expected an identifier but instead found '767676'.

Expected an identifier here.

(parse)


[error] 199-199: expected , but instead found --color-font-ltgray-4

Remove --color-font-ltgray-4

(parse)


[error] 199-199: Unexpected value or character.

Expected one of:

(parse)


[error] 199-199: Expected an identifier but instead found '999999'.

Expected an identifier here.

(parse)


[error] 200-200: expected , but instead found --color-font-ltgray-5

Remove --color-font-ltgray-5

(parse)


[error] 200-200: Unexpected value or character.

Expected one of:

(parse)


[error] 200-200: expected , but instead found ;

Remove ;

(parse)


[error] 203-203: expected , but instead found --color-error

Remove --color-error

(parse)


[error] 203-203: Unexpected value or character.

Expected one of:

(parse)


[error] 203-203: expected , but instead found ;

Remove ;

(parse)


[error] 204-204: expected , but instead found --color-success

Remove --color-success

(parse)


[error] 204-204: Unexpected value or character.

Expected one of:

(parse)


[error] 204-204: Expected an identifier but instead found '00'.

Expected an identifier here.

(parse)


[error] 204-204: expected , but instead found c673

Remove c673

(parse)


[error] 204-204: expected , but instead found ;

Remove ;

(parse)


[error] 207-207: expected , but instead found --color-category-red-text

Remove --color-category-red-text

(parse)


[error] 207-207: Unexpected value or character.

Expected one of:

(parse)


[error] 207-207: expected , but instead found ;

Remove ;

(parse)


[error] 208-208: expected , but instead found --color-category-purple-text

Remove --color-category-purple-text

(parse)


[error] 208-208: Unexpected value or character.

Expected one of:

(parse)


[error] 208-208: Expected an identifier but instead found '612694'.

Expected an identifier here.

(parse)


[error] 209-209: expected , but instead found --color-category-navyblue-text

Remove --color-category-navyblue-text

(parse)


[error] 209-209: Unexpected value or character.

Expected one of:

(parse)


[error] 209-209: Expected an identifier but instead found '2'.

Expected an identifier here.

(parse)


[error] 209-209: expected , but instead found a378e

Remove a378e

(parse)


[error] 209-209: expected , but instead found ;

Remove ;

(parse)


[error] 210-210: expected , but instead found --color-category-skyblue-text

Remove --color-category-skyblue-text

(parse)


[error] 210-210: Unexpected value or character.

Expected one of:

(parse)


[error] 210-210: Expected an identifier but instead found '3277'.

Expected an identifier here.

(parse)


[error] 210-210: expected , but instead found b8

Remove b8

(parse)


[error] 210-210: expected , but instead found ;

Remove ;

(parse)


[error] 211-211: expected , but instead found --color-category-emerald-text

Remove --color-category-emerald-text

(parse)


[error] 211-211: Unexpected value or character.

Expected one of:

(parse)


[error] 211-211: Expected an identifier but instead found '38818'.

Expected an identifier here.

(parse)


[error] 211-211: expected , but instead found d

Remove d

(parse)


[error] 211-211: expected , but instead found ;

Remove ;

(parse)


[error] 212-212: expected , but instead found --color-category-navygreen-text

Remove --color-category-navygreen-text

(parse)


[error] 212-212: Unexpected value or character.

Expected one of:

(parse)


[error] 212-212: Expected an identifier but instead found '2'.

Expected an identifier here.

(parse)


[error] 212-212: expected , but instead found c675c

Remove c675c

(parse)


[error] 212-212: expected , but instead found ;

Remove ;

(parse)


[error] 213-213: expected , but instead found --color-category-khaki-text

Remove --color-category-khaki-text

(parse)


[error] 213-213: Unexpected value or character.

Expected one of:

(parse)


[error] 213-213: Expected an identifier but instead found '62893'.

Expected an identifier here.

(parse)


[error] 213-213: expected , but instead found d

Remove d

(parse)


[error] 213-213: expected , but instead found ;

Remove ;

(parse)


[error] 214-214: expected , but instead found --color-category-orange-text

Remove --color-category-orange-text

(parse)


[error] 214-214: Unexpected value or character.

Expected one of:

(parse)


[error] 214-214: expected , but instead found ;

Remove ;

(parse)


[error] 215-215: expected , but instead found --color-category-amber-text

Remove --color-category-amber-text

(parse)


[error] 215-215: Unexpected value or character.

Expected one of:

(parse)


[error] 215-215: expected , but instead found ;

Remove ;

(parse)


[error] 216-216: expected , but instead found --color-category-maroon-text

Remove --color-category-maroon-text

(parse)


[error] 216-216: Unexpected value or character.

Expected one of:

(parse)


[error] 216-216: Expected an identifier but instead found '4'.

Expected an identifier here.

(parse)


[error] 216-216: expected , but instead found a352f

Remove a352f

(parse)


[error] 216-216: expected , but instead found ;

Remove ;

(parse)


[error] 219-219: expected , but instead found --color-category-red-bg

Remove --color-category-red-bg

(parse)


[error] 219-219: Unexpected value or character.

Expected one of:

(parse)


[error] 219-219: expected , but instead found ;

Remove ;

(parse)


[error] 220-220: expected , but instead found --color-category-purple-bg

Remove --color-category-purple-bg

(parse)


[error] 220-220: Unexpected value or character.

Expected one of:

(parse)


[error] 220-220: expected , but instead found ;

Remove ;

(parse)


[error] 221-221: expected , but instead found --color-category-navyblue-bg

Remove --color-category-navyblue-bg

(parse)


[error] 221-221: Unexpected value or character.

Expected one of:

(parse)


[error] 221-221: expected , but instead found ;

Remove ;

(parse)


[error] 222-222: expected , but instead found --color-category-skyblue-bg

Remove --color-category-skyblue-bg

(parse)


[error] 222-222: Unexpected value or character.

Expected one of:

(parse)


[error] 222-222: expected , but instead found ;

Remove ;

(parse)


[error] 223-223: expected , but instead found --color-category-emerald-bg

Remove --color-category-emerald-bg

(parse)


[error] 223-223: Unexpected value or character.

Expected one of:

(parse)


[error] 223-223: expected , but instead found ;

Remove ;

(parse)


[error] 224-224: expected , but instead found --color-category-navygreen-bg

Remove --color-category-navygreen-bg

(parse)


[error] 224-224: Unexpected value or character.

Expected one of:

(parse)


[error] 224-224: expected , but instead found ;

Remove ;

(parse)


[error] 225-225: expected , but instead found --color-category-khaki-bg

Remove --color-category-khaki-bg

(parse)


[error] 225-225: Unexpected value or character.

Expected one of:

(parse)


[error] 225-225: expected , but instead found ;

Remove ;

(parse)


[error] 226-226: expected , but instead found --color-category-orange-bg

Remove --color-category-orange-bg

(parse)


[error] 226-226: Unexpected value or character.

Expected one of:

(parse)


[error] 226-226: expected , but instead found ;

Remove ;

(parse)


[error] 227-227: expected , but instead found --color-category-amber-bg

Remove --color-category-amber-bg

(parse)


[error] 227-227: Unexpected value or character.

Expected one of:

(parse)


[error] 227-227: expected , but instead found ;

Remove ;

(parse)


[error] 228-228: expected , but instead found --color-category-maroon-bg

Remove --color-category-maroon-bg

(parse)


[error] 228-228: Unexpected value or character.

Expected one of:

(parse)


[error] 228-228: expected , but instead found ;

Remove ;

(parse)


[error] 231-231: expected , but instead found layer

Remove layer

(parse)


[error] 161-161: Unexpected unknown pseudo-class initial

See MDN web docs for more details.

(lint/correctness/noUnknownPseudoClass)


[error] 166-166: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 167-167: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 168-168: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 169-169: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 170-170: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 174-174: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 187-187: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 189-189: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 204-204: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 209-209: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 210-210: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 211-211: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 212-212: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 213-213: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 216-216: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 231-231: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)

🔇 Additional comments (6)
packages/design-system/eslint.config.mjs (1)

1-4: ESLint 프리셋 경로 워크스페이스 해상도 확인됨

  • packages/eslint-config/package.json에서 "name": "@pinback/eslint-config" 패키지 존재 확인
  • packages/design-system, apps/landing, apps/client 에서 @pinback/eslint-config/react-internal 엔트리포인트 정상 참조 확인

워크스페이스 내 해상도 문제는 없습니다.

apps/client/package.json (1)

20-21: @pinback/design-system 의존성 위치 검증 필요

TS/TSX 및 CSS/SCSS 검색 결과 @pinback/design-system import나 스타일 사용이 발견되지 않았습니다.
실제 런타임에서 사용되는 컴포넌트나 스타일이 있는지 직접 검토한 뒤,

  • 사용된다면 devDependenciesdependencies로 이동
  • 사용되지 않으면 devDependencies에 그대로 유지

해주세요.

packages/design-system/src/styles.css (1)

1-1: styles 경로 export 노출 확인 완료

  • packages/design-system/package.json의 exports"./styles": "./src/styles.css" 항목이 있어 외부 소비자가 @pinback/design-system/styles로 임포트할 수 있습니다.
apps/landing/src/App.css (1)

1-1: @tailwindcss/vite 플러그인 및 공유 스타일 import 확인 완료

  • apps/landing/vite.config.ts에서 import tailwindcss from '@tailwindcss/vite'; 확인
  • apps/client/vite.config.ts에서 import tailwindcss from '@tailwindcss/vite'; 확인
  • apps/landing/src/App.css에서 @import '@pinback/tailwind-config/shared-styles.css'; 확인
  • apps/client/src/App.css에서 @import '@pinback/tailwind-config/shared-styles.css'; 확인

공유 스타일 치환 및 플러그인 설정에 문제가 없습니다.

apps/client/src/App.css (1)

1-1: 공유 스타일로의 일원화 좋습니다

앱 로컬 CSS를 제거하고 monorepo 공유 스타일을 import하는 방향이 명확하고 유지보수에 유리합니다. shared-styles.css 내부에서 Tailwind v4의 @import "tailwindcss";가 포함되어 있는지만 한번 확인해 주세요.

packages/design-system/components.json (1)

7-12: components.json Tailwind 설정 검증 요청

  • 파일: packages/design-system/components.json
  • 위치: "tailwind" 객체 내 "config" / "prefix"
  1. "config": ""
    빈 문자열 지정 시 shadcn/ui CLI 또는 Tailwind 설정 로드 과정에서 오류를 유발할 수 있습니다.

    • Tailwind v4(CSS 기반 설정) 사용 시 해당 필드를 제거
    • 또는 실제 설정 파일 경로(e.g. ./tailwind.config.ts)를 지정
  2. "prefix"
    현 스키마에서 tailwind 객체 내부에 위치해야 하는지, 또는 지원 여부를 공식 문서에서 확인

권장 예시:

 "tailwind": {
-  "config": "",
   "css": "./src/styles.css",
   "baseColor": "neutral",
   "cssVariables": true,
-  "prefix": ""
+  "prefix": ""
 }

또는

 "tailwind": {
-  "config": "",
+  "config": "./tailwind.config.ts",
   "css": "./src/styles.css",
   "baseColor": "neutral",
   "cssVariables": true,
   "prefix": ""
 }

shadcn CLI 검증

cd packages/design-system
pnpm dlx shadcn@latest add badge

⚠️ --dry-run 옵션은 현재 shadcn CLI에서 지원되지 않습니다.

위 검증 결과를 공유해주세요.

Comment on lines 5 to 10
"exports": {
"./ui": "./src/components/index.ts",
"./icons": "./src/icons/index.ts",
"./styles": "./src/styles.css",
"./utils": "./src/lib/index.ts"
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

exports 경로 존재 여부 검증 필요(UI/icons/utils/styles 엔트리)

./src/components/index.ts, ./src/icons/index.ts, ./src/lib/index.ts, ./src/styles.css가 모두 실제로 존재해야 합니다. 누락 시 소비자 빌드가 실패합니다.

다음 스크립트로 존재 여부를 확인해 주세요:


🏁 Script executed:

#!/bin/bash
set -euo pipefail
echo "Check exported entry files exist:"
for f in "packages/design-system/src/components/index.ts" \
         "packages/design-system/src/icons/index.ts" \
         "packages/design-system/src/lib/index.ts" \
         "packages/design-system/src/styles.css"
do
  if [ -f "$f" ]; then
    echo "OK  - $f"
  else
    echo "MISS- $f"
  fi
done

Length of output: 1477


필수 항목 누락: package.json의 exports 경로에 지정된 파일이 존재하지 않습니다

packages/design-system/package.jsonexports에 지정된 엔트리 파일 중 다수가 실제로 없어서, 소비자 프로젝트에서 빌드 실패가 발생합니다.

수정이 필요한 경로:

  • packages/design-system/src/components/index.ts (exports["./ui"])
  • packages/design-system/src/icons/index.ts (exports["./icons"])
  • packages/design-system/src/lib/index.ts (exports["./utils"])

※ packages/design-system/src/styles.css (exports["./styles"])는 정상 확인됨

위 파일들을 생성하거나 올바른 경로로 수정해주시기 바랍니다.

🤖 Prompt for AI Agents
In packages/design-system/package.json around lines 5 to 10, the "exports"
entries reference files that do not exist; create the missing entry files or
update the export paths to match real files. Specifically either add these files
with appropriate re-exports/exports:
packages/design-system/src/components/index.ts,
packages/design-system/src/icons/index.ts,
packages/design-system/src/lib/index.ts (keeping src/styles.css as-is), or
change the corresponding exports["./ui"], exports["./icons"], and
exports["./utils"] to point to existing module paths; after adding files ensure
they export the component/icon/lib public APIs and run a local build to verify
the package consumers no longer fail.

Comment on lines 12 to 20
default:
"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
secondary:
"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
destructive:
"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
outline:
"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
},
Copy link

@coderabbitai coderabbitai bot Aug 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

토큰 미스매치 가능성: bg-primary/ring-ring 등 사용

이 컴포넌트의 variant 클래스로 bg-primary, text-primary-foreground, bg-secondary, bg-destructive, ring-ring, bg-accent 등을 사용합니다. 현재 공유 스타일(@theme)에 해당 토큰이 없으므로, 위 CSS 파일에 제안한 호환 토큰을 추가하지 않으면 스타일이 누락될 수 있습니다.

다음 스크립트로 토큰 정의 유무와 해당 클래스 사용처를 한 번에 확인해 주세요:


🏁 Script executed:

#!/bin/bash
set -euo pipefail
echo "Search component classes that require shadcn tokens:"
rg -n -C2 -g 'packages/design-system/**' -e '\b(bg|text|border|ring)-(primary|secondary|destructive|accent|ring)\b' 

echo
echo "Check theme tokens exist:"
rg -n -C1 -g 'packages/**/shared-styles.css' -e '--color-(primary|secondary|destructive|accent|ring|foreground|background)'

Length of output: 2471


토큰 정의 누락 확인: badge 컴포넌트에서 참조하는 CSS 토큰 추가 필요

packages/design-system/src/components/badge.tsx에서는 다음 토큰을 사용하고 있으나
packages/tailwind-config/shared-styles.css에는 --color-secondary만 정의되어 있어 스타일이 누락됩니다.

필요한 토큰 목록:

  • --color-primary
  • --color-primary-foreground
  • --color-secondary-foreground
  • --color-destructive
  • --color-accent
  • --color-accent-foreground
  • --color-ring
  • --color-foreground

위 토큰들을 shared-styles.css에 정의하여 디자인 시스템 전체에서 일관된 스타일을 보장해주세요.

🤖 Prompt for AI Agents
In packages/design-system/src/components/badge.tsx around lines 12 to 20, the
badge variants reference several CSS custom properties that are not defined in
packages/tailwind-config/shared-styles.css; add the following token definitions
to shared-styles.css: --color-primary, --color-primary-foreground,
--color-secondary-foreground, --color-destructive, --color-accent,
--color-accent-foreground, --color-ring, and --color-foreground (provide
sensible default HEX/RGB values or map them to existing palette variables and
include dark-mode counterparts if applicable) so the badge styles resolve
consistently across the design system.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shadcn/ui에서 init을 하면 추가되는 값들인데, 이번에 수동으로 설정을 해서 해당 color 설정을 못했네요! 추가했습니다 👍

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@constantly-dev 감사합니다! shadcn/ui init 과정에서 자동으로 추가되는 토큰들을 수동 설정 시 놓치기 쉬운데, 빠르게 추가해 주셨네요. 이제 badge 컴포넌트가 디자인 시스템과 일관되게 작동할 것입니다! 👍


🧠 Learnings used
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#2
File: pnpm-workspace.yaml:3-3
Timestamp: 2025-08-18T13:48:59.021Z
Learning: constantly-dev는 docs 디렉터리를 컨벤션 문서 추가용으로 사용할 예정이라고 명시했습니다.

Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#5
File: apps/extension/src/index.css:1-1
Timestamp: 2025-08-19T17:18:57.657Z
Learning: constantly-dev는 디자인 시스템 설정 PR 머지 후 `import 'pinback/tailwind-config/shared-styles.css';`를 `app.css`나 `index.css`에서 사용하여 공유 스타일을 관리할 계획입니다.

If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

Comment on lines +4 to +106
const twMerge = extendTailwindMerge({
extend: {
theme: {
text: [
'head1',
'head2',
'head3',
'head4',
'head5',
'head6',
'sub1-sb',
'sub1-m',
'sub2-b',
'sub2-sb',
'sub3-b',
'sub3-sb',
'sub4-sb',
'sub5-sb',
'body1-m',
'body1-r',
'body2-m',
'body2-r',
'body3-r',
'body4-r',
'caption1-sb',
'caption1-m',
'caption2-sb',
'caption2-m',
],

color: [
// main
'main0',
'main100',
'main200',
'main300',
'main400',
'main500',
'main600',

// gradient
'gradient-start',
'gradient-end',

// secondary
'secondary',

// grayscale
'gray0',
'gray100',
'gray200',
'gray300',
'gray400',
'gray500',
'gray600',
'gray700',
'gray800',
'gray900',

// bg
'white-bg',
'gray-bg',

// font
'font-black-1',
'font-gray-2',
'font-gray-3',
'font-ltgray-4',
'font-ltgray-5',

// state
'error',
'success',

// category text
'category-red-text',
'category-purple-text',
'category-navyblue-text',
'category-skyblue-text',
'category-emerald-text',
'category-navygreen-text',
'category-khaki-text',
'category-orange-text',
'category-amber-text',
'category-maroon-text',

// category bg
'category-red-bg',
'category-purple-bg',
'category-navyblue-bg',
'category-skyblue-bg',
'category-emerald-bg',
'category-navygreen-bg',
'category-khaki-bg',
'category-orange-bg',
'category-amber-bg',
'category-maroon-bg',
],

shadow: ['popup'],
},
},
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

tailwind-merge 확장 키가 기본 스키마와 불일치합니다(colors/fontSize/boxShadow 사용 권장)

tailwind-merge의 theme 키는 Tailwind 테마 키와 매핑됩니다. 현재 text, color, shadow로 지정되어 있어 의도한 병합 규칙이 적용되지 않을 가능성이 큽니다. 일반적으로 다음 키를 사용해야 합니다:

  • 글자 크기 토큰: fontSize
  • 색상 토큰: colors
  • 그림자 토큰: boxShadow

키만 교체해도 text-*, bg-*, shadow-* 계열의 충돌 해소가 기대 동작에 가까워집니다.

 const twMerge = extendTailwindMerge({
   extend: {
     theme: {
-      text: [
+      fontSize: [
         'head1',
         'head2',
         'head3',
         'head4',
         'head5',
         'head6',
         'sub1-sb',
         'sub1-m',
         'sub2-b',
         'sub2-sb',
         'sub3-b',
         'sub3-sb',
         'sub4-sb',
         'sub5-sb',
         'body1-m',
         'body1-r',
         'body2-m',
         'body2-r',
         'body3-r',
         'body4-r',
         'caption1-sb',
         'caption1-m',
         'caption2-sb',
         'caption2-m',
       ],
 
-      color: [
+      colors: [
         // main
         'main0',
         'main100',
         'main200',
         'main300',
         'main400',
         'main500',
         'main600',
 
         // gradient
         'gradient-start',
         'gradient-end',
 
         // secondary
         'secondary',
 
         // grayscale
         'gray0',
         'gray100',
         'gray200',
         'gray300',
         'gray400',
         'gray500',
         'gray600',
         'gray700',
         'gray800',
         'gray900',
 
         // bg
         'white-bg',
         'gray-bg',
 
         // font
         'font-black-1',
         'font-gray-2',
         'font-gray-3',
         'font-ltgray-4',
         'font-ltgray-5',
 
         // state
         'error',
         'success',
 
         // category text
         'category-red-text',
         'category-purple-text',
         'category-navyblue-text',
         'category-skyblue-text',
         'category-emerald-text',
         'category-navygreen-text',
         'category-khaki-text',
         'category-orange-text',
         'category-amber-text',
         'category-maroon-text',
 
         // category bg
         'category-red-bg',
         'category-purple-bg',
         'category-navyblue-bg',
         'category-skyblue-bg',
         'category-emerald-bg',
         'category-navygreen-bg',
         'category-khaki-bg',
         'category-orange-bg',
         'category-amber-bg',
         'category-maroon-bg',
       ],
 
-      shadow: ['popup'],
+      boxShadow: ['popup'],
     },
   },
 });

참고: text-*(font-size)와 text-*(color)가 접두사가 같아 충돌 그룹이 다릅니다. 위 교정으로 fontSize/colors 각각의 그룹에 토큰이 주입되어 올바르게 병합됩니다.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const twMerge = extendTailwindMerge({
extend: {
theme: {
text: [
'head1',
'head2',
'head3',
'head4',
'head5',
'head6',
'sub1-sb',
'sub1-m',
'sub2-b',
'sub2-sb',
'sub3-b',
'sub3-sb',
'sub4-sb',
'sub5-sb',
'body1-m',
'body1-r',
'body2-m',
'body2-r',
'body3-r',
'body4-r',
'caption1-sb',
'caption1-m',
'caption2-sb',
'caption2-m',
],
color: [
// main
'main0',
'main100',
'main200',
'main300',
'main400',
'main500',
'main600',
// gradient
'gradient-start',
'gradient-end',
// secondary
'secondary',
// grayscale
'gray0',
'gray100',
'gray200',
'gray300',
'gray400',
'gray500',
'gray600',
'gray700',
'gray800',
'gray900',
// bg
'white-bg',
'gray-bg',
// font
'font-black-1',
'font-gray-2',
'font-gray-3',
'font-ltgray-4',
'font-ltgray-5',
// state
'error',
'success',
// category text
'category-red-text',
'category-purple-text',
'category-navyblue-text',
'category-skyblue-text',
'category-emerald-text',
'category-navygreen-text',
'category-khaki-text',
'category-orange-text',
'category-amber-text',
'category-maroon-text',
// category bg
'category-red-bg',
'category-purple-bg',
'category-navyblue-bg',
'category-skyblue-bg',
'category-emerald-bg',
'category-navygreen-bg',
'category-khaki-bg',
'category-orange-bg',
'category-amber-bg',
'category-maroon-bg',
],
shadow: ['popup'],
},
},
});
const twMerge = extendTailwindMerge({
extend: {
theme: {
fontSize: [
'head1',
'head2',
'head3',
'head4',
'head5',
'head6',
'sub1-sb',
'sub1-m',
'sub2-b',
'sub2-sb',
'sub3-b',
'sub3-sb',
'sub4-sb',
'sub5-sb',
'body1-m',
'body1-r',
'body2-m',
'body2-r',
'body3-r',
'body4-r',
'caption1-sb',
'caption1-m',
'caption2-sb',
'caption2-m',
],
colors: [
// main
'main0',
'main100',
'main200',
'main300',
'main400',
'main500',
'main600',
// gradient
'gradient-start',
'gradient-end',
// secondary
'secondary',
// grayscale
'gray0',
'gray100',
'gray200',
'gray300',
'gray400',
'gray500',
'gray600',
'gray700',
'gray800',
'gray900',
// bg
'white-bg',
'gray-bg',
// font
'font-black-1',
'font-gray-2',
'font-gray-3',
'font-ltgray-4',
'font-ltgray-5',
// state
'error',
'success',
// category text
'category-red-text',
'category-purple-text',
'category-navyblue-text',
'category-skyblue-text',
'category-emerald-text',
'category-navygreen-text',
'category-khaki-text',
'category-orange-text',
'category-amber-text',
'category-maroon-text',
// category bg
'category-red-bg',
'category-purple-bg',
'category-navyblue-bg',
'category-skyblue-bg',
'category-emerald-bg',
'category-navygreen-bg',
'category-khaki-bg',
'category-orange-bg',
'category-amber-bg',
'category-maroon-bg',
],
boxShadow: ['popup'],
},
},
});
🤖 Prompt for AI Agents
packages/design-system/src/lib/utils.ts lines 4-106: the extendTailwindMerge
theme keys use nonstandard names (text/color/shadow) so tailwind-merge won’t map
them to Tailwind groups; replace those keys with the correct Tailwind theme
keys—use fontSize for text tokens, colors for color tokens, and boxShadow for
shadow tokens—so that the custom tokens are injected into the proper collision
groups (also ensure token names match the expected prefixes like text- and bg-
where applicable).

Comment on lines +3 to +10
"compilerOptions": {
"outDir": "dist",
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
"jsx": "react-jsx"
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

라이브러리 배포/소비 관점에서 rootDir 및 타입 선언 출력 설정을 고려해 주세요

현재 outDir만 지정되어 있어 .storybook 등 비소스 파일이 dist에 같이 방출될 가능성이 있습니다. 라이브러리 패키지인 만큼 rootDir와 declaration을 지정해 두는 것을 권장합니다.

아래처럼 최소 설정을 추가하는 것을 제안드립니다:

   "compilerOptions": {
     "outDir": "dist",
+    "rootDir": "src",
     "baseUrl": ".",
     "paths": {
       "@/*": ["./src/*"]
     },
-    "jsx": "react-jsx"
+    "jsx": "react-jsx",
+    "declaration": true
   },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"compilerOptions": {
"outDir": "dist",
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
"jsx": "react-jsx"
},
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
"jsx": "react-jsx",
"declaration": true
},
🤖 Prompt for AI Agents
In packages/design-system/tsconfig.json around lines 3 to 10, the tsconfig only
sets outDir which can cause non-source files (e.g. .storybook) to be emitted and
lacks type declaration output; set "rootDir" to "src" to restrict compiled
inputs, enable "declaration": true and point "declarationDir" (e.g. dist/types)
so .d.ts files are emitted into the package, and add an exclude (or adjust
includes) to prevent non-source files like .storybook or story files from being
compiled into dist.

Comment on lines +5 to +8
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

경로 alias('@/') 사용 시 런타임(번들) 해석 보장 필요

TS의 paths는 타입 체크엔 유효하지만, tsc 단독 빌드의 emit 결과엔 그대로 남습니다. design-system을 소비하는 번들러가 해당 alias를 해석하지 못하면 런타임 모듈 해석 실패가 발생합니다. 현재 앱 쪽은 vite-tsconfig-paths를 사용하지만, 서브패키지(tsconfig)까지 자동 수집되는지 확인이 필요합니다.

아래 스크립트로 alias 사용 현황과 exports 구성을 조회해 영향 범위를 확인해 주세요.


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check alias imports in design-system source =="
rg -nP --glob 'packages/design-system/src/**' -C1 $'from\\s+[\'"]@/|import\\s+@/'

echo
echo "== Show design-system package exports =="
cat packages/design-system/package.json | jq '.name, .exports, .types, .main, .module'

Length of output: 772


경로 alias('@/') 사용 부분 수정 필요

TypeScript paths 매핑은 타입 체크 시에는 유효하지만, tsc 단독 빌드 결과물에는 alias가 그대로 남아 런타임(또는 소비하는 번들러)에서 모듈을 찾지 못할 수 있습니다. 현재 packages/design-system 코드 내에서 alias를 사용 중인 부분을 모두 상대 경로로 변경하거나, 빌드 단계에서 alias를 해석하도록 설정해야 합니다.

수정 대상:

  • packages/design-system/src/components/badge.tsx
    - import { cn } from "@/lib/utils"
    + import { cn } from "../lib/utils"

필요 조치:

  • 위와 같이 codebase 내 alias 사용을 제거하고 상대 경로로 변경
  • 또는 서브패키지 빌드 시 vite-tsconfig-paths(또는 유사 플러그인)가 해당 tsconfig를 자동으로 적용하도록 빌드 설정 검증
  • (선택) package.json의 types, main, module 필드를 올바르게 설정해 소비자 번들러가 정확한 진입점을 참조하도록 보완
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
// File: packages/design-system/src/components/badge.tsx
import { cn } from "../lib/utils"
// (the rest of badge.tsx remains unchanged)
🤖 Prompt for AI Agents
In packages/design-system/tsconfig.json around lines 5 to 8, the paths alias
"@/*" is declared but will remain in emitted JS when using tsc alone, causing
runtime/module resolution failures; update
packages/design-system/src/components/badge.tsx to replace any imports using
"@/..." with correct relative imports (e.g., "../../..." or "../...") or
alternatively ensure the package build config resolves tsconfig paths by
adding/confirming a path resolver plugin (like vite-tsconfig-paths) is applied
during the subpackage build; also verify package.json fields (types, main,
module) point to the correct built files if you choose to keep alias-resolution
in the build pipeline.

Comment on lines +11 to +17
"include": [
"src",
".storybook",
".storybook/*.ts",
"turbo/generators/config.ts"
],
"exclude": ["node_modules", "dist"]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

.storybook가 빌드 산출물에 포함될 수 있습니다 — include/exclude 조정 권장

현재 include에 .storybook 디렉터리가 포함되어 있어 tsc 빌드 시 dist로 방출될 수 있습니다. Storybook은 별도 툴체인이 처리하므로 라이브러리 빌드 대상에서 제외하는 편이 안전합니다.

   "include": [
-    "src",
-    ".storybook",
-    ".storybook/*.ts",
-    "turbo/generators/config.ts"
+    "src",
+    "turbo/generators/config.ts"
   ],
-  "exclude": ["node_modules", "dist"]
+  "exclude": ["node_modules", "dist", ".storybook"]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"include": [
"src",
".storybook",
".storybook/*.ts",
"turbo/generators/config.ts"
],
"exclude": ["node_modules", "dist"]
"include": [
"src",
"turbo/generators/config.ts"
],
"exclude": ["node_modules", "dist", ".storybook"]
🤖 Prompt for AI Agents
In packages/design-system/tsconfig.json around lines 11 to 17, the .storybook
folder is currently listed in "include" which can cause Storybook files to be
compiled into the library output; remove ".storybook" (and any .storybook/*.ts
entries) from "include" and instead add ".storybook" to the "exclude" array (or
restrict "include" to only "src" and necessary build files like
turbo/generators/config.ts) so Storybook assets are not emitted by tsc.

Comment on lines +160 to +162
@theme {
--color-*: initial;

Copy link

@coderabbitai coderabbitai bot Aug 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

@theme 내부의 --color-*: 와일드카드 선언은 잘못된 문법 — 제거 필요

--color-*: initial;은 유효한 CSS 변수명이 아니며 Tailwind v4의 @theme 문법에도 존재하지 않습니다. 이 한 줄 때문에 Biome가 전체 @theme 블록을 오파싱하고 있습니다. 삭제하세요.

적용 패치:

 @theme {
-  --color-*: initial;
 
   /* Main Color */
   --color-main0: #f9fffb;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@theme {
--color-*: initial;
@theme {
/* Main Color */
--color-main0: #f9fffb;
🧰 Tools
🪛 Biome (2.1.2)

[error] 161-161: expected , but instead found *

Remove *

(parse)


[error] 161-161: expected , but instead found ;

Remove ;

(parse)


[error] 161-161: Unexpected unknown pseudo-class initial

See MDN web docs for more details.

(lint/correctness/noUnknownPseudoClass)

🤖 Prompt for AI Agents
packages/tailwind-config/shared-styles.css lines 160-162: remove the invalid CSS
variable wildcard declaration `--color-*: initial;` inside the @theme block;
ensure no other wildcard `--name-*` declarations remain in the @theme, save the
file, and run the project's formatter/linter (and re-run Biome) to confirm the
@theme block parses correctly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

https://tailwindcss.com/docs/theme

여기에 있습니다! 그리고 biome을 쓰지 않고 있어요.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Comment on lines +160 to +229
@theme {
--color-*: initial;

/* Main Color */
--color-main0: #f9fffb;
--color-main100: #c9f2e1;
--color-main200: #99dfc2;
--color-main300: #75d8af;
--color-main400: #54d19d;
--color-main500: #2aa971;
--color-main600: #1f7f55;

/* Gradient */
--color-gradient-start: #cff080;
--color-gradient-end: #33d08f;

/* Secondary Color */
--color-secondary: #f4f2ec;

/* Grayscale */
--color-gray0: #f7f7fb;
--color-gray100: #f1f1f5;
--color-gray200: #e5e5ec;
--color-gray300: #d4d4de;
--color-gray400: #babac7;
--color-gray500: #a2a2ae;
--color-gray600: #848491;
--color-gray700: #5c5c64;
--color-gray800: #404048;
--color-gray900: #28282f;

/* Background */
--color-white-bg: #ffffff;
--color-gray-bg: #fbfbfc;

/* Font Color */
--color-font-black-1: #111111;
--color-font-gray-2: #505050;
--color-font-gray-3: #767676;
--color-font-ltgray-4: #999999;
--color-font-ltgray-5: #dddddd;

/* State */
--color-error: #dc0000;
--color-success: #00c673;

/* Category - Text */
--color-category-red-text: #b63731;
--color-category-purple-text: #612694;
--color-category-navyblue-text: #2a378e;
--color-category-skyblue-text: #3277b8;
--color-category-emerald-text: #38818d;
--color-category-navygreen-text: #2c675c;
--color-category-khaki-text: #62893d;
--color-category-orange-text: #edaa46;
--color-category-amber-text: #df732c;
--color-category-maroon-text: #4a352f;

/* Category - Background */
--color-category-red-bg: #fcecee;
--color-category-purple-bg: #f1e6f4;
--color-category-navyblue-bg: #e8eaf6;
--color-category-skyblue-bg: #e5f5fd;
--color-category-emerald-bg: #e4f6f9;
--color-category-navygreen-bg: #e3f1f1;
--color-category-khaki-bg: #f2f8ea;
--color-category-orange-bg: #fffde9;
--color-category-amber-bg: #fdf3e2;
--color-category-maroon-bg: #eeebe9;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

shadcn/ui 컴포넌트 토큰(Primary/Secondary/Destructive/Accent/Ring 등) 미정의 — 배지 등 컴포넌트 유틸리티가 생성되지 않을 수 있음

Badge 컴포넌트는 bg-primary, text-primary-foreground, bg-secondary, bg-destructive, focus-visible:ring-ring 등 색상 토큰 기반 유틸리티를 사용합니다. 현재 @theme에는 해당 토큰(--color-primary, --color-secondary, --color-destructive, --color-accent, --color-ring, --color-*-foreground)이 정의되어 있지 않습니다. 이 상태에서는 해당 클래스들이 빌드되지/동작하지 않을 가능성이 큽니다.

아래처럼 기존 팔레트에 매핑하여 최소한의 호환 토큰을 추가해 주세요(값은 예시이며 팀 팔레트에 맞춰 조정 가능):

 @theme {
 
   /* Main Color */
   --color-main0: #f9fffb;
@@
   --color-main600: #1f7f55;
 
+  /* shadcn/ui compatibility tokens */
+  --color-primary: var(--color-main500);
+  --color-primary-foreground: #ffffff;
+  --color-secondary: var(--color-gray100);
+  --color-secondary-foreground: var(--color-gray900);
+  --color-accent: var(--color-gray100);
+  --color-accent-foreground: var(--color-gray900);
+  --color-destructive: var(--color-error);
+  --color-destructive-foreground: #ffffff;
+  --color-ring: var(--color-main500);
+  --color-foreground: var(--color-font-black-1);
+  --color-background: var(--color-white-bg);

추가로 shadcn 기본 세트(예: --color-muted, --color-muted-foreground, --color-card, --color-border 등)가 필요해질 수 있으니, 도입 컴포넌트 범위에 맞추어 점진적으로 보완하세요.

필요하시면 현재 도입된 컴포넌트 목록을 기준으로 누락 토큰 체크리스트와 패치까지 만들어 드리겠습니다.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@theme {
--color-*: initial;
/* Main Color */
--color-main0: #f9fffb;
--color-main100: #c9f2e1;
--color-main200: #99dfc2;
--color-main300: #75d8af;
--color-main400: #54d19d;
--color-main500: #2aa971;
--color-main600: #1f7f55;
/* Gradient */
--color-gradient-start: #cff080;
--color-gradient-end: #33d08f;
/* Secondary Color */
--color-secondary: #f4f2ec;
/* Grayscale */
--color-gray0: #f7f7fb;
--color-gray100: #f1f1f5;
--color-gray200: #e5e5ec;
--color-gray300: #d4d4de;
--color-gray400: #babac7;
--color-gray500: #a2a2ae;
--color-gray600: #848491;
--color-gray700: #5c5c64;
--color-gray800: #404048;
--color-gray900: #28282f;
/* Background */
--color-white-bg: #ffffff;
--color-gray-bg: #fbfbfc;
/* Font Color */
--color-font-black-1: #111111;
--color-font-gray-2: #505050;
--color-font-gray-3: #767676;
--color-font-ltgray-4: #999999;
--color-font-ltgray-5: #dddddd;
/* State */
--color-error: #dc0000;
--color-success: #00c673;
/* Category - Text */
--color-category-red-text: #b63731;
--color-category-purple-text: #612694;
--color-category-navyblue-text: #2a378e;
--color-category-skyblue-text: #3277b8;
--color-category-emerald-text: #38818d;
--color-category-navygreen-text: #2c675c;
--color-category-khaki-text: #62893d;
--color-category-orange-text: #edaa46;
--color-category-amber-text: #df732c;
--color-category-maroon-text: #4a352f;
/* Category - Background */
--color-category-red-bg: #fcecee;
--color-category-purple-bg: #f1e6f4;
--color-category-navyblue-bg: #e8eaf6;
--color-category-skyblue-bg: #e5f5fd;
--color-category-emerald-bg: #e4f6f9;
--color-category-navygreen-bg: #e3f1f1;
--color-category-khaki-bg: #f2f8ea;
--color-category-orange-bg: #fffde9;
--color-category-amber-bg: #fdf3e2;
--color-category-maroon-bg: #eeebe9;
}
@theme {
--color-*: initial;
/* Main Color */
--color-main0: #f9fffb;
--color-main100: #c9f2e1;
--color-main200: #99dfc2;
--color-main300: #75d8af;
--color-main400: #54d19d;
--color-main500: #2aa971;
--color-main600: #1f7f55;
/* shadcn/ui compatibility tokens */
--color-primary: var(--color-main500);
--color-primary-foreground: #ffffff;
--color-secondary: var(--color-gray100);
--color-secondary-foreground: var(--color-gray900);
--color-accent: var(--color-gray100);
--color-accent-foreground: var(--color-gray900);
--color-destructive: var(--color-error);
--color-destructive-foreground: #ffffff;
--color-ring: var(--color-main500);
--color-foreground: var(--color-font-black-1);
--color-background: var(--color-white-bg);
/* Gradient */
--color-gradient-start: #cff080;
--color-gradient-end: #33d08f;
/* Secondary Color */
--color-secondary: #f4f2ec;
/* Grayscale */
--color-gray0: #f7f7fb;
--color-gray100: #f1f1f5;
--color-gray200: #e5e5ec;
--color-gray300: #d4d4de;
--color-gray400: #babac7;
--color-gray500: #a2a2ae;
--color-gray600: #848491;
--color-gray700: #5c5c64;
--color-gray800: #404048;
--color-gray900: #28282f;
/* Background */
--color-white-bg: #ffffff;
--color-gray-bg: #fbfbfc;
/* Font Color */
--color-font-black-1: #111111;
--color-font-gray-2: #505050;
--color-font-gray-3: #767676;
--color-font-ltgray-4: #999999;
--color-font-ltgray-5: #dddddd;
/* State */
--color-error: #dc0000;
--color-success: #00c673;
/* Category - Text */
--color-category-red-text: #b63731;
--color-category-purple-text: #612694;
--color-category-navyblue-text: #2a378e;
--color-category-skyblue-text: #3277b8;
--color-category-emerald-text: #38818d;
--color-category-navygreen-text: #2c675c;
--color-category-khaki-text: #62893d;
--color-category-orange-text: #edaa46;
--color-category-amber-text: #df732c;
--color-category-maroon-text: #4a352f;
/* Category - Background */
--color-category-red-bg: #fcecee;
--color-category-purple-bg: #f1e6f4;
--color-category-navyblue-bg: #e8eaf6;
--color-category-skyblue-bg: #e5f5fd;
--color-category-emerald-bg: #e4f6f9;
--color-category-navygreen-bg: #e3f1f1;
--color-category-khaki-bg: #f2f8ea;
--color-category-orange-bg: #fffde9;
--color-category-amber-bg: #fdf3e2;
--color-category-maroon-bg: #eeebe9;
}
🧰 Tools
🪛 Biome (2.1.2)

[error] 161-161: expected , but instead found *

Remove *

(parse)


[error] 161-161: expected , but instead found ;

Remove ;

(parse)


[error] 164-164: expected , but instead found --color-main0

Remove --color-main0

(parse)


[error] 164-164: Unexpected value or character.

Expected one of:

(parse)


[error] 164-164: expected , but instead found ;

Remove ;

(parse)


[error] 165-165: expected , but instead found --color-main100

Remove --color-main100

(parse)


[error] 165-165: Unexpected value or character.

Expected one of:

(parse)


[error] 165-165: expected , but instead found ;

Remove ;

(parse)


[error] 166-166: expected , but instead found --color-main200

Remove --color-main200

(parse)


[error] 166-166: Unexpected value or character.

Expected one of:

(parse)


[error] 166-166: Expected an identifier but instead found '99'.

Expected an identifier here.

(parse)


[error] 166-166: expected , but instead found dfc2

Remove dfc2

(parse)


[error] 166-166: expected , but instead found ;

Remove ;

(parse)


[error] 167-167: expected , but instead found --color-main300

Remove --color-main300

(parse)


[error] 167-167: Unexpected value or character.

Expected one of:

(parse)


[error] 167-167: Expected an identifier but instead found '75'.

Expected an identifier here.

(parse)


[error] 167-167: expected , but instead found d8af

Remove d8af

(parse)


[error] 167-167: expected , but instead found ;

Remove ;

(parse)


[error] 168-168: expected , but instead found --color-main400

Remove --color-main400

(parse)


[error] 168-168: Unexpected value or character.

Expected one of:

(parse)


[error] 168-168: Expected an identifier but instead found '54'.

Expected an identifier here.

(parse)


[error] 168-168: expected , but instead found d19d

Remove d19d

(parse)


[error] 168-168: expected , but instead found ;

Remove ;

(parse)


[error] 169-169: expected , but instead found --color-main500

Remove --color-main500

(parse)


[error] 169-169: Unexpected value or character.

Expected one of:

(parse)


[error] 169-169: Expected an identifier but instead found '2'.

Expected an identifier here.

(parse)


[error] 169-169: expected , but instead found aa971

Remove aa971

(parse)


[error] 169-169: expected , but instead found ;

Remove ;

(parse)


[error] 170-170: expected , but instead found --color-main600

Remove --color-main600

(parse)


[error] 170-170: Unexpected value or character.

Expected one of:

(parse)


[error] 170-170: Expected an identifier but instead found '1'.

Expected an identifier here.

(parse)


[error] 170-170: expected , but instead found f7f55

Remove f7f55

(parse)


[error] 170-170: expected , but instead found ;

Remove ;

(parse)


[error] 173-173: expected , but instead found --color-gradient-start

Remove --color-gradient-start

(parse)


[error] 173-173: Unexpected value or character.

Expected one of:

(parse)


[error] 173-173: expected , but instead found ;

Remove ;

(parse)


[error] 174-174: expected , but instead found --color-gradient-end

Remove --color-gradient-end

(parse)


[error] 174-174: Unexpected value or character.

Expected one of:

(parse)


[error] 174-174: Expected an identifier but instead found '33'.

Expected an identifier here.

(parse)


[error] 174-174: expected , but instead found d08f

Remove d08f

(parse)


[error] 174-174: expected , but instead found ;

Remove ;

(parse)


[error] 177-177: expected , but instead found --color-secondary

Remove --color-secondary

(parse)


[error] 177-177: Unexpected value or character.

Expected one of:

(parse)


[error] 177-177: expected , but instead found ;

Remove ;

(parse)


[error] 180-180: expected , but instead found --color-gray0

Remove --color-gray0

(parse)


[error] 180-180: Unexpected value or character.

Expected one of:

(parse)


[error] 180-180: expected , but instead found ;

Remove ;

(parse)


[error] 181-181: expected , but instead found --color-gray100

Remove --color-gray100

(parse)


[error] 181-181: Unexpected value or character.

Expected one of:

(parse)


[error] 181-181: expected , but instead found ;

Remove ;

(parse)


[error] 182-182: expected , but instead found --color-gray200

Remove --color-gray200

(parse)


[error] 182-182: Unexpected value or character.

Expected one of:

(parse)


[error] 182-182: expected , but instead found ;

Remove ;

(parse)


[error] 183-183: expected , but instead found --color-gray300

Remove --color-gray300

(parse)


[error] 183-183: Unexpected value or character.

Expected one of:

(parse)


[error] 183-183: expected , but instead found ;

Remove ;

(parse)


[error] 184-184: expected , but instead found --color-gray400

Remove --color-gray400

(parse)


[error] 184-184: Unexpected value or character.

Expected one of:

(parse)


[error] 184-184: expected , but instead found ;

Remove ;

(parse)


[error] 185-185: expected , but instead found --color-gray500

Remove --color-gray500

(parse)


[error] 185-185: Unexpected value or character.

Expected one of:

(parse)


[error] 185-185: expected , but instead found ;

Remove ;

(parse)


[error] 186-186: expected , but instead found --color-gray600

Remove --color-gray600

(parse)


[error] 186-186: Unexpected value or character.

Expected one of:

(parse)


[error] 186-186: Expected an identifier but instead found '848491'.

Expected an identifier here.

(parse)


[error] 187-187: expected , but instead found --color-gray700

Remove --color-gray700

(parse)


[error] 187-187: Unexpected value or character.

Expected one of:

(parse)


[error] 187-187: Expected an identifier but instead found '5'.

Expected an identifier here.

(parse)


[error] 187-187: expected , but instead found c5c64

Remove c5c64

(parse)


[error] 187-187: expected , but instead found ;

Remove ;

(parse)


[error] 188-188: expected , but instead found --color-gray800

Remove --color-gray800

(parse)


[error] 188-188: Unexpected value or character.

Expected one of:

(parse)


[error] 188-188: Expected an identifier but instead found '404048'.

Expected an identifier here.

(parse)


[error] 189-189: expected , but instead found --color-gray900

Remove --color-gray900

(parse)


[error] 189-189: Unexpected value or character.

Expected one of:

(parse)


[error] 189-189: Expected an identifier but instead found '28282'.

Expected an identifier here.

(parse)


[error] 189-189: expected , but instead found f

Remove f

(parse)


[error] 189-189: expected , but instead found ;

Remove ;

(parse)


[error] 192-192: expected , but instead found --color-white-bg

Remove --color-white-bg

(parse)


[error] 192-192: Unexpected value or character.

Expected one of:

(parse)


[error] 192-192: expected , but instead found ;

Remove ;

(parse)


[error] 193-193: expected , but instead found --color-gray-bg

Remove --color-gray-bg

(parse)


[error] 193-193: Unexpected value or character.

Expected one of:

(parse)


[error] 193-193: expected , but instead found ;

Remove ;

(parse)


[error] 196-196: expected , but instead found --color-font-black-1

Remove --color-font-black-1

(parse)


[error] 196-196: Unexpected value or character.

Expected one of:

(parse)


[error] 196-196: Expected an identifier but instead found '111111'.

Expected an identifier here.

(parse)


[error] 197-197: expected , but instead found --color-font-gray-2

Remove --color-font-gray-2

(parse)


[error] 197-197: Unexpected value or character.

Expected one of:

(parse)


[error] 197-197: Expected an identifier but instead found '505050'.

Expected an identifier here.

(parse)


[error] 198-198: expected , but instead found --color-font-gray-3

Remove --color-font-gray-3

(parse)


[error] 198-198: Unexpected value or character.

Expected one of:

(parse)


[error] 198-198: Expected an identifier but instead found '767676'.

Expected an identifier here.

(parse)


[error] 199-199: expected , but instead found --color-font-ltgray-4

Remove --color-font-ltgray-4

(parse)


[error] 199-199: Unexpected value or character.

Expected one of:

(parse)


[error] 199-199: Expected an identifier but instead found '999999'.

Expected an identifier here.

(parse)


[error] 200-200: expected , but instead found --color-font-ltgray-5

Remove --color-font-ltgray-5

(parse)


[error] 200-200: Unexpected value or character.

Expected one of:

(parse)


[error] 200-200: expected , but instead found ;

Remove ;

(parse)


[error] 203-203: expected , but instead found --color-error

Remove --color-error

(parse)


[error] 203-203: Unexpected value or character.

Expected one of:

(parse)


[error] 203-203: expected , but instead found ;

Remove ;

(parse)


[error] 204-204: expected , but instead found --color-success

Remove --color-success

(parse)


[error] 204-204: Unexpected value or character.

Expected one of:

(parse)


[error] 204-204: Expected an identifier but instead found '00'.

Expected an identifier here.

(parse)


[error] 204-204: expected , but instead found c673

Remove c673

(parse)


[error] 204-204: expected , but instead found ;

Remove ;

(parse)


[error] 207-207: expected , but instead found --color-category-red-text

Remove --color-category-red-text

(parse)


[error] 207-207: Unexpected value or character.

Expected one of:

(parse)


[error] 207-207: expected , but instead found ;

Remove ;

(parse)


[error] 208-208: expected , but instead found --color-category-purple-text

Remove --color-category-purple-text

(parse)


[error] 208-208: Unexpected value or character.

Expected one of:

(parse)


[error] 208-208: Expected an identifier but instead found '612694'.

Expected an identifier here.

(parse)


[error] 209-209: expected , but instead found --color-category-navyblue-text

Remove --color-category-navyblue-text

(parse)


[error] 209-209: Unexpected value or character.

Expected one of:

(parse)


[error] 209-209: Expected an identifier but instead found '2'.

Expected an identifier here.

(parse)


[error] 209-209: expected , but instead found a378e

Remove a378e

(parse)


[error] 209-209: expected , but instead found ;

Remove ;

(parse)


[error] 210-210: expected , but instead found --color-category-skyblue-text

Remove --color-category-skyblue-text

(parse)


[error] 210-210: Unexpected value or character.

Expected one of:

(parse)


[error] 210-210: Expected an identifier but instead found '3277'.

Expected an identifier here.

(parse)


[error] 210-210: expected , but instead found b8

Remove b8

(parse)


[error] 210-210: expected , but instead found ;

Remove ;

(parse)


[error] 211-211: expected , but instead found --color-category-emerald-text

Remove --color-category-emerald-text

(parse)


[error] 211-211: Unexpected value or character.

Expected one of:

(parse)


[error] 211-211: Expected an identifier but instead found '38818'.

Expected an identifier here.

(parse)


[error] 211-211: expected , but instead found d

Remove d

(parse)


[error] 211-211: expected , but instead found ;

Remove ;

(parse)


[error] 212-212: expected , but instead found --color-category-navygreen-text

Remove --color-category-navygreen-text

(parse)


[error] 212-212: Unexpected value or character.

Expected one of:

(parse)


[error] 212-212: Expected an identifier but instead found '2'.

Expected an identifier here.

(parse)


[error] 212-212: expected , but instead found c675c

Remove c675c

(parse)


[error] 212-212: expected , but instead found ;

Remove ;

(parse)


[error] 213-213: expected , but instead found --color-category-khaki-text

Remove --color-category-khaki-text

(parse)


[error] 213-213: Unexpected value or character.

Expected one of:

(parse)


[error] 213-213: Expected an identifier but instead found '62893'.

Expected an identifier here.

(parse)


[error] 213-213: expected , but instead found d

Remove d

(parse)


[error] 213-213: expected , but instead found ;

Remove ;

(parse)


[error] 214-214: expected , but instead found --color-category-orange-text

Remove --color-category-orange-text

(parse)


[error] 214-214: Unexpected value or character.

Expected one of:

(parse)


[error] 214-214: expected , but instead found ;

Remove ;

(parse)


[error] 215-215: expected , but instead found --color-category-amber-text

Remove --color-category-amber-text

(parse)


[error] 215-215: Unexpected value or character.

Expected one of:

(parse)


[error] 215-215: expected , but instead found ;

Remove ;

(parse)


[error] 216-216: expected , but instead found --color-category-maroon-text

Remove --color-category-maroon-text

(parse)


[error] 216-216: Unexpected value or character.

Expected one of:

(parse)


[error] 216-216: Expected an identifier but instead found '4'.

Expected an identifier here.

(parse)


[error] 216-216: expected , but instead found a352f

Remove a352f

(parse)


[error] 216-216: expected , but instead found ;

Remove ;

(parse)


[error] 219-219: expected , but instead found --color-category-red-bg

Remove --color-category-red-bg

(parse)


[error] 219-219: Unexpected value or character.

Expected one of:

(parse)


[error] 219-219: expected , but instead found ;

Remove ;

(parse)


[error] 220-220: expected , but instead found --color-category-purple-bg

Remove --color-category-purple-bg

(parse)


[error] 220-220: Unexpected value or character.

Expected one of:

(parse)


[error] 220-220: expected , but instead found ;

Remove ;

(parse)


[error] 221-221: expected , but instead found --color-category-navyblue-bg

Remove --color-category-navyblue-bg

(parse)


[error] 221-221: Unexpected value or character.

Expected one of:

(parse)


[error] 221-221: expected , but instead found ;

Remove ;

(parse)


[error] 222-222: expected , but instead found --color-category-skyblue-bg

Remove --color-category-skyblue-bg

(parse)


[error] 222-222: Unexpected value or character.

Expected one of:

(parse)


[error] 222-222: expected , but instead found ;

Remove ;

(parse)


[error] 223-223: expected , but instead found --color-category-emerald-bg

Remove --color-category-emerald-bg

(parse)


[error] 223-223: Unexpected value or character.

Expected one of:

(parse)


[error] 223-223: expected , but instead found ;

Remove ;

(parse)


[error] 224-224: expected , but instead found --color-category-navygreen-bg

Remove --color-category-navygreen-bg

(parse)


[error] 224-224: Unexpected value or character.

Expected one of:

(parse)


[error] 224-224: expected , but instead found ;

Remove ;

(parse)


[error] 225-225: expected , but instead found --color-category-khaki-bg

Remove --color-category-khaki-bg

(parse)


[error] 225-225: Unexpected value or character.

Expected one of:

(parse)


[error] 225-225: expected , but instead found ;

Remove ;

(parse)


[error] 226-226: expected , but instead found --color-category-orange-bg

Remove --color-category-orange-bg

(parse)


[error] 226-226: Unexpected value or character.

Expected one of:

(parse)


[error] 226-226: expected , but instead found ;

Remove ;

(parse)


[error] 227-227: expected , but instead found --color-category-amber-bg

Remove --color-category-amber-bg

(parse)


[error] 227-227: Unexpected value or character.

Expected one of:

(parse)


[error] 227-227: expected , but instead found ;

Remove ;

(parse)


[error] 228-228: expected , but instead found --color-category-maroon-bg

Remove --color-category-maroon-bg

(parse)


[error] 228-228: Unexpected value or character.

Expected one of:

(parse)


[error] 228-228: expected , but instead found ;

Remove ;

(parse)


[error] 161-161: Unexpected unknown pseudo-class initial

See MDN web docs for more details.

(lint/correctness/noUnknownPseudoClass)


[error] 166-166: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 167-167: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 168-168: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 169-169: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 170-170: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 174-174: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 187-187: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 189-189: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 204-204: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 209-209: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 210-210: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 211-211: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 212-212: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 213-213: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 216-216: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)

🤖 Prompt for AI Agents
In packages/tailwind-config/shared-styles.css around lines 160 to 229, shadcn/ui
color token names (e.g. --color-primary, --color-primary-foreground,
--color-destructive, --color-accent, --color-ring and related foreground tokens,
plus common tokens like --color-muted, --color-muted-foreground, --color-card,
--color-border) are missing which prevents utility classes like bg-primary or
focus-visible:ring-ring from being generated; add a minimal compatibility set by
mapping these shadcn token names to existing palette variables (for example set
--color-primary to an appropriate --color-main500, --color-primary-foreground to
--color-white-bg or --color-font-black-1 depending on contrast, set
--color-secondary if needed to existing --color-secondary, set
--color-destructive to --color-error with a matching destructive-foreground, set
--color-accent to a suitable gradient/end color or main400, set --color-ring to
a high-contrast variant like --color-main200, and add --color-muted,
--color-muted-foreground, --color-card, --color-border mapped to appropriate
--color-gray* and bg tokens); adjust values to match brand palette and expand
token list later as more components are used.

Copy link
Collaborator

@jllee000 jllee000 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인했습니다!
cva는 저번에 사용해봤을 때도 확실히 좋았어서, 많이 활용할 것 같습니다!

얘기해주신 고민 포인트에 대해서 보면 확실히 v4에선 토큰 느낌이 안나네요...아니면 유틸리티 내에서 토큰만 꺼내는 식으로 써보는게 그나마 토큰화 느낌이 날지..? 방법 같이 찾아보겠습니다
(2안 헬퍼함수는 따로 만드는게 좀더 돌아간다는 거 같다는느낌도..)

Comment on lines +2 to +11

/* Head */
@utility head1 {
font-weight: 700;
font-size: 4rem;
line-height: 140%;
letter-spacing: -0.02em;
}
@utility head2 {
font-weight: 700;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://velog.io/@crg1050/tailwind-v4%EC%97%90-%EB%8C%80%ED%95%B4
값은 전부 @theme 토큰으로 끌어올리고, 유틸리티는 토큰만 참조해서 이후에 수정할때도 토큰만 수정하면 되는식으로,,

즉 “역할형” 유틸리티 (값 대신 토큰만 참조) 로 선언하는 방식이 pr에 올려주신 고민 포인트 해결과는 상관 없을까요.!!?

@utility ui-h1 {
  font-size: var(--text-head1-size);
  font-weight: var(--text-head1-weight);
  line-height: var(--text-head1-leading);
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 하면 token의 관점에서 더 가까운 코드가 될 수 있을 것 같네요! 좋은 의견 감사합니다 👍
다만 이 부분을 어떻게 분리할지 조금 더 고민이 필요할 것 같아서 팀원분들과 상의 후에 결정 및 반영해도 좋을 것 같아요!

Copy link
Collaborator

@jjangminii jjangminii left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저번 shadcn/ui와 cva 유용하게 사용해서 이번에도 유용하게 사용할 수 있을 것같습니다-! 테일윈드는 확실히 버전에 따라 다른점이 있어 복잡하네요.. 공부를 좀 더 하고 토큰에 대해서 고민해봐여할 문제라고 생각이듭니다..

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/design-system/styles.css (1)

1-1: 앱 CSS import 정리: design-system/styles만 사용

  • @pinback/tailwind-config의 package.json exports에 shared-styles.css가 올바르게 노출되어 있습니다.
  • shared-styles.css에 Tailwind v4 엔트리(@import 'tailwindcss';)가 포함되어 있습니다.
  • @pinback/design-system의 package.json exports에도 ./styles: ./styles.css 엔트리가 노출되어 있습니다.
  • 그러나 현재 apps/client 및 apps/landing에서는 @pinback/tailwind-config/shared-styles.css를 직접 import하고 있어 CSS가 중복 로드될 수 있습니다.

→ 각 앱에서 아래처럼 @pinback/design-system/styles 하나만 import 하도록 변경해 주세요.

packages/design-system/src/components/button/temp.tsx (1)

3-7: 컴포넌트 네이밍 PascalCase 및 불필요한 className 제거

React 컴포넌트는 PascalCase가 관례이며, 빈 className은 제거하는 것이 깔끔합니다. 아래처럼 최소 수정 권장합니다.

-const temp = () => {
-  return (
-    <div className=''>temp</div>
-  )
-}
+const Temp = () => {
+  return <div>temp</div>
+}

-export default temp
+export default Temp
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled
  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ca7ce44 and 3867488.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • packages/design-system/package.json (1 hunks)
  • packages/design-system/src/components/button/temp.tsx (1 hunks)
  • packages/design-system/styles.css (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/design-system/package.json
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#2
File: pnpm-workspace.yaml:3-3
Timestamp: 2025-08-18T13:48:59.021Z
Learning: constantly-dev는 docs 디렉터리를 컨벤션 문서 추가용으로 사용할 예정이라고 명시했습니다.
📚 Learning: 2025-07-04T10:12:01.690Z
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#10
File: apps/landing/src/index.css:1-1
Timestamp: 2025-07-04T10:12:01.690Z
Learning: In TailwindCSS v4, the import "tailwindcss"; syntax is the new recommended approach that replaces the three separate tailwind directives (tailwind base;, tailwind components;, tailwind utilities;). This single import pulls in all of Tailwind's preflight, components, and utilities in one step and is used with the tailwindcss/vite plugin.

Applied to files:

  • packages/design-system/styles.css
📚 Learning: 2025-07-04T10:12:01.690Z
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#10
File: apps/landing/src/index.css:1-1
Timestamp: 2025-07-04T10:12:01.690Z
Learning: In TailwindCSS v4, the import "tailwindcss"; syntax is the new recommended approach that replaces the three separate tailwind directives (tailwind base;, tailwind components;, tailwind utilities;). This is used with the tailwindcss/vite plugin.

Applied to files:

  • packages/design-system/styles.css
🔇 Additional comments (2)
packages/design-system/styles.css (1)

1-1: 디자인 시스템 스타일 엔트리 포워딩 설계 적절

공유 토큰을 tailwind-config로 집결시키고, DS 엔트리에서 얇게 포워딩하는 구조는 v4 환경에서 유지보수와 중복 제어에 유리합니다.

packages/design-system/src/components/button/temp.tsx (1)

1-1: React 자동 JSX 런타임 사용 중이므로 import React 생략 가능

packages/design-system/tsconfig.json에서 "jsx": "react-jsx" 설정이 확인되어,
packages/design-system/src/components/button/temp.tsx 파일 상단의 import React from 'react'를 제거해도 안전합니다.

  • packages/design-system/src/components/button/temp.tsx:1행
- import React from 'react'

Comment on lines 1 to 9
import React from 'react'

const temp = () => {
return (
<div className=''>temp</div>
)
}

export default temp No newline at end of file
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

임시(temp) 컴포넌트 커밋 여부 확인 및 정리 권장

button 디렉터리 하위에 temp.tsx는 스캐폴딩 잔재로 보입니다. 병합 전 다음 중 하나를 권장합니다:

  • 실제 Button 컴포넌트(shadcn add button)로 교체하거나
  • 파일을 제거해 패키지 퍼블릭 API에 노이즈가 생기지 않도록 정리

shadcn 워크플로에 맞춘 컴포넌트 파일명(button.tsx)과 내보내기 형태(가능하면 named export)를 일관화하면 DX가 좋아집니다. 필요하시면 제가 shadcn 스타일의 Button 초안까지 생성해 드릴게요.

레포 내에서 이 파일이 실제로 사용/내보내기 되는지 점검하려면 아래 스크립트를 실행해 주세요.


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "1) temp.tsx 참조 여부(임포트/경로) 검색"
rg -nP 'components/button/temp' -C2 || true

echo
echo "2) design-system exports 확인(공용 API에 노출되는지 여부)"
if [ -f packages/design-system/package.json ]; then
  jq '{name, exports}' packages/design-system/package.json
else
  echo "packages/design-system/package.json not found"
fi

Length of output: 553


불필요한 temp.tsx 파일 정리 필요

해당 파일은 코드베이스 어디에서도 임포트되지 않으며,
packages/design-system/package.jsonexports에도 포함되어 있지 않습니다.
패키지 퍼블릭 API의 노이즈를 줄이기 위해 다음 중 하나를 진행해주세요:

  • temp.tsx 파일 제거
  • 실제 Button 컴포넌트로 교체
    • 파일명: button.tsx
    • 가능하면 named export 형태로 일관화

필요하시면 shadcn 스타일의 Button 초안 생성을 도와드릴 수 있습니다.

🤖 Prompt for AI Agents
packages/design-system/src/components/button/temp.tsx lines 1-9: temp.tsx is
unused and should be removed or replaced; either delete this file and remove any
reference in the package (and ensure package.json exports remain correct), or
rename/replace it with a real Button component at
packages/design-system/src/components/button/button.tsx using a named export
(export const Button = ...) and update packages/design-system/package.json
exports to expose the new file if it should be public.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
packages/tailwind-config/shared-styles.css (1)

160-229: shadcn/ui 호환 색상 토큰 누락 — 최소 호환 세트 추가 권장

shadcn/ui 기본 컴포넌트는 bg-primary, text-primary-foreground, focus-visible:ring-ring 등 토큰 기반 유틸이 필요합니다. 현재 @theme--color-primary, --color-ring 등 호환 토큰이 없어, 생성/동작 이슈가 발생할 수 있습니다. 본 PR의 목적(디자인 시스템 + shadcn 통합)에 직결되므로, 아래 최소 세트를 매핑해 두는 것을 권장합니다.

아래 패치를 @theme 블록에 추가하세요(값은 팔레트 대비/접근성에 맞게 조정 가능):

 @theme {
   --color-*: initial;

   /* Main Color */
   --color-main0: #f9fffb;
@@
   --color-main600: #1f7f55;

+  /* shadcn/ui compatibility tokens */
+  --color-background: var(--color-white-bg);
+  --color-foreground: var(--color-font-black-1);
+
+  --color-primary: var(--color-main500);
+  --color-primary-foreground: #ffffff;
+  --color-secondary: var(--color-gray100);
+  --color-secondary-foreground: var(--color-gray900);
+  --color-accent: var(--color-gray100);
+  --color-accent-foreground: var(--color-gray900);
+  --color-destructive: var(--color-error);
+  --color-destructive-foreground: #ffffff;
+  --color-ring: var(--color-main500);
+
+  /* Common UI surface tokens used by several components */
+  --color-muted: var(--color-gray100);
+  --color-muted-foreground: var(--color-gray600);
+  --color-card: var(--color-white-bg);
+  --color-border: var(--color-gray200);
+  --color-input: var(--color-gray200);
+  --color-popover: var(--color-white-bg);
+
+  /* Typography tokens (예시: head1만 — 나머지는 동일 패턴으로 확장) */
+  --text-head1-weight: 700;
+  --text-head1-size: 4rem;
+  --text-head1-leading: 140%;
+  --text-head1-tracking: -0.02em;
+
+  /* Shadow token */
+  --shadow-common: 0 0 32px rgba(0, 0, 0, 0.1);

추가로, 도입 예정 컴포넌트(Button, Badge, Input, Dialog 등)에 따라 --color-muted, --color-popover-foreground, --color-card-foreground 등도 점진적으로 확장해 주세요. 필요 시 컴포넌트 리스트 기반 체크리스트 만들어 드리겠습니다.

🧹 Nitpick comments (5)
packages/tailwind-config/shared-styles.css (5)

4-39: 타이포 유틸을 역할형(토큰 참조)으로 전환 제안

현재는 고정값(예: 4rem, 140%)이 하드코딩되어 있어 스케일 조정 시 유틸 전반 수정이 필요합니다. @theme에 타이포 토큰을 두고 유틸은 var(...)만 참조하도록 바꾸면 유지보수성이 크게 좋아집니다. 팀 코멘트(jllee000) 방향과도 일치합니다.

예시(패턴만 제시 — head1만 변경, 동일 패턴을 head2~head6에 확장):

 @utility head1 {
-  font-weight: 700;
-  font-size: 4rem;
-  line-height: 140%;
-  letter-spacing: -0.02em;
+  font-weight: var(--text-head1-weight);
+  font-size: var(--text-head1-size);
+  line-height: var(--text-head1-leading);
+  letter-spacing: var(--text-head1-tracking);
 }

@theme에 대응 토큰 추가(별도 코멘트의 @theme 블록 패치에 함께 포함해드렸습니다).


155-158: common-shadow도 토큰화하면 재사용/브랜드 단계별 조정이 쉬워집니다

박스섀도를 공통 토큰으로 끌어올리면 다크모드/밀도 단계 조정이 수월합니다.

 @utility common-shadow {
-  box-shadow: 0px 0px 32px 0px rgba(0, 0, 0, 0.1);
+  box-shadow: var(--shadow-common);
 }

@theme 추가(아래 @theme 코멘트에 함께 제시):

--shadow-common: 0 0 32px rgba(0,0,0,.1);

160-162: --color-*: 와일드카드 선언은 Tailwind v4 전용 문법 — 빌드 체인 확인 권장

Tailwind v4의 @theme 문법에서만 의미가 있고, 일반 CSS 파서/일부 린터(Biome 등)에서는 오류로 보일 수 있습니다. 현재 레포가 v4 파이프라인(예: tailwindcss/vite 플러그인)으로만 이 파일을 처리하는지 한 번만 확인 부탁드립니다.


231-236: html 62.5% 루트 폰트 크기 설정 — 교차 앱 일관성만 확인

모노레포 모든 앱이 이 공유 CSS만 통해 루트 폰트 사이즈를 세팅한다면 OK입니다. 개별 앱 CSS에서 중복 설정이 있다면 하나로 통일하는 것을 권장합니다.


238-240: 빈 components 레이어 — 공통 포커스 링/스크롤바 등 프리미티브를 여기에 두면 좋습니다

예: focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring 같은 접근성 기본값을 컴포넌트 프리미티브로 제공 가능.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled
  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3867488 and f0bba48.

📒 Files selected for processing (1)
  • packages/tailwind-config/shared-styles.css (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#5
File: apps/extension/src/index.css:1-1
Timestamp: 2025-08-19T17:18:57.657Z
Learning: constantly-dev는 디자인 시스템 설정 PR 머지 후 `import 'pinback/tailwind-config/shared-styles.css';`를 `app.css`나 `index.css`에서 사용하여 공유 스타일을 관리할 계획입니다.
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#2
File: pnpm-workspace.yaml:3-3
Timestamp: 2025-08-18T13:48:59.021Z
Learning: constantly-dev는 docs 디렉터리를 컨벤션 문서 추가용으로 사용할 예정이라고 명시했습니다.
📚 Learning: 2025-08-19T17:18:57.657Z
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#5
File: apps/extension/src/index.css:1-1
Timestamp: 2025-08-19T17:18:57.657Z
Learning: constantly-dev는 디자인 시스템 설정 PR 머지 후 `import 'pinback/tailwind-config/shared-styles.css';`를 `app.css`나 `index.css`에서 사용하여 공유 스타일을 관리할 계획입니다.

Applied to files:

  • packages/tailwind-config/shared-styles.css
📚 Learning: 2025-07-04T10:12:01.690Z
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#10
File: apps/landing/src/index.css:1-1
Timestamp: 2025-07-04T10:12:01.690Z
Learning: In TailwindCSS v4, the import "tailwindcss"; syntax is the new recommended approach that replaces the three separate tailwind directives (tailwind base;, tailwind components;, tailwind utilities;). This single import pulls in all of Tailwind's preflight, components, and utilities in one step and is used with the tailwindcss/vite plugin.

Applied to files:

  • packages/tailwind-config/shared-styles.css
📚 Learning: 2025-07-04T10:12:01.690Z
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#10
File: apps/landing/src/index.css:1-1
Timestamp: 2025-07-04T10:12:01.690Z
Learning: In TailwindCSS v4, the import "tailwindcss"; syntax is the new recommended approach that replaces the three separate tailwind directives (tailwind base;, tailwind components;, tailwind utilities;). This is used with the tailwindcss/vite plugin.

Applied to files:

  • packages/tailwind-config/shared-styles.css
📚 Learning: 2025-07-16T13:11:52.976Z
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#89
File: apps/client/src/pages/onBoarding/components/OnboardingNavButton.tsx:26-34
Timestamp: 2025-07-16T13:11:52.976Z
Learning: In the Pinback-Team/pinback-client project, `bg-gray200` is a custom design token used consistently throughout the design system, not a typo. The project uses custom color tokens like `gray0`, `gray100`, `gray200`, `gray300`, etc. without hyphens, which is different from standard Tailwind CSS naming conventions. This should not be changed to `bg-gray-200` as it would break the design system.

Applied to files:

  • packages/tailwind-config/shared-styles.css
🪛 Biome (2.1.2)
packages/tailwind-config/shared-styles.css

[error] 161-161: expected , but instead found *

Remove *

(parse)


[error] 161-161: expected , but instead found ;

Remove ;

(parse)


[error] 164-164: expected , but instead found --color-main0

Remove --color-main0

(parse)


[error] 164-164: Unexpected value or character.

Expected one of:

(parse)


[error] 164-164: expected , but instead found ;

Remove ;

(parse)


[error] 165-165: expected , but instead found --color-main100

Remove --color-main100

(parse)


[error] 165-165: Unexpected value or character.

Expected one of:

(parse)


[error] 165-165: expected , but instead found ;

Remove ;

(parse)


[error] 166-166: expected , but instead found --color-main200

Remove --color-main200

(parse)


[error] 166-166: Unexpected value or character.

Expected one of:

(parse)


[error] 166-166: Expected an identifier but instead found '99'.

Expected an identifier here.

(parse)


[error] 166-166: expected , but instead found dfc2

Remove dfc2

(parse)


[error] 166-166: expected , but instead found ;

Remove ;

(parse)


[error] 167-167: expected , but instead found --color-main300

Remove --color-main300

(parse)


[error] 167-167: Unexpected value or character.

Expected one of:

(parse)


[error] 167-167: Expected an identifier but instead found '75'.

Expected an identifier here.

(parse)


[error] 167-167: expected , but instead found d8af

Remove d8af

(parse)


[error] 167-167: expected , but instead found ;

Remove ;

(parse)


[error] 168-168: expected , but instead found --color-main400

Remove --color-main400

(parse)


[error] 168-168: Unexpected value or character.

Expected one of:

(parse)


[error] 168-168: Expected an identifier but instead found '54'.

Expected an identifier here.

(parse)


[error] 168-168: expected , but instead found d19d

Remove d19d

(parse)


[error] 168-168: expected , but instead found ;

Remove ;

(parse)


[error] 169-169: expected , but instead found --color-main500

Remove --color-main500

(parse)


[error] 169-169: Unexpected value or character.

Expected one of:

(parse)


[error] 169-169: Expected an identifier but instead found '2'.

Expected an identifier here.

(parse)


[error] 169-169: expected , but instead found aa971

Remove aa971

(parse)


[error] 169-169: expected , but instead found ;

Remove ;

(parse)


[error] 170-170: expected , but instead found --color-main600

Remove --color-main600

(parse)


[error] 170-170: Unexpected value or character.

Expected one of:

(parse)


[error] 170-170: Expected an identifier but instead found '1'.

Expected an identifier here.

(parse)


[error] 170-170: expected , but instead found f7f55

Remove f7f55

(parse)


[error] 170-170: expected , but instead found ;

Remove ;

(parse)


[error] 173-173: expected , but instead found --color-gradient-start

Remove --color-gradient-start

(parse)


[error] 173-173: Unexpected value or character.

Expected one of:

(parse)


[error] 173-173: expected , but instead found ;

Remove ;

(parse)


[error] 174-174: expected , but instead found --color-gradient-end

Remove --color-gradient-end

(parse)


[error] 174-174: Unexpected value or character.

Expected one of:

(parse)


[error] 174-174: Expected an identifier but instead found '33'.

Expected an identifier here.

(parse)


[error] 174-174: expected , but instead found d08f

Remove d08f

(parse)


[error] 174-174: expected , but instead found ;

Remove ;

(parse)


[error] 177-177: expected , but instead found --color-secondary

Remove --color-secondary

(parse)


[error] 177-177: Unexpected value or character.

Expected one of:

(parse)


[error] 177-177: expected , but instead found ;

Remove ;

(parse)


[error] 180-180: expected , but instead found --color-gray0

Remove --color-gray0

(parse)


[error] 180-180: Unexpected value or character.

Expected one of:

(parse)


[error] 180-180: expected , but instead found ;

Remove ;

(parse)


[error] 181-181: expected , but instead found --color-gray100

Remove --color-gray100

(parse)


[error] 181-181: Unexpected value or character.

Expected one of:

(parse)


[error] 181-181: expected , but instead found ;

Remove ;

(parse)


[error] 182-182: expected , but instead found --color-gray200

Remove --color-gray200

(parse)


[error] 182-182: Unexpected value or character.

Expected one of:

(parse)


[error] 182-182: expected , but instead found ;

Remove ;

(parse)


[error] 183-183: expected , but instead found --color-gray300

Remove --color-gray300

(parse)


[error] 183-183: Unexpected value or character.

Expected one of:

(parse)


[error] 183-183: expected , but instead found ;

Remove ;

(parse)


[error] 184-184: expected , but instead found --color-gray400

Remove --color-gray400

(parse)


[error] 184-184: Unexpected value or character.

Expected one of:

(parse)


[error] 184-184: expected , but instead found ;

Remove ;

(parse)


[error] 185-185: expected , but instead found --color-gray500

Remove --color-gray500

(parse)


[error] 185-185: Unexpected value or character.

Expected one of:

(parse)


[error] 185-185: expected , but instead found ;

Remove ;

(parse)


[error] 186-186: expected , but instead found --color-gray600

Remove --color-gray600

(parse)


[error] 186-186: Unexpected value or character.

Expected one of:

(parse)


[error] 186-186: Expected an identifier but instead found '848491'.

Expected an identifier here.

(parse)


[error] 187-187: expected , but instead found --color-gray700

Remove --color-gray700

(parse)


[error] 187-187: Unexpected value or character.

Expected one of:

(parse)


[error] 187-187: Expected an identifier but instead found '5'.

Expected an identifier here.

(parse)


[error] 187-187: expected , but instead found c5c64

Remove c5c64

(parse)


[error] 187-187: expected , but instead found ;

Remove ;

(parse)


[error] 188-188: expected , but instead found --color-gray800

Remove --color-gray800

(parse)


[error] 188-188: Unexpected value or character.

Expected one of:

(parse)


[error] 188-188: Expected an identifier but instead found '404048'.

Expected an identifier here.

(parse)


[error] 189-189: expected , but instead found --color-gray900

Remove --color-gray900

(parse)


[error] 189-189: Unexpected value or character.

Expected one of:

(parse)


[error] 189-189: Expected an identifier but instead found '28282'.

Expected an identifier here.

(parse)


[error] 189-189: expected , but instead found f

Remove f

(parse)


[error] 189-189: expected , but instead found ;

Remove ;

(parse)


[error] 192-192: expected , but instead found --color-white-bg

Remove --color-white-bg

(parse)


[error] 192-192: Unexpected value or character.

Expected one of:

(parse)


[error] 192-192: expected , but instead found ;

Remove ;

(parse)


[error] 193-193: expected , but instead found --color-gray-bg

Remove --color-gray-bg

(parse)


[error] 193-193: Unexpected value or character.

Expected one of:

(parse)


[error] 193-193: expected , but instead found ;

Remove ;

(parse)


[error] 196-196: expected , but instead found --color-font-black-1

Remove --color-font-black-1

(parse)


[error] 196-196: Unexpected value or character.

Expected one of:

(parse)


[error] 196-196: Expected an identifier but instead found '111111'.

Expected an identifier here.

(parse)


[error] 197-197: expected , but instead found --color-font-gray-2

Remove --color-font-gray-2

(parse)


[error] 197-197: Unexpected value or character.

Expected one of:

(parse)


[error] 197-197: Expected an identifier but instead found '505050'.

Expected an identifier here.

(parse)


[error] 198-198: expected , but instead found --color-font-gray-3

Remove --color-font-gray-3

(parse)


[error] 198-198: Unexpected value or character.

Expected one of:

(parse)


[error] 198-198: Expected an identifier but instead found '767676'.

Expected an identifier here.

(parse)


[error] 199-199: expected , but instead found --color-font-ltgray-4

Remove --color-font-ltgray-4

(parse)


[error] 199-199: Unexpected value or character.

Expected one of:

(parse)


[error] 199-199: Expected an identifier but instead found '999999'.

Expected an identifier here.

(parse)


[error] 200-200: expected , but instead found --color-font-ltgray-5

Remove --color-font-ltgray-5

(parse)


[error] 200-200: Unexpected value or character.

Expected one of:

(parse)


[error] 200-200: expected , but instead found ;

Remove ;

(parse)


[error] 203-203: expected , but instead found --color-error

Remove --color-error

(parse)


[error] 203-203: Unexpected value or character.

Expected one of:

(parse)


[error] 203-203: expected , but instead found ;

Remove ;

(parse)


[error] 204-204: expected , but instead found --color-success

Remove --color-success

(parse)


[error] 204-204: Unexpected value or character.

Expected one of:

(parse)


[error] 204-204: Expected an identifier but instead found '00'.

Expected an identifier here.

(parse)


[error] 204-204: expected , but instead found c673

Remove c673

(parse)


[error] 204-204: expected , but instead found ;

Remove ;

(parse)


[error] 207-207: expected , but instead found --color-category-red-text

Remove --color-category-red-text

(parse)


[error] 207-207: Unexpected value or character.

Expected one of:

(parse)


[error] 207-207: expected , but instead found ;

Remove ;

(parse)


[error] 208-208: expected , but instead found --color-category-purple-text

Remove --color-category-purple-text

(parse)


[error] 208-208: Unexpected value or character.

Expected one of:

(parse)


[error] 208-208: Expected an identifier but instead found '612694'.

Expected an identifier here.

(parse)


[error] 209-209: expected , but instead found --color-category-navyblue-text

Remove --color-category-navyblue-text

(parse)


[error] 209-209: Unexpected value or character.

Expected one of:

(parse)


[error] 209-209: Expected an identifier but instead found '2'.

Expected an identifier here.

(parse)


[error] 209-209: expected , but instead found a378e

Remove a378e

(parse)


[error] 209-209: expected , but instead found ;

Remove ;

(parse)


[error] 210-210: expected , but instead found --color-category-skyblue-text

Remove --color-category-skyblue-text

(parse)


[error] 210-210: Unexpected value or character.

Expected one of:

(parse)


[error] 210-210: Expected an identifier but instead found '3277'.

Expected an identifier here.

(parse)


[error] 210-210: expected , but instead found b8

Remove b8

(parse)


[error] 210-210: expected , but instead found ;

Remove ;

(parse)


[error] 211-211: expected , but instead found --color-category-emerald-text

Remove --color-category-emerald-text

(parse)


[error] 211-211: Unexpected value or character.

Expected one of:

(parse)


[error] 211-211: Expected an identifier but instead found '38818'.

Expected an identifier here.

(parse)


[error] 211-211: expected , but instead found d

Remove d

(parse)


[error] 211-211: expected , but instead found ;

Remove ;

(parse)


[error] 212-212: expected , but instead found --color-category-navygreen-text

Remove --color-category-navygreen-text

(parse)


[error] 212-212: Unexpected value or character.

Expected one of:

(parse)


[error] 212-212: Expected an identifier but instead found '2'.

Expected an identifier here.

(parse)


[error] 212-212: expected , but instead found c675c

Remove c675c

(parse)


[error] 212-212: expected , but instead found ;

Remove ;

(parse)


[error] 213-213: expected , but instead found --color-category-khaki-text

Remove --color-category-khaki-text

(parse)


[error] 213-213: Unexpected value or character.

Expected one of:

(parse)


[error] 213-213: Expected an identifier but instead found '62893'.

Expected an identifier here.

(parse)


[error] 213-213: expected , but instead found d

Remove d

(parse)


[error] 213-213: expected , but instead found ;

Remove ;

(parse)


[error] 214-214: expected , but instead found --color-category-orange-text

Remove --color-category-orange-text

(parse)


[error] 214-214: Unexpected value or character.

Expected one of:

(parse)


[error] 214-214: expected , but instead found ;

Remove ;

(parse)


[error] 215-215: expected , but instead found --color-category-amber-text

Remove --color-category-amber-text

(parse)


[error] 215-215: Unexpected value or character.

Expected one of:

(parse)


[error] 215-215: expected , but instead found ;

Remove ;

(parse)


[error] 216-216: expected , but instead found --color-category-maroon-text

Remove --color-category-maroon-text

(parse)


[error] 216-216: Unexpected value or character.

Expected one of:

(parse)


[error] 216-216: Expected an identifier but instead found '4'.

Expected an identifier here.

(parse)


[error] 216-216: expected , but instead found a352f

Remove a352f

(parse)


[error] 216-216: expected , but instead found ;

Remove ;

(parse)


[error] 219-219: expected , but instead found --color-category-red-bg

Remove --color-category-red-bg

(parse)


[error] 219-219: Unexpected value or character.

Expected one of:

(parse)


[error] 219-219: expected , but instead found ;

Remove ;

(parse)


[error] 220-220: expected , but instead found --color-category-purple-bg

Remove --color-category-purple-bg

(parse)


[error] 220-220: Unexpected value or character.

Expected one of:

(parse)


[error] 220-220: expected , but instead found ;

Remove ;

(parse)


[error] 221-221: expected , but instead found --color-category-navyblue-bg

Remove --color-category-navyblue-bg

(parse)


[error] 221-221: Unexpected value or character.

Expected one of:

(parse)


[error] 221-221: expected , but instead found ;

Remove ;

(parse)


[error] 222-222: expected , but instead found --color-category-skyblue-bg

Remove --color-category-skyblue-bg

(parse)


[error] 222-222: Unexpected value or character.

Expected one of:

(parse)


[error] 222-222: expected , but instead found ;

Remove ;

(parse)


[error] 223-223: expected , but instead found --color-category-emerald-bg

Remove --color-category-emerald-bg

(parse)


[error] 223-223: Unexpected value or character.

Expected one of:

(parse)


[error] 223-223: expected , but instead found ;

Remove ;

(parse)


[error] 224-224: expected , but instead found --color-category-navygreen-bg

Remove --color-category-navygreen-bg

(parse)


[error] 224-224: Unexpected value or character.

Expected one of:

(parse)


[error] 224-224: expected , but instead found ;

Remove ;

(parse)


[error] 225-225: expected , but instead found --color-category-khaki-bg

Remove --color-category-khaki-bg

(parse)


[error] 225-225: Unexpected value or character.

Expected one of:

(parse)


[error] 225-225: expected , but instead found ;

Remove ;

(parse)


[error] 226-226: expected , but instead found --color-category-orange-bg

Remove --color-category-orange-bg

(parse)


[error] 226-226: Unexpected value or character.

Expected one of:

(parse)


[error] 226-226: expected , but instead found ;

Remove ;

(parse)


[error] 227-227: expected , but instead found --color-category-amber-bg

Remove --color-category-amber-bg

(parse)


[error] 227-227: Unexpected value or character.

Expected one of:

(parse)


[error] 227-227: expected , but instead found ;

Remove ;

(parse)


[error] 228-228: expected , but instead found --color-category-maroon-bg

Remove --color-category-maroon-bg

(parse)


[error] 228-228: Unexpected value or character.

Expected one of:

(parse)


[error] 228-228: expected , but instead found ;

Remove ;

(parse)


[error] 231-231: expected , but instead found layer

Remove layer

(parse)


[error] 161-161: Unexpected unknown pseudo-class initial

See MDN web docs for more details.

(lint/correctness/noUnknownPseudoClass)


[error] 166-166: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 167-167: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 168-168: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 169-169: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 170-170: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 174-174: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 187-187: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 189-189: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 204-204: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 209-209: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 210-210: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 211-211: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 212-212: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 213-213: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 216-216: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)


[error] 231-231: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)

🔇 Additional comments (2)
packages/tailwind-config/shared-styles.css (2)

1-1: Tailwind v4 스타일 진입점(@import 'tailwindcss') 사용 적절

v4 권장 패턴을 잘 적용하셨습니다. 각 앱에서 shared-styles.css만 import하면 Preflight/Utilities가 함께 들어와 관리가 단순해집니다.


179-189: 커스텀 Gray 토큰 네이밍(예: gray0/100/200…) 유지 OK

레포 컨벤션(learned: bg-gray200 등 무하이픈 토큰 네이밍)과 일치합니다. Tailwind 기본 네이밍으로 강제 변경하지 않는 것이 맞습니다.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/design-system/src/components/button/Button.tsx (1)

1-3: 추가 제안: cn/twMerge(extendTailwindMerge)와의 연동

공용 cn 유틸(clsx + twMerge 확장)을 이미 두셨으므로, 나중에 스타일이 붙을 때 className 병합에 cn을 활용하면 DS 유틸 클래스 충돌을 안정적으로 흡수할 수 있습니다. 추후 도입 시 아래 형태를 고려해 주세요.

예시:

// import { cn } from '@/lib/utils'; // 경로 별칭에 맞게 조정
// ...
// <button className={cn(baseClasses, className)} ...>

또한 shadcn/ui 표준 패턴(cva + asChild + Slot)을 채택하면 variant/size 스케일을 DS 토큰과 함께 구조적으로 관리할 수 있습니다. 현재 스코프에선 과하다고 판단되면 후속 PR에서 진행해도 충분합니다.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled
  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f0bba48 and 202d73b.

📒 Files selected for processing (2)
  • packages/design-system/src/components/button/Button.tsx (1 hunks)
  • packages/design-system/src/components/index.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/design-system/src/components/index.tsx
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#5
File: apps/extension/src/index.css:1-1
Timestamp: 2025-08-19T17:18:57.657Z
Learning: constantly-dev는 디자인 시스템 설정 PR 머지 후 `import 'pinback/tailwind-config/shared-styles.css';`를 `app.css`나 `index.css`에서 사용하여 공유 스타일을 관리할 계획입니다.
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#2
File: pnpm-workspace.yaml:3-3
Timestamp: 2025-08-18T13:48:59.021Z
Learning: constantly-dev는 docs 디렉터리를 컨벤션 문서 추가용으로 사용할 예정이라고 명시했습니다.
🔇 Additional comments (1)
packages/design-system/src/components/button/Button.tsx (1)

5-5: export 전략 일관화 완료 – 패키지 진입점 재노출 확인 필요

Button.tsx의 export default Button;을 제거하고 named export로 전환하셨습니다. 내부 코드를 검색한 결과:

  • src/components/index.* 파일이 존재하지 않음
  • default import·named import 사용처 없음

외부 소비자가 @pinback/design-system 패키지 진입점을 통해 Button을 사용하고 있는지, 그리고 진입점에 아래와 같은 재노출 구문이 있는지 확인해 주세요.

• packages/design-system/src/index.ts 에서
ts export { Button } from './components/button/Button';
• (필요시) 해당 라인 추가

Comment on lines +1 to +5
const Button = () => {
return <div>Button</div>;
};

export default Button;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

div 대신 button 요소 사용 + forwardRef/props 지원으로 접근성·재사용성 확보

디자인 시스템 컴포넌트의 베이스로 div 대신 시맨틱한 button을 사용하고, children/className/…propsforwardRef를 수용하는 형태가 필요합니다. 폼 내 기본 submit 방지를 위해 기본 type="button"도 지정하는 것을 권장합니다.

아래처럼 최소 안전/확장 가능한 형태로 바꾸는 것을 제안드립니다:

-const Button = () => {
-  return <div>Button</div>;
-};
-
-export default Button;
+import * as React from 'react';
+
+export type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement>;
+
+export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
+  ({ type = 'button', children, ...props }, ref) => {
+    return (
+      <button ref={ref} type={type} {...props}>
+        {children}
+      </button>
+    );
+  }
+);
+
+Button.displayName = 'Button';

@constantly-dev constantly-dev merged commit 8e24ea5 into develop Aug 19, 2025
@constantly-dev constantly-dev changed the title [Setting] 디자인 시스템 설정 & shadcn/ui 추가 Setting(project): 디자인 시스템 설정 & shadcn/ui 추가 Aug 19, 2025
@constantly-dev constantly-dev changed the title Setting(project): 디자인 시스템 설정 & shadcn/ui 추가 Setting(design-system): 디자인 시스템 설정 & shadcn/ui 추가 Aug 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Setting] tailwind css 설정 및 design token 설정

3 participants