# GitLab Pajamas 디자인 시스템

## GitLab Pajamas 디자인 시스템 인터페이스 미리보기

상태별로 작업을 필터링하고, 작업을 선택해 출력을 확인하세요. 실패한 링크 검사가 성공하는 상황을 시뮬레이션한 뒤 원래 픽스처를 초기화할 수 있습니다.

## GitLab Pajamas 디자인 시스템 디자인 참조

@gitlab/ui 138.0.0에서 공개한 라이트 토큰 내보내기와 기본 CSS입니다. GL_* 이름은 JavaScript 내보내기 이름이며, 컴파일된 CSS에는 이에 대응하는 소문자 --gl-* 이름이 표시됩니다. 이 예제는 기본 스타일시트와 원본 HTML/상태 로직을 사용하며, Vue 컴포넌트를 마운트하지 않습니다.

### 시맨틱 표면, 텍스트 및 테두리

| 이름 / 규칙 | 값 / 구성 | 용도 |
| --- | --- | --- |
| GL_BACKGROUND_COLOR_DEFAULT | #fff | 토큰에 지정된 역할을 사용하세요. 여기에 제시된 값은 라이트 참조 내보내기입니다. |
| GL_BACKGROUND_COLOR_SUBTLE | #f7f7f5 | 토큰에 지정된 역할을 사용하세요. 여기에 제시된 값은 라이트 참조 내보내기입니다. |
| GL_BACKGROUND_COLOR_STRONG | #ecebea | 토큰에 지정된 역할을 사용하세요. 여기에 제시된 값은 라이트 참조 내보내기입니다. |
| GL_TEXT_COLOR_DEFAULT | #3a383d | 토큰에 지정된 역할을 사용하세요. 여기에 제시된 값은 라이트 참조 내보내기입니다. |
| GL_TEXT_COLOR_SUBTLE | #646163 | 토큰에 지정된 역할을 사용하세요. 여기에 제시된 값은 라이트 참조 내보내기입니다. |
| GL_TEXT_COLOR_STRONG | #18171d | 토큰에 지정된 역할을 사용하세요. 여기에 제시된 값은 라이트 참조 내보내기입니다. |
| GL_TEXT_COLOR_HEADING | #18171d | 토큰에 지정된 역할을 사용하세요. 여기에 제시된 값은 라이트 참조 내보내기입니다. |
| GL_TEXT_COLOR_LINK | #27599f | 토큰에 지정된 역할을 사용하세요. 여기에 제시된 값은 라이트 참조 내보내기입니다. |
| GL_BORDER_COLOR_DEFAULT | #dcdbd9 | 토큰에 지정된 역할을 사용하세요. 여기에 제시된 값은 라이트 참조 내보내기입니다. |
| GL_BORDER_COLOR_SUBTLE | #ecebea | 토큰에 지정된 역할을 사용하세요. 여기에 제시된 값은 라이트 참조 내보내기입니다. |
| GL_BORDER_COLOR_STRONG | #c1bfbe | 토큰에 지정된 역할을 사용하세요. 여기에 제시된 값은 라이트 참조 내보내기입니다. |
### 인터페이스 간격

| 이름 / 규칙 | 값 / 구성 | 용도 |
| --- | --- | --- |
| GL_SPACING_SCALE_0 | 0px | 간격 스케일 값은 인덱스에 하나의 상수를 곱해 계산할 수 없습니다. |
| GL_SPACING_SCALE_1 | 0.125rem | 간격 스케일 값은 인덱스에 하나의 상수를 곱해 계산할 수 없습니다. |
| GL_SPACING_SCALE_2 | 0.25rem | 간격 스케일 값은 인덱스에 하나의 상수를 곱해 계산할 수 없습니다. |
| GL_SPACING_SCALE_3 | 0.5rem | 간격 스케일 값은 인덱스에 하나의 상수를 곱해 계산할 수 없습니다. |
| GL_SPACING_SCALE_4 | 0.75rem | 간격 스케일 값은 인덱스에 하나의 상수를 곱해 계산할 수 없습니다. |
| GL_SPACING_SCALE_5 | 1rem | 간격 스케일 값은 인덱스에 하나의 상수를 곱해 계산할 수 없습니다. |
| GL_SPACING_SCALE_6 | 1.5rem | 간격 스케일 값은 인덱스에 하나의 상수를 곱해 계산할 수 없습니다. |
| GL_SPACING_SCALE_7 | 2rem | 간격 스케일 값은 인덱스에 하나의 상수를 곱해 계산할 수 없습니다. |
| GL_SPACING_SCALE_8 | 2.5rem | 간격 스케일 값은 인덱스에 하나의 상수를 곱해 계산할 수 없습니다. |
| GL_SPACING_SCALE_9 | 3rem | 간격 스케일 값은 인덱스에 하나의 상수를 곱해 계산할 수 없습니다. |
### 반응형 글자 크기 스케일

