@hotelfriendag/design-tokens 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +20 -4
  2. package/package.json +1 -1
  3. package/README.uk.md +0 -377
package/README.md CHANGED
@@ -367,8 +367,14 @@ import { tokens } from '@hotelfriendag/design-tokens/tokens.ts';
367
367
  ### Publishing (maintainer)
368
368
 
369
369
  Releases are tag-triggered via `.github/workflows/release.yml` — push a `v*` tag
370
- and the workflow builds, validates, then `npm publish`-es to npmjs.com using
371
- the `NPM_TOKEN` repository secret. No manual `npm publish` step required.
370
+ and the workflow builds, validates, then `npm publish`-es to npmjs.com via
371
+ **Trusted Publishing (OIDC)**. No `NPM_TOKEN` secret, no PATs: GitHub Actions
372
+ mints a short-lived OIDC token that npm exchanges for publish credentials.
373
+
374
+ `--provenance` is NOT used: npmjs rejects sigstore provenance from private
375
+ source repositories, and this repo stays private (only the built artifact is
376
+ public — see RFC-0001 for the rationale). The trade is a missing attestation
377
+ badge on the npm page in exchange for keeping the source code private.
372
378
 
373
379
  ```bash
374
380
  # From the repo root, on main:
@@ -376,9 +382,19 @@ npm version patch # or minor / major → updates package.json,
376
382
  git push --follow-tags # workflow runs on the pushed tag and publishes
377
383
  ```
378
384
 
