Агентный слой
Реплика
Один шаг обмена. Всё остальное в этом слое показывает работу; реплика — то, внутри чего работа происходит: ответ это не абзац, а контейнер для шагов, диффа, запроса разрешения и бюджета.
Вы14:02
Добавь полосу долей над лентой истории.
Агент14:02
Поставлю её над лентой и дам одной легенде ключевать обе.
Разметка
<div class="inst-stack inst-stack--loose">
<div class="inst-turn" data-from="user">
<div class="inst-turn-head"><span class="inst-turn-who">Вы</span><span>14:02</span></div>
<div class="inst-turn-body">Добавь полосу долей над лентой истории.</div>
</div>
<div class="inst-turn">
<div class="inst-turn-head"><span class="inst-turn-who">Агент</span><span>14:02</span></div>
<div class="inst-turn-body">Поставлю её над лентой и дам одной легенде ключевать обе.</div>
<div class="inst-turn-actions">
<button class="inst-btn inst-btn--xs inst-btn--icon inst-btn--ghost" type="button" aria-label="Копировать"><svg class="inst-icon" aria-hidden="true"><use href="#i-copy"/></svg></button>
<button class="inst-btn inst-btn--xs inst-btn--icon inst-btn--ghost" type="button" aria-label="Повторить"><svg class="inst-icon" aria-hidden="true"><use href="#i-refresh"/></svg></button>
<button class="inst-btn inst-btn--xs inst-btn--icon inst-btn--ghost" type="button" aria-label="Ещё"><svg class="inst-icon" aria-hidden="true"><use href="#i-more"/></svg></button>
</div>
</div>
</div>
Контракт
| Что | Обязательно | Почему |
|---|---|---|
data-from="user" у реплики человека |
да | Реплика машины — умолчание. Помечать обе значило бы завести значение атрибута, которому нечего объявлять |
Имя в inst-turn-who |
да | Цвет и отступ не носители: утопление — одна и та же плёнка в любой теме, а скринридер не получает ни того ни другого |
| Время | нет | Полезно в длинной ветке, шум в короткой |
inst-turn-actions держит место |
да, если они есть | Наведение может усилить элемент, но не может вызвать его к жизни. Ряд размечен в любом случае, поэтому под курсором ничто не сдвигается: кнопки проявляются, а @media (hover: none) отдаёт их в полную силу там, где курсора нет. Ряд, которого нет в разметке вовсе, на сенсорном экране не существует |
| Ветка как список | нет | Реплики — соседи в inst-stack--loose; второго имени для колонки кит не заводит |
Реплика человека утоплена, у реплики машины поверхности нет вовсе: именно она держит шаги, диффы и запросы разрешения, и каждый из них приносит собственную рамку. Поверхность под ними положила бы плашку внутрь плашки.
Доступность
| Кто говорит | Назван текстом, а не поверхностью. Утопление — оформление, и до вспомогательных технологий оно не доходит |
| Поток | Ещё идущий ответ несёт каретку; объявлением служит сам текст |
| Действия | Настоящие кнопки с подписями. Они стоят в потоке, поэтому Tab доходит до них в порядке чтения |
Композиции
Ответ, который сделал работу
Агент14:02
Добавил, легенда теперь расшифровывает тона.
edit src/data.css
.inst-share { display: flex; }
Разметка
<div class="inst-turn">
<div class="inst-turn-head"><span class="inst-turn-who">Агент</span><span>14:02</span></div>
<div class="inst-turn-body">Добавил, легенда теперь расшифровывает тона.</div>
<details class="inst-step" open>
<summary class="inst-step-head">
<span class="inst-step-twist"></span>
<span class="inst-dot" data-tone="ok"></span>
<span class="inst-step-name">edit</span>
<span class="inst-step-sub">src/data.css</span>
<span class="inst-step-meta">0.4 с</span>
</summary>
<div class="inst-step-body">
<div class="inst-code">.inst-share { display: flex; }</div>
</div>
</details>
<div class="inst-turn-actions">
<button class="inst-btn inst-btn--xs inst-btn--ghost" type="button">Копировать</button>
<button class="inst-btn inst-btn--xs inst-btn--ghost" type="button">Повторить</button>
</div>
</div>
API
| Имя | Что делает |
|---|---|
| класс | |
inst-turn | Один шаг обмена |
inst-turn-head | Кто и когда, кеглем метаданных |
inst-turn-who | Имя в этой строке |
inst-turn-body | Что сказано. Может держать любой компонент этого слоя |
inst-turn-actions | Копировать, повторить, ветвить. Ряд всегда занимает своё место; кнопки проявляются под курсором и стоят в полную силу там, где курсора нет |
| Имя | Значение | Что делает |
|---|---|---|
| атрибут | ||
data-from | user | Реплика человека, и только она: она утоплена, реплика машины — умолчание, без поверхности |
| Имя | Значение | Откуда |
|---|---|---|
| токен | ||
--surface-recessed | light-dark(oklch(0 0 0 / 0.060), oklch(1 0 0 / 0.050)) | одно на все ячейки |
--radius-lg | 12px | база +4: масштаб |
--pad-panel | var(--space-5) | база +14: плотность · масштаб |
--space-3 | 6px | одно на все ячейки |
--text-xs | 0.78125rem | база +4: масштаб |
--text-muted | light-dark(var(--n-8), var(--n-6)) | одно на все ячейки |
--text-secondary | light-dark(var(--n-9), var(--n-5)) | одно на все ячейки |
--weight-medium | 600 | одно на все ячейки |
--leading-ui | 1.4 | одно на все ячейки |
Почему кит устроен именно так — конституция · Открытый код под MIT, github.com/keshon/instrument