| 이름 / 규칙 | 값 / 구성 | 용도 |
| --- | --- | --- |
| GL_FONT_SIZE_100 | 0.75rem | 큰 역할에는 clamp가 사용됩니다. 유동적인 타이포그래피가 필요한 경우 이 표현식을 그대로 유지하세요. |
| GL_FONT_SIZE_200 | 0.8125rem | 큰 역할에는 clamp가 사용됩니다. 유동적인 타이포그래피가 필요한 경우 이 표현식을 그대로 유지하세요. |
| GL_FONT_SIZE_300 | 0.875rem | 큰 역할에는 clamp가 사용됩니다. 유동적인 타이포그래피가 필요한 경우 이 표현식을 그대로 유지하세요. |
| GL_FONT_SIZE_400 | 1rem | 큰 역할에는 clamp가 사용됩니다. 유동적인 타이포그래피가 필요한 경우 이 표현식을 그대로 유지하세요. |
| GL_FONT_SIZE_500 | clamp(1.125rem, 0.9027777778rem + 0.462962963vw, 1.25rem) | 큰 역할에는 clamp가 사용됩니다. 유동적인 타이포그래피가 필요한 경우 이 표현식을 그대로 유지하세요. |
| GL_FONT_SIZE_600 | clamp(1.3125rem, 0.8680555556rem + 0.9259259259vw, 1.5625rem) | 큰 역할에는 clamp가 사용됩니다. 유동적인 타이포그래피가 필요한 경우 이 표현식을 그대로 유지하세요. |
| GL_FONT_SIZE_700 | clamp(1.5rem, 0.8333333333rem + 1.3888888889vw, 1.875rem) | 큰 역할에는 clamp가 사용됩니다. 유동적인 타이포그래피가 필요한 경우 이 표현식을 그대로 유지하세요. |
| GL_FONT_SIZE_800 | clamp(1.75rem, 0.8611111111rem + 1.8518518519vw, 2.25rem) | 큰 역할에는 clamp가 사용됩니다. 유동적인 타이포그래피가 필요한 경우 이 표현식을 그대로 유지하세요. |
### 컨트롤 및 표면의 모서리 반경

| 이름 / 규칙 | 값 / 구성 | 용도 |
| --- | --- | --- |
| GL_BORDER_RADIUS_NONE | 0px | 반경은 컴포넌트의 형태를 나타내며, 작업의 중요도를 뜻하지 않습니다. |
| GL_BORDER_RADIUS_XS | 1px | 반경은 컴포넌트의 형태를 나타내며, 작업의 중요도를 뜻하지 않습니다. |
| GL_BORDER_RADIUS_SM | 0.125rem | 반경은 컴포넌트의 형태를 나타내며, 작업의 중요도를 뜻하지 않습니다. |
| GL_BORDER_RADIUS_MD | 0.25rem | 반경은 컴포넌트의 형태를 나타내며, 작업의 중요도를 뜻하지 않습니다. |
| GL_BORDER_RADIUS_LG | 0.5rem | 반경은 컴포넌트의 형태를 나타내며, 작업의 중요도를 뜻하지 않습니다. |
| GL_BORDER_RADIUS_XL | 0.75rem | 반경은 컴포넌트의 형태를 나타내며, 작업의 중요도를 뜻하지 않습니다. |
| GL_BORDER_RADIUS_FULL | 9999px | 반경은 컴포넌트의 형태를 나타내며, 작업의 중요도를 뜻하지 않습니다. |
| GL_BORDER_RADIUS_DEFAULT | 0.25rem | 반경은 컴포넌트의 형태를 나타내며, 작업의 중요도를 뜻하지 않습니다. |
### 상태 색상 참조

