Дизайн корпоративных продуктов · Новый ресурс

Дизайн-система Maersk.

Изучите язык операционного интерфейса Maersk на примере настоящих ролей светлой темы, шкал заголовков и основного текста, вложенных скруглений и обработки идентификаторов. Пример поиска отправления показывает точное совпадение по номеру и доступную историю событий, не создавая впечатления доступа к данным текущей логистики.

Руководство OpenDesign8 глав37 справочных записейАвторское руководство по приложению
01

Дизайн-система Maersk Предпросмотр интерфейса

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

Поиск примера отправленияОткрыть полный пример
Оригинальная автономная интерпретация на нативном HTML с использованием документированных светлых ролей и отступов Maersk. Без закрытой среды выполнения MDS, файлов фирменных шрифтов и подключения к актуальным данным об отправлениях. · Справочник по реализации
02

Дизайн-система Maersk Справочник по дизайну

Общедоступная основа MDS и документация по использованию компонентов. Нативные пакеты компонентов доступны в закрытых реестрах Maersk; в работающем примере используются нативный HTML и документированный снимок токенов, а не выдуманные API mc-*.

Светлые роли Maersk

Источник
Название / правилоЗначение / конфигурацияПрименение
--mds_brand_appearance_primary_default_background-color#141414 Основное действие с заливкой.
--mds_brand_appearance_primary_default_on-background-color#FFFFFF Текст на основном цветном фоне.
--mds_brand_appearance_primary_default_link-color#0077B2 Текст ссылки.
--mds_brand_appearance_secondary_default_background-color#42B0D5 Вторичный фирменный цвет фона.
--mds_brand_appearance_secondary_default_on-background-color#141414 Текст на вторичном цветном фоне.
--mds_brand_appearance_secondary_weak_background-color#E2F3F9 Ненавязчивый вторичный фон.
--mds_brand_appearance_neutral_default_border-color#D4D4D4 Стандартная граница.
--mds_brand_appearance_neutral_weakest_text-color#6A6A6A Вспомогательный текст.
--mds_brand_appearance_neutral_weakest_background-color#F7F7F7 Ненавязчивый фон страницы.

Шкала текста

Источник
Название / правилоЗначение / конфигурацияПрименение
--mds_brand_typography_text_font-familyMaersk TextФирменный шрифт.
text_large desktop/mobile18px / 28px line heightОдинаково на обеих платформах.
text_medium desktop/mobile16px / 24px line heightСтандартный размер основного текста.
text_small desktop/mobile14px / 20px line heightКомпактные метаданные.
text_x-small desktop/mobile12px / 16px line heightНаименьший справочный размер.
normal / light / medium / semibold / bold400 / 300 / 500 / 600 / 700Документированные насыщенности текста.

Шкала заголовков

Источник
Название / правилоЗначение / конфигурацияПрименение
headline_large desktop50px / 56px, weight 300Крупный акцидентный заголовок.
headline_large mobile38px / 38px, weight 300Версия для мобильных устройств.
headline_medium desktop40px / 40px, weight 300Заголовок страницы.
headline_medium mobile26px / 32px, weight 300Заголовок мобильной страницы.
headline_small desktop26px / 32px, weight 400Заголовок раздела.
headline_small mobile22px / 26px, weight 400Заголовок раздела на мобильном устройстве.
headline_x-small desktop/mobile20px / 24px, weight 400Небольшой заголовок.

Радиусы скругления

Источник
Название / правилоЗначение / конфигурацияПрименение
radius-xs2pxНебольшие вложенные элементы.
radius-sm4pxЭлементы размером с флажок.
radius-md6pxКнопки и поля ввода.
radius-lg8pxУведомления и таблицы.
radius-xl12pxКарточки со вложенными элементами управления.
radius-2xl16pxКрупные изображения и диалоговые окна.
radius-full9999pxПолностью скруглённые формы.

Отступы и плотность

