# Дизайн-система GitLab Pajamas

## Предварительный просмотр интерфейса дизайн-системы GitLab Pajamas

Фильтруйте задания по состоянию, выберите задание, чтобы прочитать его вывод, смоделируйте успешное прохождение проверки ссылок после сбоя и восстановите исходные тестовые данные.

## Справочник по дизайн-системе GitLab Pajamas

Экспорт токенов для светлой темы и штатный CSS из @gitlab/ui 138.0.0. Имена GL_* — это экспорты JavaScript; их эквиваленты в нижнем регистре --gl-* доступны в скомпилированном CSS. В примере используется штатная таблица стилей с исходной логикой 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

### Используйте семантические роли для рабочей области

Экспорт для светлой темы содержит тёплые нейтральные поверхности, несколько уровней контрастности текста и ненавязчивые границы. В примере для карточек заданий используется стандартная поверхность, для выбранного задания — синяя, а для области журнала — тёмная. В справочнике приведены точные значения пакета: так пользователь сможет воспроизвести их сочетание, не подбирая цвета по снимку экрана.

### Передавайте смысл с помощью меток состояния

В каждой строке задания и на каждой метке указано Passed или Failed. Галочка или крестик дополняют текст; одних цветных меток было бы недостаточно. Фирменный фиолетовый цвет не используется как универсальный признак успеха. Цвета состояний в таблице намеренно отделены от синего цвета выделения.

## Шкала типографики и технический текст в дизайн-системе GitLab Pajamas

### Сохраняйте гибкие выражения там, где они нужны

В пакете есть фиксированные малые роли и крупные роли на основе clamp. Замена clamp его наибольшим конечным значением меняет адаптивное поведение. В исходном примере заголовок размером 24px соответствует размеру приложения, а вспомогательный текст — компактным ролям 12–14px; эти решения относятся к компоновке, а не к дополнительным токенам пакета.

### Используйте моноширинный шрифт для идентификаторов и вывода

Для ветки и коммита используется оформление кода, а названия заданий остаются читабельным текстом интерфейса. Вывод помещён в моноширинный блок с переносом строк, на который можно перевести клавиатурный фокус. Длинные пути переносятся, не растягивая всю страницу шире экрана телефона; при выборе задания текст заменяется, а не вставляется как необработанный HTML.

## Ритм интервалов и границ в дизайн-системе GitLab Pajamas

### Не вычисляйте значения токенов по их номеру

GL_SPACING_SCALE_3 равен 0.5rem, а scale_5 — 1rem; индекс служит ключом, а не множителем. При реализации шкалы используйте экспортированное значение. В справочной таблице указаны точные единицы измерения, в том числе шаг в ноль пикселей.

### Используйте границы для разделения областей

Светлая граница отделяет заголовок рабочей области от панели инструментов, а более заметная граница карточки обрамляет инспектор вывода. У кнопок заданий есть собственная граница выделения. Различимые границы позволяют понять, какой объект выбран, без дополнительных рамок вокруг каждой строки метаданных.

## Выбор и фильтрация заданий в дизайн-системе GitLab Pajamas

### Не связывайте выбранное задание с его позицией в фильтре

В скрипте используются стабильные строковые идентификаторы, например links и accessibility. Фильтр меняет список заданий и выбирает подходящее задание, если оно есть. Нажатие на задание одновременно обновляет состояние aria-pressed, этап, метку состояния и журнал. Так заголовок одного задания не будет показан рядом с выводом другого.

### Сохраняйте контекст восстановления, когда результат исчезает

После того как для сбойного задания смоделирован успешный результат, фильтр Failed jobs не находит заданий. Сообщение о пустом списке объясняет, как восстановить его, а инспектор сохраняет только что полученный результат. Это сделано намеренно: пользователь понимает, почему строка исчезла, и не теряет подтверждение результата.

## Повтор и сброс в дизайн-системе GitLab Pajamas

### Чётко обозначайте симуляцию

Действие называется Simulate successful retry: оно меняет только локальные тестовые данные и заменяет журнал текстом о смоделированном результате. Оно не ставит задачу в очередь исполнителя, не создаёт задание и не проверяет репозиторий. Общее состояние конвейера пересчитывается по состоянию всех заданий, а не безусловно меняется на успешное после любого нажатия.

### Полностью восстанавливайте исходные тестовые данные

Сброс создаёт новую копию исходных данных заданий, выбирает сбойное задание links, возвращает фильтр All jobs и заново отрисовывает обе панели. Смоделированный результат сбрасывается без перезагрузки страницы. Так пример можно запускать повторно, и следующий пользователь не примет ранее смоделированный успех за исходное состояние.

1. Выберите Failed jobs и изучите маршрут, вызвавший сбой.

2. Смоделируйте успех и прочитайте сохранённый результат в инспекторе и пустом отфильтрованном списке.

3. Сбросьте пример и убедитесь, что сбой и исходный вывод восстановились.

## Доступные элементы управления заданиями в дизайн-системе GitLab Pajamas

### Используйте кнопки для локального выбора

Каждое задание — настоящая кнопка с атрибутом aria-pressed. Состояние указано рядом с длительностью, а видимое состояние клавиатурного фокуса отличается от выделения. У фильтра есть видимая подпись. Для этих простых элементов управления не заявлена специальная клавиатурная навигация по графу.

### Сообщайте о результате, не перемещая фокус

После повтора или сброса результат появляется в области статуса. Журнал — это текст, который можно выделить; на него также можно перевести клавиатурный фокус, чтобы прочитать содержимое. При этом приложение не переносит фокус в журнал автоматически после каждого выбора. Так сравнивать задания можно предсказуемо, одно за другим.

## Границы интеграции CSS и Vue в дизайн-системе GitLab Pajamas

### Явно выбирайте уровень интеграции

Этот исходный код подключает опубликованный дистрибутив CSS и добавляет исходную логику HTML/JavaScript. Он не создаёт экземпляры GlButton, GlFormSelect и других экспортируемых компонентов Vue. В приложении Vue следует использовать соответствующие штатные компоненты и актуальные свойства и события, а не считать эту реализацию DOM примером для Vue.

- Дистрибутив 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 к peer-зависимостям.

```
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, точными значениями интервалов и типографики, стабильными идентификаторами заданий и доступным выбором. Используйте полный исходный код тестовых данных, сохраняйте видимый контекст сбоя, делайте понятными пустые результаты фильтрации и помечайте все локальные симуляции. Не создавайте впечатление, что CSS или повтор в примере создаёт задание GitLab CI.
```

## Источники и область применения дизайн-системы GitLab Pajamas

Руководство по приложению OpenDesign для GitLab Pajamas и @gitlab/ui 138.0.0. Стили исходного примера HTML/JavaScript задаются таблицей стилей штатного пакета CSS. Конвейер вымышленный; запросы к GitLab API, среда выполнения Vue, исполнитель CI и действия с репозиторием не используются.

- Рекомендации по цветам Pajamas Роли элементов интерфейса и значения состояний.

- Кнопки 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 Роли элементов интерфейса и значения состояний.](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)