| 이름 / 규칙 | 값 / 구성 | 용도 |
| --- | --- | --- |
| GL_COLOR_GREEN_50 | #e6f5ea | 성공 상태에 사용하는 절제된 표면 색상입니다. |
| GL_COLOR_GREEN_800 | #075048 | 밝은 표면 위에서 성공 상태를 나타내는 전경색입니다. |
| GL_COLOR_RED_50 | #feeef0 | 실패 상태에 사용하는 절제된 표면 색상입니다. |
| GL_COLOR_RED_800 | #891c2f | 밝은 표면 위에서 실패 상태를 나타내는 전경색입니다. |
| GL_COLOR_BLUE_50 | #e8f2fd | 선택된 작업의 표면 색상입니다. |
| GL_COLOR_BLUE_700 | #27599f | 선택 테두리 및 눈에 보이는 포커스 참조입니다. |
## GitLab Pajamas 디자인 시스템 전체 가이드

실제 인터페이스를 위해 이 시스템을 선택하고 적용하고 검토하는 실용 가이드.

완전한 안내와 구현 시작점, 소스 링크.

## GitLab Pajamas 디자인 시스템 파이프라인 정보 구조

### 복구 방법보다 실패 상황을 먼저 설명하세요

> 헤더에는 가상의 파이프라인, 브랜치 및 커밋을 표시해 작업 검사기에 맥락을 제공합니다. Build, Test 및 Publish는 그룹으로 구분되며, 작업을 선택하면 해당 작업의 출력이 열립니다. 링크 검사 실패 항목에는 재시도 작업을 보여주기 전에 실패 이유를 설명하는 경로와 종료 조건이 포함됩니다.

### 간결한 그래프를 읽기 쉽게 유지하세요

이 예제는 완전한 종속성 그래프를 구현하는 대신 단계 열과 버튼을 사용합니다. 화면이 좁아지면 문서 순서에 따라 단계가 세로로 쌓입니다. 실제 파이프라인에는 병렬 작업, 종속성, 대기, 수동 및 취소 상태가 필요할 수 있습니다. 이런 상태는 세 가지 예시 제목만으로 추론하지 말고 명시적으로 모델링해야 합니다.

## GitLab Pajamas 디자인 시스템 시맨틱 색상 및 상태

### 작업 영역에는 시맨틱 UI 역할을 사용하세요

라이트 내보내기는 따뜻한 중성 표면, 강약이 구분되는 텍스트 및 은은한 테두리를 제공합니다. 이 예제에서는 작업 카드에 기본 표면을, 선택 항목에 파란색 표면을, 로그 영역에 어두운 표면을 사용합니다. 가이드에는 패키지의 정확한 값이 나와 있어 스크린샷에서 픽셀 색을 추출하지 않고도 같은 색상 관계를 재현할 수 있습니다.

### 상태 레이블에 의미를 담으세요

각 작업 행과 배지에는 Passed 또는 Failed가 표시됩니다. 체크 표시나 엑스 표시는 텍스트를 보완하며, 색상 배지만으로는 의미가 모호할 수 있습니다. 브랜드 보라색을 일반적인 성공 표시로 사용하지 않습니다. 표의 상태 참조 색상은 선택 항목의 파란색과 의도적으로 구분되어 있습니다.

## GitLab Pajamas 디자인 시스템 글자 크기 스케일 및 기술 텍스트

### 필요한 곳에는 유동형 표현식을 유지하세요

패키지는 고정된 작은 역할과 clamp 기반의 큰 역할을 제공합니다. clamp를 가장 큰 끝점 값으로 대체하면 반응형 동작이 달라집니다. 원본 예제에서는 애플리케이션 크기의 24px 제목과 12–14px의 간결한 보조 텍스트 역할을 사용합니다. 이러한 값은 추가 패키지 토큰이 아니라 레이아웃 결정으로 구분됩니다.

### 식별자와 출력에는 고정폭 글꼴을 사용하세요