Источник
Название / правилоЗначение / конфигурацияПрименение
Base rhythm4px multiplesВнутренние и внешние отступы, а также интервалы.
Fine component exceptions2px, 6px, 10pxВыравнивание небольших компонентов.
Responsive dimensionsNot required to be divisible by 4Соблюдайте шаг сетки при размещении соседних элементов.

Иерархия действий

Источник
Название / правилоЗначение / конфигурацияПрименение
Primary actionPrimary + FilledОдно основное действие.
Secondary actionNeutral + OutlinedВспомогательное действие в открытой форме.
Tertiary actionNeutral + PlainОчистка, сброс или повторное раскрытие.
Secondary in a dialogNeutral + FilledНе создавайте конкурирующие обводки.
Brand hero exceptionSecondary + FilledНе используйте как стандартное действие формы.
03

Дизайн-система Maersk Полное руководство

Практическое руководство по выбору, применению и оценке этой системы для реального интерфейса.

DESIGN-maersk.md

Подробные рекомендации, отправная точка для реализации и ссылки на источники.

Скачать руководство

Дизайн-система Maersk Общедоступные правила и закрытые компоненты — разные ресурсы

Честно выбирайте способ внедрения

MDS предоставляет широкую документацию по основе и использованию компонентов в открытом доступе, однако в руководстве для разработчиков указано, что пакеты размещены в закрытых реестрах Maersk Global GitHub Packages и Nexus. Доступ к странице компонента не даёт права на распространение пакета или шрифтов.

Из этого руководства OpenDesign

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

  1. Прежде чем использовать нативный пакет, убедитесь, что у вас есть доступ к корпоративному реестру.
  2. Сверяйте документацию по компонентам с установленной версией.
  3. Используйте оригинальный пример HTML для изучения общедоступных материалов без закрытых зависимостей.

Прочитать вспомогательную спецификацию

Дизайн-система Maersk Сначала определите роль, а не узнавайте фирменный цвет

В светлой теме основное действие тёмное

Синий цвет Maersk узнаваем, но в светлой теме основная заливка — #141414, а текст на ней — белый. Для вторичной заливки используется #42B0D5 с тёмным текстом. Это различие не даёт всем элементам управления превратиться в яркие фирменные акценты.

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

Прочитать вспомогательную спецификацию

Дизайн-система Maersk Разделяйте характер заголовков и плотность основного текста

Используйте соответствующие пары размеров для настольных и мобильных устройств

Maersk Headline и Maersk Text выполняют разные задачи. Размер среднего заголовка меняется с 40/40 на настольных устройствах до 26/32 на мобильных, тогда как размер основного текста остаётся 16/24. Если масштабировать все стили текста на один и тот же процент, это намеренное различие будет утрачено.

В оригинальном предпросмотре используется Arial, поскольку файлы фирменных шрифтов не распространяются. Иерархия размеров соответствует документации: лёгкое начертание заголовка страницы, чёткие заголовки разделов и хорошо читаемые метаданные событий размером 14px. Справочные идентификаторы остаются выделяемым текстом, чтобы можно было проверить начальные нули и скопировать строку без изменений.

Прочитать вспомогательную спецификацию

Дизайн-система Maersk Плотность создаётся за счёт отступов, а не за счёт отсутствующей информации

Сохраняйте взаимосвязи элементов в компактном операционном интерфейсе

В MDS используется ритм отступов с шагом 4px и исключениями в 2, 6 и 10px для точного выравнивания компонентов. Токены плотности поддерживают режимы Default, Compact и Spacious, но не следует угадывать не подтверждённое значение плотности для конкретного пакета, ориентируясь лишь на эти названия.

В примере интервалы 8px и 16px объединяют подписи, события и метаданные; интервалы 24px и 32px разделяют более крупные области. На узких экранах маршрут и история событий располагаются друг под другом. Информация остаётся на месте и не исчезает ради более аккуратного скриншота.

