Изучите язык операционного интерфейса Maersk на примере настоящих ролей светлой темы, шкал заголовков и основного текста, вложенных скруглений и обработки идентификаторов. Пример поиска отправления показывает точное совпадение по номеру и доступную историю событий, не создавая впечатления доступа к данным текущей логистики.
Оригинальная автономная интерпретация на нативном HTML с использованием документированных светлых ролей и отступов Maersk. Без закрытой среды выполнения MDS, файлов фирменных шрифтов и подключения к актуальным данным об отправлениях. · Справочник по реализации
02
Дизайн-система Maersk Справочник по дизайну
Общедоступная основа MDS и документация по использованию компонентов. Нативные пакеты компонентов доступны в закрытых реестрах Maersk; в работающем примере используются нативный HTML и документированный снимок токенов, а не выдуманные API mc-*.
Дизайн-система Maersk Общедоступные правила и закрытые компоненты — разные ресурсы
Честно выбирайте способ внедрения
MDS предоставляет широкую документацию по основе и использованию компонентов в открытом доступе, однако в руководстве для разработчиков указано, что пакеты размещены в закрытых реестрах Maersk Global GitHub Packages и Nexus. Доступ к странице компонента не даёт права на распространение пакета или шрифтов.
Авторизованным командам следует использовать пакеты и Storybook, соответствующие их корпоративной среде. В этом общедоступном справочнике вместо этого приведена полная оригинальная реализация видимых правил на нативном HTML, чтобы поведение можно было изучить без вымышленной публичной команды установки.
Прежде чем использовать нативный пакет, убедитесь, что у вас есть доступ к корпоративному реестру.
Сверяйте документацию по компонентам с установленной версией.
Используйте оригинальный пример 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 повсеместно.
В этом примере используется документированная светлая тема. Чтобы добавить тёмную тему, необходимо согласованно заменить весь набор ролей, включая цвета при наведении, границ и текста на фоне. Для исходной схемы маршрута также потребуется отдельная проверка контрастности — она не должна автоматически наследовать глобальный фильтр.
Сохраните весь документ как 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 требуется авторизованный корпоративный доступ. Все идентификаторы отправлений, маршруты и события в предварительном просмотре — вымышленные примеры; сервис отслеживания не вызывается.