브랜치와 커밋에는 코드 스타일을 적용하고, 작업 이름은 읽기 쉬운 인터페이스 텍스트로 유지합니다. 출력은 줄바꿈이 적용된 고정폭 글꼴 블록으로 표시하며 키보드 포커스를 받을 수 있습니다. 긴 경로는 줄바꿈되어 페이지 전체가 휴대전화 화면보다 넓어지는 일을 방지합니다. 선택 항목을 변경하면 원시 HTML를 삽입하는 대신 텍스트가 교체됩니다.

## GitLab Pajamas 디자인 시스템 간격 및 테두리 리듬

### 토큰 값이 숫자로부터 계산된다고 가정하지 마세요

GL_SPACING_SCALE_3은 0.5rem이고 scale_5는 1rem입니다. 인덱스는 키일 뿐, 직접 곱하는 값이 아닙니다. 스케일을 구현할 때는 내보낸 값을 사용하세요. 참조 표에는 0픽셀 단계까지 포함해 정확한 단위가 표시되어 있습니다.

### 영역을 구분할 때 경계를 활용하세요

밝은 테두리는 작업 영역 헤더와 도구 모음을 나누고, 더 뚜렷한 카드 경계는 출력 검사기를 감쌉니다. 작업 버튼에는 선택 상태를 나타내는 별도의 테두리가 있습니다. 경계를 서로 구분해 사용하면 메타데이터의 모든 줄을 또 다른 상자로 둘러싸지 않고도 어떤 개체가 선택되었는지 명확하게 알 수 있습니다.

## GitLab Pajamas 디자인 시스템 작업 선택 및 필터링

### 선택된 작업은 필터 위치와 별개로 식별되도록 유지하세요

스크립트는 links 및 accessibility와 같은 안정적인 문자열 ID를 사용합니다. 필터를 변경하면 작업 목록이 갱신되고, 일치하는 작업이 있으면 해당 작업을 선택합니다. 작업을 클릭하면 눌림 상태, 단계, 상태 배지 및 로그가 함께 업데이트됩니다. 따라서 한 작업의 제목에 다른 작업의 출력이 표시되는 일을 방지합니다.

### 결과가 목록에서 사라져도 복구 맥락을 유지하세요

실패한 작업을 성공으로 시뮬레이션하면 Failed jobs 필터에 결과가 표시되지 않습니다. 빈 상태 메시지는 목록을 다시 표시하는 방법을 안내하고, 검사기는 방금 완료된 결과를 계속 보여줍니다. 이렇게 하면 행이 사라진 이유를 이해할 수 있으며 완료 확인도 놓치지 않습니다.

## GitLab Pajamas 디자인 시스템 재시도 및 초기화 동작

### 시뮬레이션임을 명확하게 표시하세요

작업 이름은 Simulate successful retry이며, 로컬 픽스처만 변경하고 시뮬레이션 결과를 텍스트로 표시합니다. 러너를 대기열에 추가하거나 작업을 만들거나 저장소를 검사하지 않습니다. 전체 파이프라인 배지는 클릭할 때마다 성공으로 바꾸는 대신 모든 작업 상태를 바탕으로 다시 계산됩니다.

### 초기 픽스처 전체를 복원하세요

초기화하면 최초 작업 데이터의 새 사본을 만들고, 실패한 링크 작업을 선택하며, 모든 작업을 복원하고 두 패널을 다시 렌더링합니다. 페이지를 새로고침하지 않고 시뮬레이션 결과를 지웁니다. 덕분에 예제를 반복해서 확인할 수 있고, 다음 사용자가 이전에 시뮬레이션한 성공 결과를 초기 상태로 오인하지 않습니다.

1. 실패한 작업을 선택하고 실패한 경로를 확인하세요.

2. 성공을 시뮬레이션한 뒤 유지된 검사기와 비어 있는 필터링 목록을 확인하세요.

3. 예제를 초기화하고 실패 상태와 원래 출력이 복원되는지 확인하세요.

## GitLab Pajamas 디자인 시스템 접근성 작업 컨트롤

### 로컬 선택에는 버튼 사용