Прочитать вспомогательную спецификацию

Дизайн-система Maersk Внешним контейнерам нужно пространство для внутренних элементов управления

Радиусы обозначают уровни вложенности

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

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

Прочитать вспомогательную спецификацию

Дизайн-система Maersk Номер отправления — это идентификатор, а не сумма

Не позволяйте полю ввода числа изменять идентификатор

В рекомендациях MDS по полям ввода количества отличают от идентификаторов, например номеров контейнеров и номеров отправлений. Поле числового ввода может удалить начальные нули или изменить значение при случайном нажатии на стрелку. Поэтому в примере используются type="text", inputmode="numeric" и точные строковые ключи.

Формат из шести цифр — ограничение исходного примера, а не спецификация номеров отправлений Maersk. Для пустого или неправильно оформленного ввода показывается отдельное сообщение с просьбой исправить значение; если формат верный, но запись не найдена, показывается отдельное сообщение об отсутствии совпадений. Эти ситуации нельзя сводить к расплывчатой ошибке «Недопустимое значение».

  • Расположите подпись над полем.
  • Сохраняйте все цифры идентификатора в виде строки.
  • Свяжите справку по формату и текст ошибки с помощью aria-describedby.
  • Устанавливайте aria-invalid только при ошибке формата, но не для записи с верным форматом, которая не найдена.

Прочитать вспомогательную спецификацию

Дизайн-система Maersk Отделите основной поиск от примеров для быстрого доступа

Используйте глаголы в повелительном наклонении, описывающие конкретный результат

«Показать отправление» — единственное основное действие с заливкой. Примеры номеров отправлений — действия с низким визуальным приоритетом: они подставляют тот же поисковый запрос, а не конкурируют друг с другом в качестве нескольких основных кнопок. В открытой форме основное действие должно предшествовать вспомогательному в порядке навигации с клавиатуры и чтения.

Предварительный просмотр показывает историю событий для выбранного примера в виде упорядоченного списка. Статус указан текстом в подписях событий, поэтому синий маркер и соединительная линия — лишь дополнительные элементы. Запись явно обозначена как вымышленная; информация о времени прибытия или маршруте не выдаётся за актуальные операционные данные.

Прочитать вспомогательную спецификацию

Дизайн-система Maersk Для тёмной темы нужны собственные семантические значения

Не инвертируйте скриншот

В общедоступной таблице для тёмной темы основной текст меняется на #F0F0F0, основная заливка — на белую, а нейтральный фон — на #141414. Это целенаправленное сопоставление ролей, а не указание инвертировать значения RGB повсеместно.

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

Прочитать вспомогательную спецификацию

Примеры компонентов дизайн-системы дизайн-система Maersk

Полноценный автономный интерактивный пример

Сохраните весь документ как index.html и откройте его в браузере. Оригинальная автономная реализация HTML использует документированные светлые роли и интервалы Maersk. Не требуются закрытая среда выполнения MDS, файлы фирменных шрифтов или подключение к актуальным данным отправлений.