379
- The `prepublishOnly` script re-runs the generator + validator so the published package is always self-consistent. If you need to publish manually from a local machine (bootstrap or hotfix), `pnpm publish` works the same way after `pnpm version <bump>` (you'll need to be logged in: `npm login` first).
385
+ The `prepublishOnly` script re-runs the generator + validator so the published package is always self-consistent. If you need to publish manually from a local machine (hotfix), `npm publish` works the same way after `npm version <bump>` and `npm login` but Trusted Publishing is the canonical path.
386
+
387
+ The Trusted Publisher binding on npmjs (Package → Settings → Trusted publishing) is configured for:
388
+
389
+ | Field | Value |
390
+ |---|---|
391
+ | Organization | `HotelFriendAG` |
392
+ | Repository | `design-system` |
393
+ | Workflow filename | `release.yml` |
394
+
395
+ Changing the workflow filename, repo name, or org requires updating the npmjs binding before the next release will succeed.
380
396
 
381
- > Historical: versions `0.2.x` were briefly published to GitHub Packages while the registry decision was pending. `0.3.0+` is published exclusively to npmjs.com; consumers should install from there.
397
+ > Historical: versions `0.2.x` were briefly published to GitHub Packages while the registry decision was pending. `0.3.0+` is published exclusively to npmjs.com; consumers should install from there. `0.3.0` itself was bootstrapped by a one-time manual publish from a maintainer's machine using a short-lived Granular Access Token (since Trusted Publishing requires the package to already exist on npm). The token was revoked immediately after; all subsequent versions use OIDC.
382
398
 
383
399
  ## Changelog
384
400
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hotelfriendag/design-tokens",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "HotelFriend Design System — portable bundle (tokens, components, AI rules). Three-tier model per RFC-0002.",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
package/README.uk.md DELETED
@@ -1,377 +0,0 @@
1
- # HotelFriend Design System
2
-
3
- Спільна дизайн-основа для всіх проєктів: токени, згенеровані файли під кожен стек (CSS / SCSS / TS / Tailwind v3 + v4 / shadcn), шар компонентів `.hf-*` та правила для AI-інструментів.
4
-
5
- > **Виокремлено 2026-05-25** із [`hotelfriend/backend-hf`](https://bitbucket.org/hotelfriend/backend-hf) (`docs/portable-design/`), щоб цей репозиторій став єдиним джерелом істини для решти проєктів HotelFriend.
6
- >
7
- > **Статус:** RFC-0001 Фаза 1 завершена (семантична трирівнева модель + префіксація без колізій + CI-гейт на дрейф). Наступний крок — версійований npm-пакет (`@hotelfriend/design-tokens` через GitHub Packages). Повний чек-лист — у `RFC-0001-cross-project-design-system.md` §9.
8
-
9
- ## Ієрархія файлів (читати в цьому порядку)
10
-
11
- ```
12
- portable-design/
13
-
14
- ├── components.html ← ОСНОВНЕ · канонічний візуальний референс (відкрити у браузері)
15
- ├── UI_DESIGN.md ← НАРАТИВ · обґрунтування, анатомія, рішення (AI читає це першим)
16
- ├── tokens.figma.json ← ТОКЕНИ · атомарний експорт Tokens Studio → живить Figma + генератори
17
-
18
- ├── pre-built/ ← ЗГЕНЕРОВАНІ · підставляєте у свій білд-пайплайн
19
- │ ├── tailwind.css · Tailwind v4 @theme-блок (рекомендовано)
20
- │ ├── tailwind.preset.js · Tailwind v3 preset (легасі)
21
- │ ├── tokens.css · звичайні CSS custom properties
22
- │ ├── _tokens.scss · SCSS-змінні
23
- │ ├── tokens.ts · TypeScript const
24
- │ ├── shadcn-tokens.css · контракт shadcn/ui
25
- │ └── components.css · примітиви `.hf-*` (витяг із components.html)
26
-
27
- ├── states-canonical.json ← курований набір інтерактивних станів (використовуйте цей)
28
- ├── states.json ← сирий експорт із порталу (160 КБ — краще брати states-canonical.json)
29
- ├── generate-tokens.cjs ← Node-скрипт (без залежностей) — перетворює токени на Tailwind/CSS/SCSS/TS/shadcn
30
-
31
- ├── ai-rules/ ← покладіть ОДИН файл у корінь нового проєкту
32
- │ ├── CLAUDE.md · для Claude Code (підхоплюється автоматично)
33
- │ ├── cursorrules.template · перейменуйте на .cursorrules
34
- │ ├── github-copilot-instructions.md · покласти в .github/copilot-instructions.md
35
- │ └── system-prompt-compact.md · компактний промпт для ChatGPT/v0/Lovable
36
-
37
- ├── portal-audit.html ← АРХІВ · знімок аудиту старого порталу (НЕ для нового коду)
38
- └── README.md ← ви тут (швидкий старт)
39
- ```
40
-
41
- ### Правило пріоритету — коли файли суперечать одне одному
42
-
43
- 1. **`components.html`** — канон для **візуальних рішень** (кольори, розміри, анатомія)
44
- 2. **`tokens.figma.json`** — канон для **значень токенів**. Після редагування — перегенеруйте `pre-built/*`
45
- 3. **`UI_DESIGN.md`** — канон для **ЧОМУ було прийнято рішення** (історія, компроміси, нотатки про дрейф порталу)
46
- 4. **`pre-built/*`** — **згенеровані**, руками не правити. Після зміни JSON запускайте `generate-tokens.cjs`
47
- 5. **`portal-audit.html`** — **тільки архів**. Показує поточний вигляд легасі-порталу — корисно для трекінгу міграції, НЕ для нового UI
48
-
49
- Якщо `components.html` і `UI_DESIGN.md` суперечать одне одному — **виграє `components.html`**, а `UI_DESIGN.md` вважається застарілим.
50
-
51
- ## Швидкий старт за 60 секунд
52
-
53
- ```bash
54
- # 1. Скопіювати цю папку у новий проєкт (куди завгодно; рекомендуємо docs/)
55
- cp -r /path/to/portable-design ../new-project/docs/
56
-
57
- # 2. Підключити CSS у білд (оберіть ОДНЕ)
58
- # Tailwind v4: @import pre-built/tailwind.css
59
- # Vanilla CSS: підключити tokens.css + components.css
60
- # SCSS: @import _tokens.scss
61
-
62
- # 3. Підключити AI до правил системи (оберіть ОДНЕ)
63
- cp docs/portable-design/ai-rules/CLAUDE.md ../../CLAUDE.md # Claude Code
64
- cp docs/portable-design/ai-rules/cursorrules.template ../../.cursorrules
65
- mkdir -p ../../.github && cp docs/portable-design/ai-rules/github-copilot-instructions.md ../../.github/copilot-instructions.md
66
- ```
67
-
68
- ## ⚠️ Інтеграція у наявний проєкт
69
-
70
- > **Статус:** ✅ Вирішено у Фазі 1A (RFC-0001 §4.2). Усі згенеровані токени мають префікс `hf-` ВСЕРЕДИНІ категорії (`--color-hf-*`, `--text-hf-*`, `--radius-hf-*`, `--spacing-hf-*`, `--font-hf-*`, `--shadow-hf-*`). Жоден не може зіткнутися з дефолтами Tailwind v4. Повний `@import` у наявному проєкті — безпечний.
71
-
72
- **Рекомендована конфігурація для будь-якого проєкту (новий чи наявний):**
73
-
74
- ```css
75
- /* app/globals.css */
76
- @import "tailwindcss";
77
- @import "./docs/portable-design/pre-built/tailwind.css"; /* @theme — додає --color-hf-*, --text-hf-* тощо */
78
- @import "./docs/portable-design/pre-built/components.css"; /* примітиви .hf-* */
79
-
80
- /* Опційно: виключити демо-HTML із пакета зі сканування Tailwind,
81
- щоб легасі-класи / bg-[#hex] із showcase не потрапили у ваш бандл. */
82
- @source not "./docs/portable-design/components.html";
83
- @source not "./docs/portable-design/portal-audit.html";
84
- ```
85
-
86
- Що ви отримуєте:
87
-
88
- - `bg-hf-accent` (= `#24AFE8` — бренд) — `bg-blue-500` із Tailwind лишається дефолтним
89
- - `text-hf-base` (= 14px — основний текст) — `text-base` із Tailwind лишається 16px
90
- - `rounded-hf-sm` (= 6px) — `rounded-sm` із Tailwind лишається 2px
91
- - `shadow-hf-modal` (= тінь модалки порталу)
92
- - … тощо. Ваші наявні утиліти **не змінюються**.
93
-
94
- **Для проєктів, чиї інтеграційні скрипти просять "additive"-таргет за назвою**, `--target=tailwind-v4-additive` — явний alias для `--target=tailwind-v4`. Вихідний файл ідентичний — префікс зробив additive-фільтр непотрібним.
95
-
96
- ```bash
97
- node generate-tokens.cjs --target=tailwind-v4-additive > pre-built/tailwind.additive.css
98
- # (байт-у-байт як --target=tailwind-v4)
99
- ```
100
-
101
- ## Сніпети під конкретні стеки
102
-
103
- ### React + Tailwind v4 (рекомендовано, новий проєкт)
104
-
105
- ```css
106
- /* app/globals.css */
107
- @import "tailwindcss";
108
- @import "./docs/portable-design/pre-built/tailwind.css"; /* @theme токени */
109
- @import "./docs/portable-design/pre-built/components.css"; /* примітиви .hf-* */
110
- ```
111
-
112
- ```jsx
113
- <button className="bg-hf-primary hover:bg-hf-primary-hover text-white h-10 px-5 rounded-hf text-hf-md font-semibold">
114
- Зберегти
115
- </button>
116
- <span className="hf-pill status-booking-confirmed">Підтверджено</span>
117
- <div className="hf-modal max-w-[500px]">
118
- <div className="hf-modal__header">
119
- <h2 className="hf-modal__title">Редагувати гостя</h2>
120
- <button className="hf-modal__close">✕</button>
121
- </div>
122
- <div className="hf-modal__body">…</div>
123
- <div className="hf-modal__footer"><button>Скасувати</button><button>Зберегти</button></div>
124
- </div>
125
- ```
126
-
127
- ### React + Tailwind v3 (легасі)
128
-
129
- ```js
130
- // tailwind.config.js
131
- const hfPreset = require('./docs/portable-design/pre-built/tailwind.preset.js');
132
- module.exports = {
133
- presets: [hfPreset],
134
- content: ['./app/**/*.{ts,tsx}', './components/**/*.{ts,tsx}'],
135
- };
136
- ```
137
-
138
- ```html
139
- <link rel="stylesheet" href="docs/portable-design/pre-built/components.css">
140
- ```
141
-
142
- ### Next.js + shadcn/ui
143
-
144
- Допишіть `pre-built/shadcn-tokens.css` у `app/globals.css`. Компоненти shadcn автоматично підхоплять `--primary`, `--background`, `--ring` тощо.
145
-
146
- ### Vue 3 / Nuxt
147
-
148
- ```ts
149
- // nuxt.config.ts
150
- export default defineNuxtConfig({
151
- css: [
152
- '~/docs/portable-design/pre-built/tokens.css',
153
- '~/docs/portable-design/pre-built/components.css',
154
- ],
155
- });
156
- ```
157
-
158
- У шаблонах використовуйте `var(--color-hf-accent)`, `var(--font-size-hf-base)` або `.hf-modal` / `.hf-pill .status-booking-confirmed`.
159
-
160
- ### SCSS-стек (Yii / Laravel / WP)
161
-
162
- ```scss
163
- // _app.scss
164
- @import 'docs/portable-design/pre-built/tokens';
165
- @import 'docs/portable-design/pre-built/components.css';
166
-
167
- .my-btn {
168
- background: $colorPrimaryDefault;
169
- height: $sizeBtnDefault;
170
- border-radius: $borderRadiusSm;
171
- }
172
- ```
173
-
174
- ### TS / CSS-in-JS
175
-
176
- ```ts
177
- import { tokens } from './docs/portable-design/pre-built/tokens';
178
-
179
- const Button = styled.button`
180
- background: ${tokens.color.primary.default};
181
- height: ${tokens.size.btnDefault};
182
- border-radius: ${tokens.borderRadius.sm};
183
- `;
184
- ```
185
-
186
- ### Ванільний / статичний HTML
187
-
188
- ```html
189
- <link rel="stylesheet" href="docs/portable-design/pre-built/tokens.css">
190
- <link rel="stylesheet" href="docs/portable-design/pre-built/components.css">
191
-
192
- <span class="hf-pill status-booking-confirmed">Підтверджено</span>
193
- <button class="hf-modal__close">✕</button>
194
- ```
195
-
196
- ## Примітиви компонентів у `components.css`
197
-
198
- | Клас | Анатомія | Дивись |
199
- |---|---|---|
200
- | `.hf-pill` + `.status-{domain}-{state}` | Статус-бейдж — радіус 6px, фон 15% + текст 100% + рамка 1px | components.html#status |
201
- | `.hf-tab` / `.hf-tab--sm` / `.hf-pill-tabs` | Таби з підкресленням та сегментовані | components.html#tabs |
202
- | `.hf-pagination` + `__item` / `__ellipsis` | Активний — стриманий сірий (НЕ primary!) — 34×34, радіус 8px | components.html#pagination |
203
- | `.hf-modal` + `__header/__title/__body/__footer/__close` | Радіус 6px, у футера немає верхньої рамки | components.html#modal |
204
- | `.hf-alert` + `--success/--info/--warn/--error` | Білий фон + 3px акцентна смуга зверху + квадратна іконка 26×26 | components.html#alerts |
205
- | `.hf-alert--tinted` / `--banner` / `--compact` | Модифікатори — тонований фон / на всю ширину / компактний у картці | components.html#alerts |
206
- | `.hf-toast` | Плаваюче сповіщення (правий нижній кут) — радіус 9px | components.html#alerts |
207
- | `.hf-check` / `.hf-radio` | Кастомні чекбокс та радіо — 18×18, активний — заливка primary | components.html#inputs |
208
- | `.hf-dropdown-menu` + `__item / __header / __shortcut / __icon / __divider` | Дропдаун з радіусом 9px та тінню `0 1px 10px rgba(0,0,0,.1)` | components.html#dropdown |
209
- | `.skeleton` + `.hf-spin` | Примітиви станів завантаження (шимер + обертання) | components.html#empty |
210
-
211
- ## Як цим користується AI
212
-
213
- Після того як ви поклали один із файлів `ai-rules/*` у корінь нового проєкту:
214
-
215
- 1. **Claude Code / Cursor / Copilot** автоматично додають його до кожного чату. Агент знає:
216
- - канонічну палітру (primary `#24AFE8`, кольори статусів, нейтральні)
217
- - типографіку (Roboto, розміри 11/13/14/15/16/18/20/22/26/30, ваги 400/500/600)
218
- - шкалу відступів (кратно 4)
219
- - шкалу радіусів (6/8/9/12/99)
220
- - набір тіней (default/subtle/wrapper/card/modal/outline/hover)
221
- - бібліотеку компонентів (`.hf-modal`, `.hf-alert`, `.hf-pill`, `.hf-tab`, `.hf-pagination`, `.hf-check`, `.hf-dropdown-menu` тощо)
222
- - жорсткі правила ("ніколи не зашивати hex", "завжди робити hover/focus/disabled", "не мішати іконкові набори")
223
-
224
- 2. **Візуальний референс для нових проєктів:** відкрийте `components.html` у браузері — це канон, де відрендерені всі патерни `.hf-*`.
225
-
226
- 3. **Для чат-AI** (ChatGPT, v0, Lovable): вставте `ai-rules/system-prompt-compact.md` або JSON-довідник токенів із `UI_DESIGN.md` §9 як system prompt перед запитом UI-завдання.
227
-
228
- ## Оновлення згенерованих файлів
229
-
230
- Коли змінюється `tokens.figma.json`, перегенеруйте:
231
-
232
- ```bash
233
- cd docs/portable-design
234
- node generate-tokens.cjs --target=tailwind-v4 > pre-built/tailwind.css # v4 (рекомендовано)
235
- node generate-tokens.cjs --target=tailwind > pre-built/tailwind.preset.js # v3 (легасі)
236
- node generate-tokens.cjs --target=css > pre-built/tokens.css
237
- node generate-tokens.cjs --target=scss > pre-built/_tokens.scss
238
- node generate-tokens.cjs --target=ts > pre-built/tokens.ts
239
- node generate-tokens.cjs --target=shadcn > pre-built/shadcn-tokens.css
240
- ```
241
-
242
- > `pre-built/components.css` поки **не генерується** — він вручну витягнутий із `components.html`. Якщо ви змінюєте блок `<style type="text/tailwindcss">` / `@layer components` у `components.html`, синхронізуйте витягнутий файл вручну. Заголовок `pre-built/components.css` містить координати джерела.
243
-
244
- Або вбудуйте регенерацію в `package.json`:
245
-
246
- ```json
247
- {
248
- "scripts": {
249
- "tokens:build:v4": "node docs/portable-design/generate-tokens.cjs --target=tailwind-v4 > tailwind.css",
250
- "tokens:build:v3": "node docs/portable-design/generate-tokens.cjs --target=tailwind > tailwind.preset.js",
251
- "prebuild": "npm run tokens:build:v3 && npm run tokens:build:v4"
252
- }
253
- }
254
- ```
255
-
256
- ## Чек-ліст валідації
257
-
258
- Після перенесення у новий проєкт перевірте:
259
-
260
- - [ ] `cat CLAUDE.md` (або `.cursorrules`) показує правила дизайн-системи.
261
- - [ ] `node docs/portable-design/generate-tokens.cjs --target=css` відпрацьовує чисто і дає стабільний вивід.
262
- - [ ] AI-агент на питання "який primary color?" відповідає `#24AFE8`.
263
- - [ ] Перша згенерована AI кнопка відповідає `.btn-primary` (40px / 15px / 600 / `#24AFE8` / радіус 6px).
264
- - [ ] Бейджі статусів резолвляться через токени `--status-{domain}-{state}-color`.
265
- - [ ] `.hf-modal`, `.hf-alert`, `.hf-pagination` рендеряться коректно, коли підвантажений `pre-built/components.css`.
266
-
267
- ## Що НЕ переноситься
268
-
269
- Ці файли у батьківському `docs/` — **специфічні для порталу HotelFriend** (легасі-аудит / детект дрейфу), копіювати їх НЕ треба:
270
-
271
- - `docs/migration-plan.md` — черга прибирання старого SCSS (тільки портал на Yii)
272
- - `docs/design-tokens-audit.md` — звіт про дрейф
273
- - `docs/ui-elements-catalog.*` — спостережені компоненти у порталі
274
- - `docs/icon-audit.*` — карта міграції FA→Lucide
275
- - `docs/component-anatomy.json` — обміри легасі-модалок
276
- - `scratch/` — Playwright-воркери, що сканують портал
277
-
278
- Вони лежать у вихідному репо для господарських потреб; новому проєкту вони не потрібні.
279
-
280
- `portal-audit.html` всередині цього пакета — єдиний легасі-артефакт, що подорожує разом із portable-папкою — залиште його як історичний референс і для трекінгу міграції. Новий код **ніколи** не повинен копіювати патерни з `portal-audit.html`.
281
-
282
- ---
283
-
284
- ## Детект дрейфу та інтеграція з CI
285
-
286
- ### Pre-commit hook (рекомендовано для будь-якого проєкту, що чіпає цей пакет)
287
-
288
- ```bash
289
- # З husky (рекомендовано)
290
- pnpm add -D husky
291
- pnpm husky init
292
- cp docs/portable-design/scripts/pre-commit.sh .husky/pre-commit
293
- chmod +x .husky/pre-commit
294
-
295
- # Без husky (сирий git-hook)
296
- cp docs/portable-design/scripts/pre-commit.sh .git/hooks/pre-commit
297
- chmod +x .git/hooks/pre-commit
298
- ```
299
-
300
- Хук запускає `validate-tokens.cjs`, коли в staging є будь-які файли з tokens / pre-built / docs / components.html. Падає на дрейфі. Мовчить на успіху.
301
-
302
- ### Конфіг Stylelint (рекомендовано для проєктів-споживачів)
303
-
304
- Сумісний Stylelint-конфіг, який забороняє сирий hex / іменовані кольори / літеральні `box-shadow`:
305
-
306
- ```js
307
- // .stylelintrc.cjs
308
- module.exports = {
309
- extends: [
310
- 'stylelint-config-standard',
311
- './node_modules/@hotelfriend/design-tokens/pre-built/stylelint-design-system.cjs'
312
- // — або, якщо підключено через копіювання папки:
313
- // './docs/portable-design/pre-built/stylelint-design-system.cjs'
314
- ],
315
- overrides: [
316
- // У згенерованих файлах hex допустимий (fallback-и, примітиви) — opt-out
317
- { files: ['**/pre-built/*.css'], rules: { 'color-no-hex': null } },
318
- ],
319
- };
320
- ```
321
-
322
- ### Самостійний валідатор (одноразова перевірка у CI)
323
-
324
- ```bash
325
- cd docs/portable-design
326
- node scripts/validate-tokens.cjs
327
- # ✓ validate-tokens: all checks passed
328
- # 168 CSS variables defined, all var() refs resolve, no bare hex.
329
- ```
330
-
331
- Використовуйте у CI поруч із лінтом та тестами. Виходить із ненульовим кодом, якщо:
332
- 1. `var(--*)` посилається на CSS-змінну, яка ніде не визначена
333
- 2. У `components.css` / `status.css` є сирий hex (поза коментарями та fallback-ами `var()`; `#fff`/`#000` дозволені)
334
- 3. У код-блоці документації згадано токен, якого нема в `pre-built/*`
335
-
336
- ## NPM-пакет (приватний реєстр)
337
-
338
- Пакет публікується як `@hotelfriend/design-tokens` у приватний реєстр GitHub Packages:
339
-
340
- ```bash
341
- # У проєкті-споживачі:
342
- echo "@hotelfriend:registry=https://npm.pkg.github.com" >> .npmrc
343
- pnpm add @hotelfriend/design-tokens
344
- ```
345
-
346
- Імпорт під свій стек:
347
-
348
- ```css
349
- /* CSS / Tailwind v4 */
350
- @import "@hotelfriend/design-tokens/tailwind.css";
351
- @import "@hotelfriend/design-tokens/components.css";
352
- @import "@hotelfriend/design-tokens/status.css";
353
- ```
354
-
355
- ```ts
356
- // TypeScript
357
- import { tokens } from '@hotelfriend/design-tokens/tokens.ts';
358
- ```
359
-
360
- ```scss
361
- // SCSS
362
- @import '@hotelfriend/design-tokens/_tokens';
363
- ```
364
-
365
- ### Публікація (для мейнтейнера)
366
-
367
- ```bash
368
- cd docs/portable-design
369
- pnpm version patch # або minor / major
370
- pnpm publish # запускає prepublishOnly → build + validate
371
- ```
372
-
373
- `prepublishOnly` перезбирає та валідує, тож опублікований пакет завжди узгоджений.
374
-
375
- ---
376
-
377
- Зібрано на основі HotelFriend Design System v0.1.0 — JSON-довідник токенів див. у `UI_DESIGN.md` §9, канонічний візуальний референс — у `components.html`. Англомовна версія цього файлу — [`README.md`](README.md), повний журнал фаз і змін — там же.