각 작업은 aria-pressed 속성이 있는 실제 버튼입니다. 상태는 소요 시간 옆에 표시되며, 키보드 포커스 표시는 선택된 모양과 별도로 유지됩니다. 필터에는 눈에 보이는 레이블이 있습니다. 이러한 단순한 컨트롤에 맞춤 키보드 전용 그래프 탐색 기능을 제공한다고 주장하지 않습니다.

### 독자의 포커스를 옮기지 않고 결과 알리기

재시도하거나 초기화한 뒤 결과를 상태 영역에 표시합니다. 로그는 선택할 수 있는 텍스트이며, 키보드 포커스를 받아 읽을 수 있지만 선택할 때마다 애플리케이션이 로그로 포커스를 자동 이동하지는 않습니다. 따라서 작업을 반복해 비교할 때 예측 가능한 동작을 유지할 수 있습니다.

## GitLab Pajamas 디자인 시스템 CSS과 Vue 통합 경계

### 통합 수준을 명확히 선택

이 소스는 공개된 CSS 배포판을 가져오고, 독자적인 HTML/JavaScript 동작을 제공합니다. GlButton, GlFormSelect 또는 다른 Vue 내보내기 항목을 인스턴스화하지 않습니다. Vue 애플리케이션에서는 이 DOM 구현을 Vue 예제로 취급하지 말고, 해당하는 네이티브 컴포넌트와 현재 props/events를 사용해야 합니다.

- CSS 배포판: 네이티브 모양과 시맨틱 변수.

- 독자적인 HTML: 접근성 있는 컨트롤과 영역 구조.

- 독자적인 JavaScript: 픽스처 데이터, 선택, 필터 및 시뮬레이션.

### 토큰을 가져온 릴리스에 맞춰 유지

참조 값은 미리보기와 동일한 138.0.0 패키지에서 가져왔습니다. 향후 토큰과 컴포넌트 변경 사항은 함께 검토해야 합니다. 아래 전체 소스에는 독자적인 CSS 구성과 픽스처 로직이 포함되어 있어, 다운로드한 가이드만으로도 예시 동작을 재현할 수 있습니다.

## GitLab Pajamas 디자인 시스템 컴포넌트 예제

### index.html — 파이프라인 작업 공간

시맨틱 레이아웃과 컨트롤 전체.

```
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Pipeline specimen</title>
<body>
<main class="pipeline-example">
  <header>
    <p class="eyebrow">sample-team / documentation</p>
    <div class="title-row">
      <div>
        <h1>Pipeline #1842</h1>
        <p>
          Preview build for <code>docs/update-navigation</code> ·
          <code>7c31a82</code>
        </p>
      </div>
      <span id="pipeline-state" class="state failed">Failed</span>
    </div>
  </header>
  <div class="toolbar">
    <label for="job-filter">Show jobs</label
    ><select id="job-filter" class="gl-form-select">
      <option value="all">All jobs</option>
      <option value="failed">Failed jobs</option>
      <option value="passed">Passed jobs</option></select
    ><button id="reset" class="btn btn-default gl-button">
      Reset specimen
    </button>
  </div>
  <div class="pipeline-layout">
    <section aria-label="Pipeline stages">
      <div id="stages" class="stages"></div>
      <p id="empty" hidden>
        No jobs match this filter. Choose All jobs to restore the pipeline.
      </p>
    </section>
    <section class="job-detail" aria-labelledby="job-title">
      <div class="detail-heading">
        <h2 id="job-title"></h2>
        <span id="job-state" class="state"></span>
      </div>
      <dl>
        <dt>Stage</dt>
        <dd id="job-stage"></dd>
        <dt>Runner</dt>
        <dd>local-example-runner</dd>
        <dt>Execution</dt>
        <dd>Simulated in this page</dd>
      </dl>
      <h3>Job output</h3>
      <pre id="job-log" tabindex="0" aria-label="Selected job output"></pre>
      <button id="retry" class="btn btn-confirm gl-button">
        Simulate successful retry
      </button>
      <p id="feedback" role="status"></p>
    </section>
  </div>
  <footer>
    Native @gitlab/ui 138.0.0 CSS with original HTML and state logic. Fictional
    pipeline; no runner, repository or CI job is started.
  </footer>
</main>

<script type="module" src="/src/main.js"></script>
</body></html>
```

코드 참조