html
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width"><title>Sample shipment lookup</title><style>*{box-sizing:border-box}body{font:16px/24px Arial,sans-serif;background:#f7f7f7;color:#141414;margin:0}button,input{font:inherit}button{cursor:pointer}button:focus-visible,input:focus-visible{outline:3px solid #0077b2;outline-offset:3px}header{background:#fff;padding:20px 32px;display:flex;justify-content:space-between;gap:16px;border-bottom:1px solid #d4d4d4}header b{font-weight:500;letter-spacing:1px}header span{font-size:12px;color:#6a6a6a}main{max-width:1120px;margin:auto;padding:32px}h1{font-size:40px;line-height:40px;font-weight:300;margin:8px 0 16px}p{margin:0 0 16px}.subtitle{color:#6a6a6a}.search{background:#fff;border:1px solid #d4d4d4;padding:24px;border-radius:12px;margin:24px 0}.search label{display:block;margin-bottom:8px}.entry{display:flex;gap:8px}.entry input{border:1px solid #8a8a8a;border-radius:6px;padding:12px 16px;max-width:360px;min-width:0;width:100%;background:#fff;color:#141414}.entry button{border:0;background:#141414;color:#fff;border-radius:6px;padding:12px 24px}.hint{font-size:14px;color:#6a6a6a;margin:8px 0 0}.error{color:#b80012;margin:8px 0 0}.error:empty{display:none}.layout{display:grid;grid-template-columns:250px 1fr;gap:24px}aside{background:#fff;border-radius:12px;border:1px solid #d4d4d4;padding:24px}aside h2{font-size:20px;line-height:24px;font-weight:400;margin:0 0 16px}.record{display:block;text-align:left;background:none;border:0;border-top:1px solid #e2e2e2;padding:16px 0;width:100%;color:#141414}.record strong,.record small{display:block}.record strong{font-size:16px;font-weight:500}.record small{color:#6a6a6a;font-size:12px;margin-top:4px}.record[aria-pressed=true]{color:#0077b2}.record[aria-pressed=true] strong:after{content:' →'}.detail{background:#fff;border:1px solid #d4d4d4;border-radius:12px;padding:24px;min-width:0}.detail h2{font-size:26px;line-height:32px;font-weight:400;margin:0}.topline{display:flex;justify-content:space-between;gap:16px;margin-bottom:20px}.tag{font-size:12px;border-radius:4px;background:#e2f3f9;color:#141414;padding:4px 8px;align-self:start;white-space:nowrap}.route{height:148px;border-radius:12px;background:#e2f3f9;display:flex;align-items:center;justify-content:space-between;padding:24px;position:relative;gap:16px}.port{position:relative;z-index:1;font-size:14px;max-width:40%}.port b{display:block;font-size:20px;line-height:24px;font-weight:400}.port:last-child{text-align:right}.route:before{content:'';height:2px;background:#42b0d5;position:absolute;left:24px;right:24px;top:52%}.port{background:#e2f3f9;padding:8px}.history{list-style:none;margin:24px 0 0;padding:0}.history li{position:relative;padding:0 0 24px 28px;border-left:2px solid #d4d4d4;margin-left:5px}.history li:last-child{padding-bottom:0;border-color:transparent}.history li:before{content:'';position:absolute;left:-6px;top:7px;width:10px;height:10px;background:#42b0d5;border-radius:50%}.history b{font-weight:500;display:block}.history small{font-size:14px;line-height:20px;color:#6a6a6a;display:block;margin-top:4px}.notice{padding:32px 0;max-width:430px}footer{font-size:12px;line-height:16px;color:#6a6a6a;margin-top:24px}@media(max-width:650px){header{padding:16px}header span{max-width:115px}main{padding:24px 16px}h1{font-size:26px;line-height:32px}.layout{grid-template-columns:1fr}aside{padding:16px}.record{padding:12px 0}.search,.detail{padding:20px}.entry{flex-wrap:wrap}.entry input{max-width:none}.entry button{width:100%}.topline{flex-wrap:wrap}.route{padding:8px}.port b{font-size:18px}.route:before{left:16px;right:16px}}
</style><header><b>CARGO / WORKSPACE</b><span>Independent MDS interpretation</span></header><main><h1>Follow the next milestone.</h1><p class="subtitle">A reference lookup and event history, using original sample records.</p><form id="lookup" class="search" novalidate><label for="reference">Shipment reference</label><div class="entry"><input id="reference" type="text" inputmode="numeric" value="000042" required aria-describedby="hint error"><button type="submit">Show shipment</button></div><p class="hint" id="hint">Try 000042 or 000108. Keep the leading zeros.</p><p class="error" id="error" role="alert"></p></form><div class="layout"><aside><h2>Sample shipments</h2><button class="record" data-id="000042" aria-pressed="true"><strong>000042</strong><small>Rotterdam → Singapore</small></button><button class="record" data-id="000108" aria-pressed="false"><strong>000108</strong><small>Hamburg → New York</small></button></aside><section class="detail" id="result" aria-live="polite"></section></div><footer>All references, routes and events are fictional. No live tracking, shipment status or transport commitment is represented.</footer></main><script>const data={'000042':{from:'Rotterdam',to:'Singapore',status:'In transit',events:[['Booking received','Sample milestone 1 · Reference created'],['Loaded at origin','Sample milestone 2 · Origin handling complete'],['In transit','Sample milestone 3 · Next event pending']]},'000108':{from:'Hamburg',to:'New York',status:'Awaiting handover',events:[['Booking received','Sample milestone 1 · Reference created'],['Awaiting origin handover','Sample milestone 2 · Cargo handover pending']]}};const input=document.querySelector('#reference'),result=document.querySelector('#result'),error=document.querySelector('#error');function resetError(){error.textContent='';input.setAttribute('aria-invalid','false')}function show(){resetError();const id=input.value.trim();document.querySelectorAll('.record').forEach(x=>x.setAttribute('aria-pressed',String(x.dataset.id===id)));result.replaceChildren();if(!/^\d{6}$/.test(id)){error.textContent='Use a six-digit sample reference, including leading zeros.';input.setAttribute('aria-invalid','true');input.focus();result.innerHTML='<p class="notice">Correct the reference to view a sample event history.</p>';return}const r=data[id];if(!r){result.innerHTML='<h2>No sample shipment found</h2><p class="notice">This reference does not match the two sample records. Try 000042 or 000108.</p>';return}result.innerHTML=`<div class="topline"><h2>Shipment ${id}</h2><span class="tag">${r.status}</span></div><div class="route"><div class="port"><small>ORIGIN</small><b>${r.from}</b></div><div class="port"><small>DESTINATION</small><b>${r.to}</b></div></div><ol class="history">${r.events.map(([a,b])=>`<li><b>${a}</b><small>${b}</small></li>`).join('')}</ol>`}document.querySelector('#lookup').onsubmit=e=>{e.preventDefault();show()};document.querySelectorAll('.record').forEach(x=>x.onclick=()=>{input.value=x.dataset.id;show()});input.oninput=()=>{resetError();document.querySelectorAll('.record').forEach(x=>x.setAttribute('aria-pressed','false'));result.innerHTML='<p class="notice">Select Show shipment to look up the edited reference.</p>'};show();</script></html>