- Vite 프로젝트 루트에 저장하세요.

### main.js — 픽스처 및 복구 로직

네이티브 CSS 가져오기와 단계별 작업 동작 전체.

```
import "@gitlab/ui/dist/index.css";
import "./pajamas.css";
const initial = [
  {
    id: "lint",
    stage: "Build",
    state: "passed",
    time: "12s",
    log: "$ npm run lint\nNo lint errors.\nJob succeeded.",
  },
  {
    id: "bundle",
    stage: "Build",
    state: "passed",
    time: "31s",
    log: "$ npm run build\nStatic assets generated.\nJob succeeded.",
  },
  {
    id: "links",
    stage: "Test",
    state: "failed",
    time: "18s",
    log: "$ npm run check:links\n/docs/old-navigation returned 404\n1 broken internal link.\nJob failed: exit code 1.",
  },
  {
    id: "accessibility",
    stage: "Test",
    state: "passed",
    time: "24s",
    log: "$ npm run check:a11y\nExample fixture checks passed.\nJob succeeded.",
  },
  {
    id: "preview",
    stage: "Publish",
    state: "passed",
    time: "9s",
    log: "$ npm run package:preview\nLocal preview archive generated.\nJob succeeded.",
  },
];
let jobs = structuredClone(initial),
  selected = "links";
const filter = document.querySelector("#job-filter"),
  stages = document.querySelector("#stages"),
  retry = document.querySelector("#retry"),
  feedback = document.querySelector("#feedback");
function render() {
  stages.replaceChildren();
  let count = 0;
  for (const name of ["Build", "Test", "Publish"]) {
    const matches = jobs.filter(
      (j) =>
        j.stage === name &&
        (filter.value === "all" || j.state === filter.value),
    );
    if (!matches.length) continue;
    const section = document.createElement("div");
    section.className = "stage";
    const h = document.createElement("h2");
    h.textContent = name;
    section.append(h);
    for (const j of matches) {
      count++;
      const b = document.createElement("button");
      b.type = "button";
      b.className = "job";
      b.setAttribute("aria-pressed", String(j.id === selected));
      const strong = document.createElement("strong"),
        small = document.createElement("small");
      strong.textContent = j.id;
      small.textContent =
        (j.state === "passed" ? "✓ Passed" : "× Failed") + " · " + j.time;
      b.append(strong, small);
      b.onclick = () => {
        selected = j.id;
        feedback.textContent = "";
        render();
      };
      section.append(b);
    }
    stages.append(section);
  }
  document.querySelector("#empty").hidden = count !== 0;
  const j = jobs.find((j) => j.id === selected);
  document.querySelector("#job-title").textContent = j.id;
  document.querySelector("#job-stage").textContent = j.stage;
  document.querySelector("#job-log").textContent = j.log;
  const state = document.querySelector("#job-state");
  state.className = "state " + j.state;
  state.textContent = j.state === "passed" ? "Passed" : "Failed";
  retry.hidden = j.state !== "failed";
  const failed = jobs.some((j) => j.state === "failed"),
    overall = document.querySelector("#pipeline-state");
  overall.textContent = failed ? "Failed" : "Passed";
  overall.className = "state " + (failed ? "failed" : "passed");
}
filter.onchange = () => {
  const match = jobs.find(
    (j) => filter.value === "all" || j.state === filter.value,
  );
  if (match) selected = match.id;
  feedback.textContent = "";
  render();
};
retry.onclick = () => {
  const j = jobs.find((j) => j.id === selected);
  j.state = "passed";
  j.time = "15s";
  j.log =
    "$ npm run check:links\nSimulation: updated route found.\nNo broken internal links.\nJob succeeded (local simulation).";
  render();
  feedback.textContent =
    "Simulated retry completed locally. No CI job was started.";
};
document.querySelector("#reset").onclick = () => {
  jobs = structuredClone(initial);
  selected = "links";
  filter.value = "all";
  feedback.textContent = "Specimen restored.";
  render();
};
render();
```

코드 참조

- src/main.js로 저장하세요. CI 요청은 없습니다.

### pajamas.css — 원본 구성

반응형 단계, 선택된 카드, 메타데이터 및 줄바꿈되는 로그 출력.

```
[hidden] {
  display: none !important;
}
* {
  box-sizing: border-box;
}
body {
  margin: 0;
  font-family: Arial, sans-serif;
  font-size: 14px;
  color: var(--gl-text-color-default, #3a383d);
  background: var(--gl-background-color-default, #fff);
}
.pipeline-example {
  padding: 28px;
}
.pipeline-example header {
  padding-bottom: 20px;
  border-bottom: 1px solid var(--gl-border-color-default);
}
.eyebrow {
  font-size: 12px;
  color: var(--gl-text-color-subtle);
  margin-bottom: 16px;
}
.title-row {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  align-items: flex-start;
}
h1 {
  font-size: 24px;
  font-weight: 600;
  margin: 0 0 8px;
}
h2 {
  font-size: 18px;
  font-weight: 600;
  margin: 0;
}
h3 {
  font-size: 14px;
  font-weight: 600;
}
.title-row p {
  margin: 0;
  color: var(--gl-text-color-subtle);
}
code {
  font: 12px monospace;
  background: #f7f7f5;
  color: #3a383d;
  padding: 2px 4px;
  overflow-wrap: anywhere;
}
.toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 20px 0;
}
.toolbar label {
  margin: 0;
  font-weight: 600;
}
.toolbar select {
  max-width: 180px;
}
.toolbar button {
  margin-left: auto;
}
.pipeline-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(300px, 1fr);
  gap: 24px;
}
.stages {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}
.stage h2 {
  font-size: 13px;
  margin-bottom: 12px;
  color: var(--gl-text-color-subtle);
}
.job {
  display: block;
  width: 100%;
  text-align: left;
  background: #fff;
  border: 1px solid var(--gl-border-color-default);
  border-radius: 4px;
  padding: 12px;
  margin-bottom: 8px;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.job[aria-pressed="true"] {
  border-color: #27599f;
  box-shadow: inset 0 0 0 1px #27599f;
  background: #e8f2fd;
}
.job strong {
  display: block;
  font-size: 13px;
  overflow-wrap: anywhere;
}
.job small {
  display: block;
  margin-top: 6px;
  color: var(--gl-text-color-subtle);
}
.job-detail {
  border: 1px solid var(--gl-border-color-default);
  border-radius: 4px;
  padding: 20px;
  min-width: 0;
}
.detail-heading {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  align-items: center;
}
.state {
  font-size: 12px;
  font-weight: 600;
  border-radius: 9999px;
  padding: 3px 9px;
  white-space: nowrap;
}
.state.failed {
  background: #feeef0;
  color: #891c2f;
}
.state.passed {
  background: #e6f5ea;
  color: #075048;
}
dl {
  display: grid;
  grid-template-columns: 90px minmax(0, 1fr);
  gap: 8px;
  margin: 20px 0;
  font-size: 12px;
}
dt {
  color: var(--gl-text-color-subtle);
  font-weight: 400;
}
dd {
  margin: 0;
  overflow-wrap: anywhere;
}
pre {
  background: #18171d;
  color: #ecebea;
  padding: 16px;
  border-radius: 4px;
  font: 12px/1.7 monospace;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  min-height: 160px;
  margin-bottom: 16px;
}
#feedback {
  font-size: 12px;
  margin: 12px 0 0;
}
footer {
  margin-top: 28px;
  padding-top: 16px;
  border-top: 1px solid var(--gl-border-color-subtle);
  font-size: 12px;
  color: var(--gl-text-color-subtle);
}
button:focus-visible,
select:focus-visible,
pre:focus-visible {
  outline: 2px solid #27599f;
  outline-offset: 3px;
}
@media (max-width: 1050px) {
  .pipeline-layout {
    grid-template-columns: 1fr;
  }
  .stages {
    gap: 16px;
  }
}
@media (max-width: 550px) {
  .pipeline-example {
    padding: 16px;
  }
  .toolbar {
    flex-wrap: wrap;
  }
  .toolbar button {
    margin-left: 0;
  }
  .stages {
    grid-template-columns: 1fr;
  }
  .stage {
    border-bottom: 1px solid var(--gl-border-color-subtle);
    padding-bottom: 8px;
  }
  .title-row {
    flex-wrap: wrap;
  }
  .job-detail {
    padding: 16px;
  }
}
```