Справочник по коду

  • Найти можно только включённые в пример номера отправлений. Точное сопоставление строк сохраняет идентификаторы; в документе нет закрытых компонентов Maersk и доступа к отслеживанию.

Сохраняйте номера отправлений как текст

Нативная форма соответствует рекомендациям MDS по полям ввода и использует общедоступные роли токенов. Точное сопоставление с данными примеров сохраняет начальные нули и позволяет отличить неверный формат от отсутствующей записи.

html
<!doctype html>
<html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width">
<title>Sample shipment lookup</title><style>
/* Local snapshot of documented Maersk light roles; not an MDS package import. */
:root{--mds_brand_appearance_primary_default_background-color:#141414;
--mds_brand_appearance_primary_default_on-background-color:#fff;
--mds_brand_appearance_neutral_default_border-color:#d4d4d4;
--mds_brand_appearance_secondary_weak_background-color:#e2f3f9}
body{font:16px/24px Arial,sans-serif;color:#141414;margin:32px}
main{max-width:48rem;margin:auto}label{display:block;margin-bottom:8px}
input,button{font:inherit;padding:12px 16px;border-radius:6px}
input{border:1px solid var(--mds_brand_appearance_neutral_default_border-color);max-width:100%;box-sizing:border-box}
button{border:0;background:var(--mds_brand_appearance_primary_default_background-color);color:var(--mds_brand_appearance_primary_default_on-background-color)}
.actions{display:flex;gap:8px;flex-wrap:wrap}li{padding:12px 0}#error{color:#b80012}#result{margin-top:24px;padding:24px;border-radius:12px;background:var(--mds_brand_appearance_secondary_weak_background-color)}
</style><main><h1>Find a sample shipment</h1>
<form id="lookup" novalidate><label for="reference">Shipment reference</label>
<p id="hint">Try 000042 or 000108. These are original sample records.</p>
<div class="actions"><input id="reference" type="text" inputmode="numeric" value="000042" aria-describedby="hint error" required>
<button type="submit">Show shipment</button></div><p id="error" role="alert"></p></form>
<section id="result" aria-live="polite"></section></main>
<script>
const shipments={'000042':{route:'Rotterdam → Singapore',events:['Booking received','Loaded at origin','In transit']},'000108':{route:'Hamburg → New York',events:['Booking received','Awaiting origin handover']}};
const input=document.querySelector('#reference'),result=document.querySelector('#result'),error=document.querySelector('#error');
function lookup(e){e.preventDefault();const id=input.value.trim();error.textContent='';input.setAttribute('aria-invalid','false');result.replaceChildren();
 if(!/^\d{6}$/.test(id)){error.textContent='Use a six-digit sample reference, including leading zeros.';input.setAttribute('aria-invalid','true');input.focus();return;}
 const record=shipments[id];if(!record){result.textContent='No sample shipment matches this reference. Try 000042 or 000108.';return;}
 const heading=document.createElement('h2');heading.textContent=id+' · '+record.route;
 const list=document.createElement('ol');record.events.forEach(x=>{const li=document.createElement('li');li.textContent=x;list.append(li)});
 result.append(heading,list);
}
document.querySelector('#lookup').addEventListener('submit',lookup);
input.addEventListener('input',()=>{error.textContent='';input.setAttribute('aria-invalid','false');result.replaceChildren();});
</script></html>

Справочник по коду

  • type="text" сохраняет цифры идентификатора; inputmode только предлагает подходящую клавиатуру.
  • Видимая подпись, постоянная подсказка и связанное с полем сообщение об ошибке выполняют разные задачи.
  • Этот код — оригинальная реализация, а не закрытый компонент Input из MDS API.
04

Настройка агента дизайн-система Maersk

Отправная точка для реализации

На общедоступной странице для разработчиков описан доступ к закрытому реестру. Точные импорты нативных компонентов и сигнатуры событий не выдумываются на основе недоступных фрагментов кода. Предоставленный HTML — законченная рабочая интерпретация общедоступных основ.

текст
Native MDS adoption (authorized Maersk teams):
1. Obtain access to Maersk Global GitHub Packages or the private Nexus registry.
2. Use the corporate authentication and SSO flow in the official developer guide.
3. Install the approved component or core package and its documented token/font dependencies.
4. Read exact component properties and events in the MDS Storybook for that installed release.

Public reference specimen:
Save the complete HTML example as index.html and open it in a browser.
It requires no registry, external script or private asset.
Its token declarations are a local light-theme snapshot; they do not initialize MDS Web Components.

Запрос для вашего проекта

Промпт для AI-агента
Создайте интерфейс поиска отправлений в духе Maersk, используя документированные светлые роли, тёмное основное действие, интервалы на основе 4px, скругление полей 6px и карточек 12px. Сохраняйте идентификаторы отправлений в виде текста, отличайте неверный формат от отсутствующей записи и показывайте историю событий в виде упорядоченного списка. Не выдумывайте доступ к общедоступным пакетам или API закрытых компонентов.
05

Дизайн-система Maersk Источники и область применения

Независимый справочник OpenDesign. Для работы с нативными пакетами MDS требуется авторизованный корпоративный доступ. Все идентификаторы отправлений, маршруты и события в предварительном просмотре — вымышленные примеры; сервис отслеживания не вызывается.