코드 참조

- src/pajamas.css로 저장하세요. 시스템 글꼴 대체가 명시되어 있으며 GitLab 브랜드 글꼴은 포함되지 않습니다.

## GitLab Pajamas 디자인 시스템 에이전트 설정

### 구현 시작점

이 통합은 네이티브 CSS 배포판만 가져옵니다. Vue 컴포넌트를 도입하는 경우 GitLab UI의 피어 종속성 요구 사항을 별도로 확인하세요.

```
npm create vite@latest pajamas-pipeline -- --template vanilla
cd pajamas-pipeline
npm install
npm install @gitlab/ui@138.0.0
# Replace index.html; add src/main.js and src/pajamas.css from the complete examples.
npm run dev
```

### 프로젝트를 위한 프롬프트

```
Pajamas 시맨틱 표면, 실제 간격 및 타이포그래피 참조, 안정적인 작업 ID, 접근성 있는 선택 기능을 사용해 기술 작업 검사기를 만드세요. 픽스처 전체 소스를 사용하고, 실패 맥락을 눈에 띄게 유지하며, 필터 결과가 없을 때 이를 이해하기 쉽게 안내하고, 모든 로컬 시뮬레이션에 레이블을 표시하세요. CSS이나 예제의 재시도가 GitLab CI 작업을 생성한다고 암시하지 마세요.
```

## GitLab Pajamas 디자인 시스템 출처 및 범위

OpenDesign에서 GitLab Pajamas 및 @gitlab/ui 138.0.0을 사용하는 애플리케이션 가이드입니다. 네이티브 패키지 CSS는 독자적인 HTML/JavaScript 예제에 스타일을 적용합니다. 파이프라인은 가상이며 GitLab API, Vue 런타임, CI 러너 또는 저장소 작업은 호출되지 않습니다.

- Pajamas 색상 지침 UI 역할 및 상태의 의미.

- Pajamas 버튼 동작 계층 및 버튼 동작.

- 고정된 토큰 내보내기 138.0.0의 정확한 참조 값.

- 공식 출처 Pajamas 및 GitLab UI 소스 저장소.

## GitLab Pajamas 디자인 시스템 관련 자료

### HPE Grommet

Grommet의 레이아웃 기본 요소, 제어형 폼 필드, 숫자 미터를 사용해 수용 인원 예약 인터페이스를 구성하세요. 테마 스케일을 의도적으로 활용하고, 기본 Grommet 테마와 별도로 설치하는 HPE 테마를 구분하세요.

### Infor 디자인 시스템

실제 IDS 입력 상태, 테마 별칭 및 정확한 에셋 식별자를 사용해 엔터프라이즈 유지보수 양식을 구성하세요. 현재 공개 테마 토큰과 버전을 고정한 Web Components 패키지, 유효성 검사 및 초기화 기능이 있는 로컬 초안 워크플로를 살펴보세요.

### Kajabi Sage

읽기 쉬운 강좌 맥락, 명확한 복사 작업, 정확한 클립보드 피드백을 제공하는 크리에이터용 공유 패널을 만드세요. Sage의 Rails 컴포넌트 구조, 공개된 타이포그래피 사양, 외부에서 불러오는 최신 Pine 토큰 계층을 살펴보세요.


- [구현 레퍼런스](https://design.gitlab.com/)
- [출처](https://cdn.jsdelivr.net/npm/@gitlab/ui@138.0.0/dist/tokens/build/js/tokens.js)
- [코드 참조](https://design.gitlab.com/)
- [Pajamas 색상 지침 UI 역할 및 상태의 의미.](https://design.gitlab.com/product-foundations/color/)
- [Pajamas 버튼 동작 계층 및 버튼 동작.](https://design.gitlab.com/components/button/)
- [고정된 토큰 내보내기 138.0.0의 정확한 참조 값.](https://cdn.jsdelivr.net/npm/@gitlab/ui@138.0.0/dist/tokens/build/js/tokens.js)
- [공식 출처 Pajamas 및 GitLab UI 소스 저장소.](https://gitlab.com/gitlab-org/gitlab-services/design.gitlab.com)
