@hotelfriendag/design-tokens 0.3.0

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.
@@ -0,0 +1,3018 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>HotelFriend — Component Reference</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;600&display=swap" rel="stylesheet">
8
+ <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
9
+
10
+ <style type="text/tailwindcss">
11
+ @import "tailwindcss";
12
+
13
+ /* ═══════════════════════════════════════════════════════════════════════════
14
+ components.html @theme — Phase 2D reconciliation (RFC-0002).
15
+ The CANONICAL tokens below mirror pre-built/tailwind.css (hf-prefixed,
16
+ three-tier). The LEGACY ALIASES below them keep this demo's existing
17
+ Tailwind class refs (bg-primary, text-ink, etc.) working so the markup
18
+ does not need a 500+ class rewrite.
19
+
20
+ For new code, use the hf-prefixed names (bg-hf-accent, text-hf-fg, ...).
21
+ The legacy names are kept ONLY for this demo's continuity.
22
+ ═══════════════════════════════════════════════════════════════════════════ */
23
+ @theme {
24
+ /* ── Font ── */
25
+ --font-hf-sans: 'Roboto', sans-serif;
26
+ --font-sans: 'Roboto', sans-serif; /* legacy alias */
27
+
28
+ /* ── Font sizes — canonical (hf-prefixed) ── */
29
+ --text-hf-xs: 11px;
30
+ --text-hf-sm: 13px;
31
+ --text-hf-base: 14px;
32
+ --text-hf-md: 15px;
33
+ --text-hf-lg: 16px;
34
+ --text-hf-xl: 18px;
35
+ --text-hf-2xl: 20px;
36
+ --text-hf-h2: 24px;
37
+ --text-hf-page: 26px;
38
+ --text-hf-hero: 30px;
39
+
40
+ /* ── Font sizes — legacy aliases (demo continuity) ── */
41
+ --text-caption: var(--text-hf-xs);
42
+ --text-meta: var(--text-hf-sm);
43
+ --text-body: var(--text-hf-base);
44
+ --text-action: var(--text-hf-md);
45
+ --text-heading: var(--text-hf-xl);
46
+ --text-title: 22px; /* between xl(18) and 2xl(20) — kept direct, no semantic */
47
+ --text-page: var(--text-hf-page);
48
+
49
+ /* ── Colors — PRIMITIVES (Phase 1B) ── */
50
+ --color-hf-blue-50: #E9F6FC;
51
+ --color-hf-blue-100: #EFF6FF;
52
+ --color-hf-blue-500: #24AFE8;
53
+ --color-hf-blue-600: #149AD1;
54
+ --color-hf-gray-25: #FBFBFC;
55
+ --color-hf-gray-50: #F6F7FB;
56
+ --color-hf-gray-100: #F1F3F6;
57
+ --color-hf-gray-200: #E4E8EF;
58
+ --color-hf-gray-300: #D1D6DD;
59
+ --color-hf-gray-400: #AEBCCF;
60
+ --color-hf-gray-500: #99A1B7;
61
+ --color-hf-gray-550: #7E8EA6;
62
+ --color-hf-gray-600: #50627E;
63
+ --color-hf-gray-700: #485B78;
64
+ --color-hf-gray-800: #4B5675;
65
+ --color-hf-gray-900: #2B2B2B;
66
+ --color-hf-gray-950: #252F4A;
67
+ --color-hf-green-500: #59B59D;
68
+ --color-hf-amber-400: #FFBD5A;
69
+ --color-hf-amber-600: #FFC900;
70
+ --color-hf-red-400: #EA6565;
71
+ --color-hf-red-500: #FB5A56;
72
+ --color-hf-red-700: #D9534F;
73
+ --color-hf-orange-500: #F87921;
74
+ --color-hf-orange-700: #A55505;
75
+ --color-hf-violet-500: #5761D8;
76
+ --color-hf-slate-500: #7F8FA4;
77
+ --color-hf-olive-700: #5B7A02;
78
+ --color-hf-white: #FFFFFF;
79
+ --color-hf-black: #000000;
80
+
81
+ /* ── Colors — SEMANTIC accent ── */
82
+ --color-hf-accent: var(--color-hf-blue-500);
83
+ --color-hf-accent-hover: var(--color-hf-blue-600);
84
+ --color-hf-accent-subtle: var(--color-hf-blue-50);
85
+ --color-hf-accent-subtler: var(--color-hf-blue-100);
86
+ --color-hf-on-accent: var(--color-hf-white);
87
+
88
+ /* ── Colors — SEMANTIC bg / fg / border ── */
89
+ --color-hf-bg-page: var(--color-hf-gray-25);
90
+ --color-hf-bg-section: var(--color-hf-gray-50);
91
+ --color-hf-bg-muted: var(--color-hf-gray-100);
92
+ --color-hf-bg-surface: var(--color-hf-white);
93
+ --color-hf-fg: var(--color-hf-gray-900);
94
+ --color-hf-fg-muted: var(--color-hf-gray-800);
95
+ --color-hf-fg-subtle: var(--color-hf-gray-550);
96
+ --color-hf-fg-faint: var(--color-hf-gray-400);
97
+ --color-hf-border: var(--color-hf-gray-300);
98
+ --color-hf-border-subtle: var(--color-hf-gray-200);
99
+ --color-hf-border-strong: var(--color-hf-gray-400);
100
+
101
+ /* ── Colors — SEMANTIC status ── */
102
+ --color-hf-status-success: var(--color-hf-green-500);
103
+ --color-hf-status-success-bg: rgba(89,181,157,.15);
104
+ --color-hf-status-warning: var(--color-hf-amber-400);
105
+ --color-hf-status-warning-bg: rgba(255,189,90,.15);
106
+ --color-hf-status-warning-strong: var(--color-hf-amber-600);
107
+ --color-hf-status-warning-strong-bg: rgba(255,201,0,.15);
108
+ --color-hf-status-error: var(--color-hf-red-400);
109
+ --color-hf-status-error-bg: rgba(234,101,101,.15);
110
+ --color-hf-status-error-strong: var(--color-hf-red-700);
111
+ --color-hf-status-error-alt: var(--color-hf-red-500);
112
+ --color-hf-status-info: var(--color-hf-accent);
113
+ --color-hf-status-info-bg: rgba(36,175,232,.15);
114
+ --color-hf-status-cancel: var(--color-hf-slate-500);
115
+ --color-hf-status-cancel-bg: rgba(127,143,164,.15);
116
+ --color-hf-status-coral: var(--color-hf-orange-500);
117
+ --color-hf-status-coral-bg: rgba(248,121,33,.15);
118
+ --color-hf-status-violet: var(--color-hf-violet-500);
119
+ --color-hf-status-violet-bg: rgba(87,97,216,.15);
120
+ --color-hf-status-olive: var(--color-hf-olive-700);
121
+ --color-hf-status-olive-bg: rgba(91,122,2,.15);
122
+ --color-hf-status-orange-deep: var(--color-hf-orange-700);
123
+ --color-hf-status-orange-deep-bg: rgba(165,85,5,.15);
124
+
125
+ /* ── Colors — SEMANTIC component-tier (Phase 2B) ── */
126
+ --color-hf-tab-fg-inactive: var(--color-hf-gray-700);
127
+ --color-hf-tab-count-fg: var(--color-hf-gray-700);
128
+ --color-hf-pagination-fg-inactive: var(--color-hf-gray-700);
129
+ --color-hf-pagination-fg-active: var(--color-hf-gray-950);
130
+ --color-hf-input-border: #DBDFE9;
131
+ --color-hf-menu-bg-hover: #F5F5F5;
132
+
133
+ /* ── Colors — LEGACY ALIASES (demo continuity — DO NOT introduce in new code) ── */
134
+ --color-primary: var(--color-hf-accent);
135
+ --color-primary-hover: var(--color-hf-accent-hover);
136
+ --color-primary-light: var(--color-hf-accent-subtle);
137
+ --color-primary-tint: var(--color-hf-accent-subtler);
138
+ --color-primary-tint-hover:#E5F0FF; /* no semantic match — kept direct */
139
+ --color-page: var(--color-hf-bg-page);
140
+ --color-section: var(--color-hf-bg-section);
141
+ --color-muted: var(--color-hf-bg-muted);
142
+ --color-border: var(--color-hf-border);
143
+ --color-border-light: var(--color-hf-border-subtle);
144
+ --color-border-strong: var(--color-hf-border-strong);
145
+ --color-border-neutral: var(--color-hf-fg-faint);
146
+ --color-ink: var(--color-hf-fg);
147
+ --color-ink-secondary: var(--color-hf-fg-muted);
148
+ --color-ink-steel: var(--color-hf-tab-fg-inactive);
149
+ --color-ink-muted: var(--color-hf-gray-600);
150
+ --color-ink-useful: var(--color-hf-fg-subtle);
151
+ --color-ink-faint: var(--color-hf-fg-faint);
152
+ --color-ok: var(--color-hf-status-success);
153
+ --color-warn: var(--color-hf-status-warning);
154
+ --color-bad: var(--color-hf-status-error);
155
+ --color-danger: var(--color-hf-status-error-strong);
156
+ --color-danger-hover: #C9302C; /* darker error-strong — no token */
157
+ --color-danger-outline: #F14141; /* portal-specific — no token */
158
+ --color-coral: var(--color-hf-status-coral);
159
+ --color-violet: var(--color-hf-status-violet);
160
+
161
+ /* ── Border radius — canonical ── */
162
+ --radius-hf-sm: 6px;
163
+ --radius-hf-md: 8px;
164
+ --radius-hf-lg: 9px;
165
+ --radius-hf-xl: 12px;
166
+ --radius-hf-pill: 99px;
167
+
168
+ /* ── Border radius — legacy aliases ── */
169
+ --radius: var(--radius-hf-sm); /* rounded → 6px */
170
+ --radius-md: var(--radius-hf-lg); /* rounded-md → 9px (was 9, Phase 1B renamed) */
171
+ --radius-lg: var(--radius-hf-xl); /* rounded-lg → 12px */
172
+ --radius-full: 9999px;
173
+
174
+ /* ── Shadows — canonical ── */
175
+ --shadow-hf: 0 1px 8px rgba(0,0,0,.10);
176
+ --shadow-hf-subtle: rgba(0,0,0,.05) 0px 2px 4px 0px;
177
+ --shadow-hf-wrapper: 0 3px 4px rgba(0,0,0,.03);
178
+ --shadow-hf-card: rgba(26,26,30,.06) 0px 12px 24px 0px;
179
+ --shadow-hf-modal: 0 6px 18px rgba(0,0,0,.10);
180
+ --shadow-hf-outline: rgba(72,91,120,.18) 0px 1px 2px 0px;
181
+ --shadow-hf-hover: 0 2px 3px rgba(0,0,0,.06);
182
+
183
+ /* ── Shadows — legacy aliases ── */
184
+ --shadow-default: var(--shadow-hf);
185
+ --shadow-subtle: var(--shadow-hf-subtle);
186
+ --shadow-card: var(--shadow-hf-card);
187
+ --shadow-modal: var(--shadow-hf-modal);
188
+ --shadow-outline: var(--shadow-hf-outline);
189
+ --shadow-hover: var(--shadow-hf-hover);
190
+ }
191
+
192
+ /* ── Embedded component layer — keeps components.html self-contained (standalone demo).
193
+ Phase 3A attempted @import "./pre-built/components.css" but Tailwind v4 browser CDN
194
+ does not support nested @imports. So this block stays as the canonical rendering for
195
+ the demo. The same rules are also in pre-built/components.css for consumer projects. ── */
196
+ @layer components {
197
+ :root {
198
+ --color-badge-booking-new-color: #FFBD5A; --color-badge-booking-new-bg: rgba(255,189,90,.15);
199
+ --color-badge-booking-offer-color: #5761D8; --color-badge-booking-offer-bg: rgba(87,97,216,.15);
200
+ --color-badge-booking-confirmed-color: #24AFE8; --color-badge-booking-confirmed-bg: rgba(36,175,232,.15);
201
+ --color-badge-booking-check-in-color: #5B7A02; --color-badge-booking-check-in-bg: rgba(91,122,2,.15);
202
+ --color-badge-booking-check-out-color: #F87921; --color-badge-booking-check-out-bg: rgba(248,121,33,.15);
203
+ --color-badge-booking-no-show-color: #EA6565; --color-badge-booking-no-show-bg: rgba(234,101,101,.15);
204
+ --color-badge-booking-due-in-color: #59B59D; --color-badge-booking-due-in-bg: rgba(89,181,157,.15);
205
+ --color-badge-booking-due-out-color: #A55505; --color-badge-booking-due-out-bg: rgba(165,85,5,.15);
206
+ --color-badge-booking-canceled-color: #7F8FA4; --color-badge-booking-canceled-bg: rgba(127,143,164,.15);
207
+ --color-badge-order-waiting-color: #FFBD5A; --color-badge-order-waiting-bg: rgba(255,189,90,.15);
208
+ --color-badge-order-confirmed-color: #24AFE8; --color-badge-order-confirmed-bg: rgba(36,175,232,.15);
209
+ --color-badge-order-completed-color: #59B59D; --color-badge-order-completed-bg: rgba(89,181,157,.15);
210
+ --color-badge-order-in-progress-color: #F87921; --color-badge-order-in-progress-bg: rgba(248,121,33,.15);
211
+ --color-badge-order-action-required-color: #EA6565; --color-badge-order-action-required-bg: rgba(234,101,101,.15);
212
+ --color-badge-order-canceled-color: #7F8FA4; --color-badge-order-canceled-bg: rgba(127,143,164,.15);
213
+ --color-badge-front-desk-quota-free-color: #59B59D; --color-badge-front-desk-quota-free-bg: rgba(89,181,157,.15);
214
+ --color-badge-front-desk-quota-busy-color: #EA6565; --color-badge-front-desk-quota-busy-bg: rgba(234,101,101,.15);
215
+ --color-badge-front-desk-out-of-order-color: #FFC900; --color-badge-front-desk-out-of-order-bg: rgba(255,201,0,.15);
216
+ --color-badge-room-item-cleaning-clean-color: #59B59D; --color-badge-room-item-cleaning-clean-bg: rgba(89,181,157,.15);
217
+ --color-badge-room-item-cleaning-dirty-color: #EA6565; --color-badge-room-item-cleaning-dirty-bg: rgba(234,101,101,.15);
218
+ --color-badge-room-item-cleaning-cleaning-color: #24AFE8; --color-badge-room-item-cleaning-cleaning-bg: rgba(36,175,232,.15);
219
+ --color-badge-room-item-cleaning-inspected-color: #5761D8; --color-badge-room-item-cleaning-inspected-bg: rgba(87,97,216,.15);
220
+ --color-badge-room-item-cleaning-out-of-service-color: #7F8FA4; --color-badge-room-item-cleaning-out-of-service-bg: rgba(127,143,164,.15);
221
+ /* Cancellation variants (all share cloud-gray #7F8FA4) and deleted */
222
+ --color-badge-cancel-color: #7F8FA4; --color-badge-cancel-bg: rgba(127,143,164,.15);
223
+ --color-badge-deleted-color: #7F8FA4; --color-badge-deleted-bg: rgba(127,143,164,.15);
224
+ }
225
+
226
+ /* ── Status pills ── */
227
+ .hf-pill {
228
+ display: inline-flex; align-items: center; justify-content: center;
229
+ padding: 6px 20px; border-radius: 6px;
230
+ font-size: 14px; font-weight: 500; line-height: 1; white-space: nowrap;
231
+ border: 1px solid currentColor;
232
+ text-align: center;
233
+ user-select: none;
234
+ transition: opacity 200ms, background-color 200ms;
235
+ }
236
+ .hf-pill:hover { opacity: .9; }
237
+ .hf-pill.is-active {
238
+ background: transparent !important;
239
+ box-shadow: inset 0 0 0 1px currentColor;
240
+ }
241
+ .hf-pill--striped {
242
+ background-image: repeating-linear-gradient(
243
+ -45deg, currentColor 0, currentColor 1px, transparent 1px, transparent 6px
244
+ );
245
+ background-color: white !important;
246
+ }
247
+ .hf-pill--dd { padding-right: 32px; cursor: pointer; position: relative; }
248
+ .hf-pill--dd::after {
249
+ content: ''; position: absolute; right: 12px; top: 50%;
250
+ width: 8px; height: 5px;
251
+ background-color: currentColor;
252
+ clip-path: polygon(0 0, 100% 0, 50% 100%);
253
+ transform: translateY(-50%);
254
+ }
255
+ /* Class names match token paths exactly (RFC §5d) */
256
+ .status-booking-new { color: var(--color-badge-booking-new-color); background: var(--color-badge-booking-new-bg); }
257
+ .status-booking-offer { color: var(--color-badge-booking-offer-color); background: var(--color-badge-booking-offer-bg); }
258
+ .status-booking-confirmed { color: var(--color-badge-booking-confirmed-color); background: var(--color-badge-booking-confirmed-bg); }
259
+ .status-booking-check-in { color: var(--color-badge-booking-check-in-color); background: var(--color-badge-booking-check-in-bg); }
260
+ .status-booking-check-out { color: var(--color-badge-booking-check-out-color); background: var(--color-badge-booking-check-out-bg); }
261
+ .status-booking-no-show { color: var(--color-badge-booking-no-show-color); background: var(--color-badge-booking-no-show-bg); }
262
+ .status-booking-due-in { color: var(--color-badge-booking-due-in-color); background: var(--color-badge-booking-due-in-bg); }
263
+ .status-booking-due-out { color: var(--color-badge-booking-due-out-color); background: var(--color-badge-booking-due-out-bg); }
264
+ .status-booking-canceled { color: var(--color-badge-booking-canceled-color); background: var(--color-badge-booking-canceled-bg); }
265
+ .status-order-waiting { color: var(--color-badge-order-waiting-color); background: var(--color-badge-order-waiting-bg); }
266
+ .status-order-confirmed { color: var(--color-badge-order-confirmed-color); background: var(--color-badge-order-confirmed-bg); }
267
+ .status-order-completed { color: var(--color-badge-order-completed-color); background: var(--color-badge-order-completed-bg); }
268
+ .status-order-in-progress { color: var(--color-badge-order-in-progress-color); background: var(--color-badge-order-in-progress-bg); }
269
+ .status-order-action-required { color: var(--color-badge-order-action-required-color); background: var(--color-badge-order-action-required-bg); }
270
+ .status-order-canceled { color: var(--color-badge-order-canceled-color); background: var(--color-badge-order-canceled-bg); }
271
+ .status-front-desk-quota-free { color: var(--color-badge-front-desk-quota-free-color); background: var(--color-badge-front-desk-quota-free-bg); }
272
+ .status-front-desk-quota-busy { color: var(--color-badge-front-desk-quota-busy-color); background: var(--color-badge-front-desk-quota-busy-bg); }
273
+ .status-front-desk-out-of-order { color: var(--color-badge-front-desk-out-of-order-color); background: var(--color-badge-front-desk-out-of-order-bg); }
274
+ .status-room-item-cleaning-clean { color: var(--color-badge-room-item-cleaning-clean-color); background: var(--color-badge-room-item-cleaning-clean-bg); }
275
+ .status-room-item-cleaning-dirty { color: var(--color-badge-room-item-cleaning-dirty-color); background: var(--color-badge-room-item-cleaning-dirty-bg); }
276
+ .status-room-item-cleaning-cleaning { color: var(--color-badge-room-item-cleaning-cleaning-color); background: var(--color-badge-room-item-cleaning-cleaning-bg); }
277
+ .status-room-item-cleaning-inspected { color: var(--color-badge-room-item-cleaning-inspected-color); background: var(--color-badge-room-item-cleaning-inspected-bg); }
278
+ .status-room-item-cleaning-out-of-service { color: var(--color-badge-room-item-cleaning-out-of-service-color); background: var(--color-badge-room-item-cleaning-out-of-service-bg); }
279
+ /* Cancellation reasons + deleted — all share cloud-gray cancel token */
280
+ .status-booking-canceled-by-hotel,
281
+ .status-booking-canceled-by-guest,
282
+ .status-booking-canceled-by-hf,
283
+ .status-order-canceled-by-hotel,
284
+ .status-order-canceled-by-guest,
285
+ .status-order-canceled-by-pos { color: var(--color-badge-cancel-color); background: var(--color-badge-cancel-bg); }
286
+ .status-deleted { color: var(--color-badge-deleted-color); background: var(--color-badge-deleted-bg); }
287
+
288
+ /* ── Tabs (.hf-tab) ── */
289
+ .hf-tab {
290
+ padding: 22px 15px; font-size: 16px; font-weight: 500; color: #50627E;
291
+ cursor: pointer; transition: color 200ms; position: relative;
292
+ white-space: nowrap; border: 0; background: 0; line-height: 1;
293
+ display: inline-flex; align-items: center; gap: 8px;
294
+ }
295
+ .hf-tab:hover { color: #2B2B2B; }
296
+ .hf-tab.is-active { color: #24AFE8; }
297
+ .hf-tab.is-active::after {
298
+ content: ''; position: absolute; left: 0; right: 0; bottom: -1px;
299
+ height: 3px; background: #24AFE8;
300
+ }
301
+ .hf-tab:disabled {
302
+ color: #AEBCCF; cursor: not-allowed;
303
+ }
304
+ .hf-tab:disabled:hover { color: #AEBCCF; }
305
+ /* Small sub-tabs (Today/All style) — 10px/15px padding, 15px font */
306
+ .hf-tab--sm { padding: 10px 15px; font-size: 15px; }
307
+ /* Count badge inside tab */
308
+ .hf-tab__count {
309
+ display: inline-flex; align-items: center; justify-content: center;
310
+ min-width: 22px; height: 18px; padding: 0 6px;
311
+ background: rgba(72,91,120,.1); color: #50627E;
312
+ border-radius: 9999px; font-size: 11px; font-weight: 600; line-height: 1;
313
+ }
314
+ .hf-tab.is-active .hf-tab__count {
315
+ background: rgba(36,175,232,.15); color: #24AFE8;
316
+ }
317
+ /* Pill tabs (segmented control) */
318
+ .hf-pill-tabs {
319
+ display: inline-flex; gap: 4px; padding: 4px;
320
+ background: #F6F7FB; border-radius: 9px;
321
+ }
322
+ .hf-pill-tab {
323
+ padding: 8px 14px; font-size: 14px; font-weight: 500;
324
+ color: #50627E; background: transparent;
325
+ border: 0; border-radius: 6px; cursor: pointer;
326
+ transition: background 200ms, color 200ms;
327
+ white-space: nowrap;
328
+ }
329
+ .hf-pill-tab:hover { color: #2B2B2B; }
330
+ .hf-pill-tab.is-active {
331
+ background: #fff; color: #24AFE8;
332
+ box-shadow: 0 1px 2px rgba(0,0,0,.05);
333
+ }
334
+
335
+ /* ── Pagination (.hf-pagination) — portal Bootstrap-style with subtle active ── */
336
+ .hf-pagination {
337
+ display: inline-flex; align-items: center; gap: 4px;
338
+ padding: 0; list-style: none;
339
+ }
340
+ .hf-pagination__item {
341
+ display: inline-flex; align-items: center; justify-content: center;
342
+ min-width: 34px; height: 34px;
343
+ padding: 0 12px;
344
+ font-size: 14px; font-weight: 400;
345
+ color: #485B78; /* ink-steel */
346
+ background: transparent;
347
+ border: 1px solid transparent;
348
+ border-radius: 8px;
349
+ cursor: pointer;
350
+ transition: background-color 200ms, color 200ms, border-color 200ms;
351
+ text-decoration: none;
352
+ }
353
+ .hf-pagination__item:hover { background: #F1F3F6; color: #2B2B2B; }
354
+ .hf-pagination__item.is-active {
355
+ background: #E4E8EF;
356
+ border-color: #E4E8EF;
357
+ color: #252F4A;
358
+ cursor: default;
359
+ }
360
+ .hf-pagination__item.is-active:hover { background: #E4E8EF; }
361
+ .hf-pagination__item:disabled,
362
+ .hf-pagination__item.is-disabled {
363
+ color: #AEBCCF;
364
+ cursor: not-allowed;
365
+ pointer-events: none;
366
+ }
367
+ .hf-pagination__ellipsis {
368
+ display: inline-flex; align-items: center; justify-content: center;
369
+ min-width: 34px; height: 34px;
370
+ color: #485B78;
371
+ cursor: default;
372
+ }
373
+
374
+ /* ── Alert (.hf-alert) — portal .alert pattern (top 3px bar + square icon) ── */
375
+ .hf-alert {
376
+ position: relative;
377
+ display: flex; align-items: flex-start; gap: 16px;
378
+ padding: 16px 48px 14px 20px;
379
+ background: #fff;
380
+ border: 1px solid rgba(72,91,120,.15);
381
+ border-radius: 6px;
382
+ box-shadow: 0 2px 4px 0 rgba(72,91,120,.07);
383
+ overflow: hidden;
384
+ }
385
+ .hf-alert::before {
386
+ /* 3px top accent bar */
387
+ content: '';
388
+ position: absolute;
389
+ left: 0; right: 0; top: 0;
390
+ height: 3px;
391
+ background: currentColor;
392
+ }
393
+ .hf-alert__icon {
394
+ flex-shrink: 0;
395
+ width: 26px; height: 26px;
396
+ border-radius: 5px;
397
+ display: inline-flex; align-items: center; justify-content: center;
398
+ background: currentColor; /* inherits accent color from .hf-alert--* */
399
+ }
400
+ /* SVG gets explicit white color so it doesn't inherit the parent's accent */
401
+ .hf-alert__icon > svg {
402
+ width: 16px; height: 16px;
403
+ color: #fff;
404
+ stroke: #fff;
405
+ fill: none;
406
+ }
407
+ .hf-alert__body { flex: 1; min-width: 0; color: #2B2B2B; }
408
+ .hf-alert__title { font-size: 18px; font-weight: 500; line-height: 1.3; margin: 0 0 4px; color: #2B2B2B; }
409
+ .hf-alert__text { font-size: 15px; line-height: 1.4; color: #50627E; margin: 0; }
410
+ .hf-alert__close {
411
+ position: absolute; top: 12px; right: 12px;
412
+ width: 24px; height: 24px;
413
+ display: inline-flex; align-items: center; justify-content: center;
414
+ background: transparent; border: 0; border-radius: 4px;
415
+ color: #99A1B7; cursor: pointer;
416
+ transition: color 200ms, background 200ms;
417
+ }
418
+ .hf-alert__close:hover { color: #2B2B2B; background: #F1F3F6; }
419
+ /* Variants — set accent color via currentColor on root */
420
+ .hf-alert--success { color: #59B59D; }
421
+ .hf-alert--info { color: #24AFE8; }
422
+ .hf-alert--warn { color: #FFBD5A; }
423
+ .hf-alert--error { color: #EA6565; }
424
+ /* Tinted variant: background-tint instead of white */
425
+ .hf-alert--tinted.hf-alert--success { background: rgba(89,181,157,.06); }
426
+ .hf-alert--tinted.hf-alert--info { background: rgba(36,175,232,.06); }
427
+ .hf-alert--tinted.hf-alert--warn { background: rgba(255,189,90,.10); }
428
+ .hf-alert--tinted.hf-alert--error { background: rgba(234,101,101,.06); }
429
+ /* Page banner — full-width strip, no rounded, no shadow */
430
+ .hf-alert--banner {
431
+ border-radius: 0;
432
+ border-left: 0; border-right: 0;
433
+ box-shadow: none;
434
+ background: currentColor;
435
+ }
436
+ .hf-alert--banner::before { display: none; }
437
+ .hf-alert--banner .hf-alert__body { color: #fff; }
438
+ .hf-alert--banner .hf-alert__title,
439
+ .hf-alert--banner .hf-alert__text { color: #fff; }
440
+ .hf-alert--banner .hf-alert__icon { background: rgba(255,255,255,.18); }
441
+ .hf-alert--banner .hf-alert__close { color: rgba(255,255,255,.7); }
442
+ .hf-alert--banner .hf-alert__close:hover { color: #fff; background: rgba(255,255,255,.12); }
443
+ /* Compact variant — for inside cards */
444
+ .hf-alert--compact { padding: 10px 36px 10px 14px; gap: 10px; }
445
+ .hf-alert--compact .hf-alert__icon { width: 20px; height: 20px; border-radius: 4px; }
446
+ .hf-alert--compact .hf-alert__icon > svg { width: 12px; height: 12px; }
447
+ .hf-alert--compact .hf-alert__title { font-size: 14px; font-weight: 600; margin-bottom: 0; }
448
+ .hf-alert--compact .hf-alert__text { font-size: 13px; }
449
+ .hf-alert--compact .hf-alert__close { top: 8px; right: 8px; }
450
+ /* Toast — small floating notification */
451
+ .hf-toast {
452
+ display: inline-flex; align-items: center; gap: 10px;
453
+ padding: 10px 14px;
454
+ background: #fff;
455
+ border: 1px solid rgba(72,91,120,.15);
456
+ border-radius: 9px;
457
+ box-shadow: 0 6px 18px rgba(0,0,0,.10);
458
+ min-width: 280px; max-width: 420px;
459
+ color: #2B2B2B; font-size: 14px;
460
+ }
461
+ .hf-toast__icon { flex-shrink: 0; width: 20px; height: 20px; }
462
+ .hf-toast__text { flex: 1; }
463
+ .hf-toast__close {
464
+ flex-shrink: 0;
465
+ width: 20px; height: 20px;
466
+ display: inline-flex; align-items: center; justify-content: center;
467
+ background: transparent; border: 0; border-radius: 4px;
468
+ color: #99A1B7; cursor: pointer; transition: color 200ms;
469
+ }
470
+ .hf-toast__close:hover { color: #2B2B2B; }
471
+
472
+ /* ── Modal (.hf-modal) — portal .modal-content ── */
473
+ .hf-modal {
474
+ background: #fff;
475
+ border: 1px solid rgba(72,91,120,.15);
476
+ border-radius: 6px;
477
+ box-shadow: 0 2px 4px 0 rgba(72,91,120,.18);
478
+ overflow: hidden;
479
+ width: 100%;
480
+ }
481
+ .hf-modal__header {
482
+ display: flex; align-items: center; justify-content: space-between;
483
+ padding: 20px;
484
+ border-bottom: 1px solid #E4E8EF;
485
+ }
486
+ .hf-modal__title {
487
+ font-size: 18px; font-weight: 600; color: #2B2B2B;
488
+ margin: 0;
489
+ }
490
+ .hf-modal__close {
491
+ width: 32px; height: 32px;
492
+ display: inline-flex; align-items: center; justify-content: center;
493
+ background: transparent;
494
+ border: 0; border-radius: 6px;
495
+ color: #50627E;
496
+ cursor: pointer;
497
+ transition: background 200ms, color 200ms;
498
+ }
499
+ .hf-modal__close:hover { background: #F1F3F6; color: #2B2B2B; }
500
+ .hf-modal__body { padding: 20px; }
501
+ .hf-modal__footer {
502
+ display: flex; justify-content: flex-end; gap: 12px;
503
+ padding: 20px;
504
+ border-top: 0; /* portal: no top border on footer */
505
+ background: transparent;
506
+ }
507
+ /* Optional footer separator variant — set on the modal if needed */
508
+ .hf-modal--with-footer-border .hf-modal__footer {
509
+ border-top: 1px solid #E4E8EF;
510
+ }
511
+
512
+ /* ── Checkbox & Radio (.hf-check, .hf-radio) — portal .mt-checkbox-outline ── */
513
+ .hf-check,
514
+ .hf-radio {
515
+ appearance: none; -webkit-appearance: none;
516
+ position: relative; flex-shrink: 0;
517
+ width: 18px; height: 18px;
518
+ margin: 0;
519
+ background: transparent;
520
+ border: 1px solid #DBDFE9;
521
+ cursor: pointer;
522
+ transition: border-color 200ms, background-color 200ms;
523
+ }
524
+ .hf-check { border-radius: 6px; }
525
+ .hf-radio { border-radius: 9999px; }
526
+ .hf-check:hover:not(:disabled),
527
+ .hf-radio:hover:not(:disabled) { border-color: #26ADE4; }
528
+ .hf-check:checked,
529
+ .hf-radio:checked { background: #26ADE4; border-color: #26ADE4; }
530
+ /* checkmark — white 5×10 with right+bottom border, rotated 45deg */
531
+ .hf-check:checked::after {
532
+ content: '';
533
+ position: absolute; top: 2px; left: 5px;
534
+ width: 5px; height: 10px;
535
+ border: solid #fff;
536
+ border-width: 0 2px 2px 0;
537
+ transform: rotate(45deg);
538
+ }
539
+ /* inner dot for radio */
540
+ .hf-radio:checked::after {
541
+ content: '';
542
+ position: absolute; top: 50%; left: 50%;
543
+ width: 6px; height: 6px;
544
+ background: #fff; border-radius: 9999px;
545
+ transform: translate(-50%, -50%);
546
+ }
547
+ .hf-check:disabled,
548
+ .hf-radio:disabled {
549
+ cursor: not-allowed;
550
+ opacity: .5;
551
+ }
552
+ .hf-check:checked:disabled,
553
+ .hf-radio:checked:disabled {
554
+ background: rgba(38,173,228,.5);
555
+ border-color: rgba(38,173,228,.5);
556
+ opacity: 1;
557
+ }
558
+
559
+ /* ── Dropdown menu (portal .dropdown-menu.open) ── */
560
+ .hf-dropdown-menu {
561
+ background: #fff;
562
+ border-radius: 9px;
563
+ box-shadow: 0 1px 10px 0 rgba(0,0,0,.1); /* $dropdown_shadow */
564
+ min-width: 180px;
565
+ padding: 6px 0;
566
+ border: 1px solid rgba(228,232,239,.6);
567
+ }
568
+ .hf-dropdown-header {
569
+ padding: 10px 16px 8px;
570
+ font-size: 11px; font-weight: 600;
571
+ color: #99A1B7;
572
+ text-transform: uppercase;
573
+ letter-spacing: .04em;
574
+ }
575
+ .hf-dropdown-item {
576
+ display: flex; align-items: center; gap: 10px;
577
+ padding: 8px 16px; font-size: 14px; color: #2B2B2B;
578
+ cursor: pointer; transition: background 150ms;
579
+ line-height: 1.4;
580
+ }
581
+ .hf-dropdown-item:hover { background: #F5F5F5; }
582
+ .hf-dropdown-item.is-active { background: #EFF6FF; color: #24AFE8; }
583
+ .hf-dropdown-item:focus-visible { background: #F5F5F5; outline: 2px solid #24AFE8; outline-offset: -2px; }
584
+ .hf-dropdown-item.danger { color: #EA6565; }
585
+ .hf-dropdown-item.danger:hover { background: rgba(234,101,101,.08); }
586
+ .hf-dropdown-item[aria-disabled="true"],
587
+ .hf-dropdown-item.is-disabled {
588
+ color: #AEBCCF; cursor: not-allowed; pointer-events: none;
589
+ }
590
+ .hf-dropdown-item__shortcut {
591
+ margin-left: auto;
592
+ color: #99A1B7;
593
+ font-size: 12px;
594
+ }
595
+ .hf-dropdown-item__icon { color: #99A1B7; width: 16px; height: 16px; flex-shrink: 0; }
596
+ .hf-dropdown-item:hover .hf-dropdown-item__icon { color: #50627E; }
597
+ .hf-dropdown-item.danger .hf-dropdown-item__icon { color: currentColor; }
598
+ .hf-dropdown-divider { height: 1px; background: #E4E8EF; margin: 4px 0; }
599
+ }
600
+ </style>
601
+
602
+ <style>
603
+ /* ════════════════════════════════════════════════════════════════════════
604
+ DESIGN TOKENS — plain-CSS passthrough (RFC-0002 fix)
605
+ ────────────────────────────────────────────────────────────────────────
606
+ The @theme block in the <style type="text/tailwindcss"> above is the
607
+ canonical token source AND generates the utility classes. But Tailwind
608
+ v4's browser CDN claims every `--color-*` declaration inside the block it
609
+ compiles and tree-shakes the ones not referenced by a used utility — it
610
+ does NOT trace var() chains, so primitives referenced only by a semantic
611
+ token (e.g. --color-hf-border: var(--color-hf-gray-300)) get dropped and
612
+ the semantic token collapses to currentColor (≈ black #2B2B2B). That is
613
+ why gray borders turned black.
614
+
615
+ This block lives in a PLAIN <style> (no type=text/tailwindcss), which
616
+ Tailwind never touches, so these declarations always reach :root and every
617
+ var() chain resolves. Keep in sync with the @theme primitives + semantics
618
+ above and with pre-built/tokens.css. ── */
619
+ :root {
620
+ /* Primitives */
621
+ --color-hf-blue-50: #E9F6FC; --color-hf-blue-100: #EFF6FF;
622
+ --color-hf-blue-500: #24AFE8; --color-hf-blue-600: #149AD1;
623
+ --color-hf-gray-25: #FBFBFC; --color-hf-gray-50: #F6F7FB;
624
+ --color-hf-gray-100: #F1F3F6; --color-hf-gray-200: #E4E8EF;
625
+ --color-hf-gray-300: #D1D6DD; --color-hf-gray-400: #AEBCCF;
626
+ --color-hf-gray-500: #99A1B7; --color-hf-gray-550: #7E8EA6;
627
+ --color-hf-gray-600: #50627E; --color-hf-gray-700: #485B78;
628
+ --color-hf-gray-800: #4B5675; --color-hf-gray-900: #2B2B2B;
629
+ --color-hf-gray-950: #252F4A;
630
+ --color-hf-green-500: #59B59D;
631
+ --color-hf-amber-400: #FFBD5A; --color-hf-amber-600: #FFC900;
632
+ --color-hf-red-400: #EA6565; --color-hf-red-500: #FB5A56; --color-hf-red-700: #D9534F;
633
+ --color-hf-orange-500: #F87921; --color-hf-orange-700: #A55505;
634
+ --color-hf-violet-500: #5761D8; --color-hf-slate-500: #7F8FA4; --color-hf-olive-700: #5B7A02;
635
+ --color-hf-white: #FFFFFF; --color-hf-black: #000000;
636
+ /* Semantic — accent */
637
+ --color-hf-accent: var(--color-hf-blue-500);
638
+ --color-hf-accent-hover: var(--color-hf-blue-600);
639
+ --color-hf-accent-subtle: var(--color-hf-blue-50);
640
+ --color-hf-accent-subtler: var(--color-hf-blue-100);
641
+ --color-hf-on-accent: var(--color-hf-white);
642
+ /* Semantic — bg / fg / border */
643
+ --color-hf-bg-page: var(--color-hf-gray-25);
644
+ --color-hf-bg-section: var(--color-hf-gray-50);
645
+ --color-hf-bg-muted: var(--color-hf-gray-100);
646
+ --color-hf-bg-surface: var(--color-hf-white);
647
+ --color-hf-fg: var(--color-hf-gray-900);
648
+ --color-hf-fg-muted: var(--color-hf-gray-800);
649
+ --color-hf-fg-subtle: var(--color-hf-gray-550);
650
+ --color-hf-fg-faint: var(--color-hf-gray-400);
651
+ --color-hf-border: var(--color-hf-gray-300);
652
+ --color-hf-border-subtle: var(--color-hf-gray-200);
653
+ --color-hf-border-strong: var(--color-hf-gray-400);
654
+ /* Semantic — component-tier */
655
+ --color-hf-tab-fg-inactive: var(--color-hf-gray-700);
656
+ --color-hf-tab-count-fg: var(--color-hf-gray-700);
657
+ --color-hf-pagination-fg-inactive: var(--color-hf-gray-700);
658
+ --color-hf-pagination-fg-active: var(--color-hf-gray-950);
659
+ --color-hf-input-border: #DBDFE9;
660
+ --color-hf-menu-bg-hover: #F5F5F5;
661
+ /* Legacy aliases (demo continuity) */
662
+ --color-border: var(--color-hf-border);
663
+ --color-border-light: var(--color-hf-border-subtle);
664
+ --color-border-strong: var(--color-hf-border-strong);
665
+ --color-border-neutral:var(--color-hf-fg-faint);
666
+ }
667
+
668
+ /* ── Code snippet ── */
669
+ .snippet { position: relative; background: #1e293b; border-radius: 6px; margin-top: 16px; }
670
+ .snippet pre { padding: 14px 16px; overflow-x: auto; font-size: 12px; line-height: 1.6; color: #cbd5e1; font-family: 'Roboto Mono','Fira Code',monospace; margin: 0; }
671
+ .snippet .copy-btn { position: absolute; top: 8px; right: 10px; background: rgba(255,255,255,.08); color: #94a3b8; border: 0; border-radius: 4px; padding: 3px 10px; font-size: 11px; cursor: pointer; }
672
+ .snippet .copy-btn:hover { background: rgba(255,255,255,.16); color: #e2e8f0; }
673
+ .snippet .copy-btn.copied { color: #59B59D; }
674
+
675
+ /* ── Skeleton ── */
676
+ @keyframes shimmer { 0%{background-position:-200% 0} 100%{background-position:200% 0} }
677
+ .skeleton { background: linear-gradient(90deg,#F1F3F6 25%,#E4E8EF 50%,#F1F3F6 75%); background-size:200% 100%; animation:shimmer 1.4s infinite; border-radius:4px; }
678
+
679
+ /* ── Loading spinner ── */
680
+ @keyframes hf-spin { to { transform: rotate(360deg); } }
681
+ .hf-spin { animation: hf-spin .6s linear infinite; }
682
+
683
+ /* ── Layout helpers ── */
684
+ .section-title { font-size: 22px; font-weight: 600; color: #2B2B2B; margin-bottom: 4px; }
685
+ .section-desc { font-size: 14px; color: #4B5675; margin-bottom: 24px; }
686
+ .demo-row { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; }
687
+ .state-label { font-size: 11px; font-weight: 500; color: #99A1B7; text-transform: uppercase; letter-spacing: .05em; min-width: 72px; }
688
+ .sub-title { font-size: 15px; font-weight: 600; color: #2B2B2B; margin-bottom: 12px; }
689
+ </style>
690
+ </head>
691
+
692
+ <!-- ── Lucide icons ── -->
693
+ <svg style="display:none" aria-hidden="true">
694
+ <symbol id="ic-save" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
695
+ <path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
696
+ <polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/>
697
+ </symbol>
698
+ <symbol id="ic-x" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
699
+ <line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
700
+ </symbol>
701
+ <symbol id="ic-trash" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
702
+ <polyline points="3 6 5 6 21 6"/>
703
+ <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2"/>
704
+ <line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/>
705
+ </symbol>
706
+ <symbol id="ic-plus" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
707
+ <line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>
708
+ </symbol>
709
+ <symbol id="ic-refresh-cw" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
710
+ <polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/>
711
+ <path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/>
712
+ </symbol>
713
+ <symbol id="ic-chevron-down" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
714
+ <polyline points="6 9 12 15 18 9"/>
715
+ </symbol>
716
+ <symbol id="ic-chevron-left" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
717
+ <polyline points="15 18 9 12 15 6"/>
718
+ </symbol>
719
+ <symbol id="ic-chevron-right" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
720
+ <polyline points="9 18 15 12 9 6"/>
721
+ </symbol>
722
+ <symbol id="ic-search" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
723
+ <circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
724
+ </symbol>
725
+ <symbol id="ic-filter" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
726
+ <polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/>
727
+ </symbol>
728
+ <symbol id="ic-edit-2" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
729
+ <path d="M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z"/>
730
+ </symbol>
731
+ <symbol id="ic-eye" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
732
+ <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>
733
+ </symbol>
734
+ <symbol id="ic-more-vertical" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
735
+ <circle cx="12" cy="5" r="1"/><circle cx="12" cy="12" r="1"/><circle cx="12" cy="19" r="1"/>
736
+ </symbol>
737
+ <symbol id="ic-copy" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
738
+ <rect x="9" y="9" width="13" height="13" rx="2" ry="2"/>
739
+ <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>
740
+ </symbol>
741
+ <symbol id="ic-settings" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
742
+ <circle cx="12" cy="12" r="3"/>
743
+ <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
744
+ </symbol>
745
+ <symbol id="ic-log-out" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
746
+ <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/>
747
+ <polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/>
748
+ </symbol>
749
+ <symbol id="ic-alert-circle" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
750
+ <circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/>
751
+ </symbol>
752
+ <symbol id="ic-check-circle" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
753
+ <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/>
754
+ </symbol>
755
+ <symbol id="ic-info" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
756
+ <circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/>
757
+ </symbol>
758
+ <symbol id="ic-alert-triangle" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
759
+ <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>
760
+ <line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/>
761
+ </symbol>
762
+ <symbol id="ic-calendar" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
763
+ <rect x="3" y="4" width="18" height="18" rx="2" ry="2"/>
764
+ <line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/>
765
+ </symbol>
766
+ <symbol id="ic-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
767
+ <polyline points="20 6 9 17 4 12"/>
768
+ </symbol>
769
+ </svg>
770
+
771
+ <body class="bg-page font-sans text-ink antialiased">
772
+ <div class="flex min-h-screen">
773
+
774
+ <!-- Sidebar -->
775
+ <aside class="w-52 shrink-0 bg-section border-r border-border-light sticky top-0 h-screen overflow-y-auto py-6 px-4">
776
+ <div class="text-action font-semibold text-primary mb-6 px-2">HF Components</div>
777
+ <nav class="flex flex-col gap-0.5 text-body text-ink-secondary">
778
+ <a href="#buttons" class="px-3 py-2 rounded hover:bg-primary-light hover:text-primary transition-colors duration-200">Buttons</a>
779
+ <a href="#inputs" class="px-3 py-2 rounded hover:bg-primary-light hover:text-primary transition-colors duration-200">Inputs</a>
780
+ <a href="#cards" class="px-3 py-2 rounded hover:bg-primary-light hover:text-primary transition-colors duration-200">Cards</a>
781
+ <a href="#status" class="px-3 py-2 rounded hover:bg-primary-light hover:text-primary transition-colors duration-200">Status Pills</a>
782
+ <a href="#tabs" class="px-3 py-2 rounded hover:bg-primary-light hover:text-primary transition-colors duration-200">Tabs</a>
783
+ <a href="#dropdown" class="px-3 py-2 rounded hover:bg-primary-light hover:text-primary transition-colors duration-200">Dropdown</a>
784
+ <a href="#modal" class="px-3 py-2 rounded hover:bg-primary-light hover:text-primary transition-colors duration-200">Modal</a>
785
+ <a href="#alerts" class="px-3 py-2 rounded hover:bg-primary-light hover:text-primary transition-colors duration-200">Alerts</a>
786
+ <a href="#pagination" class="px-3 py-2 rounded hover:bg-primary-light hover:text-primary transition-colors duration-200">Pagination</a>
787
+ <a href="#empty" class="px-3 py-2 rounded hover:bg-primary-light hover:text-primary transition-colors duration-200">Empty / Skeleton</a>
788
+ <a href="#layout" class="px-3 py-2 rounded hover:bg-primary-light hover:text-primary transition-colors duration-200">Page Layouts</a>
789
+ </nav>
790
+ </aside>
791
+
792
+ <!-- Main -->
793
+ <main class="flex-1 min-w-0 p-10 max-w-4xl">
794
+ <h1 class="text-page font-semibold text-ink mb-1">HotelFriend Components</h1>
795
+ <p class="text-body text-ink-secondary mb-10">Extracted from the live portal via Playwright. Values are computed styles — exact pixels, not approximations.</p>
796
+
797
+ <!-- ════════════════════════════════════════════════════════════════ -->
798
+ <!-- BUTTONS -->
799
+ <!-- ════════════════════════════════════════════════════════════════ -->
800
+ <section id="buttons" class="mb-16">
801
+ <div class="section-title">Buttons</div>
802
+ <div class="section-desc">All values extracted from <code class="bg-muted px-1 rounded text-meta">localhost/design/index</code> via Playwright <code class="bg-muted px-1 rounded text-meta">getComputedStyle()</code>.</div>
803
+
804
+ <!-- Filled buttons -->
805
+ <div class="sub-title">Filled</div>
806
+ <div class="demo-row mb-8">
807
+ <!-- btn-primary: h=40, px=20, bg=#26ADE4→canonical #24AFE8, fw=600, hover=bg:#149AD1 -->
808
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-primary hover:bg-primary-hover text-white text-action font-semibold rounded transition-all duration-200 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary disabled:opacity-60 disabled:cursor-not-allowed">
809
+ <svg class="w-4 h-4"><use href="#ic-save"/></svg> Save
810
+ </button>
811
+ <!-- btn-danger: h=40, px=20, bg=#D9534F, hover=bg:#C9302C, fw=600 -->
812
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-danger hover:bg-danger-hover text-white text-action font-semibold rounded transition-all duration-200 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-danger disabled:opacity-60 disabled:cursor-not-allowed">
813
+ <svg class="w-4 h-4"><use href="#ic-trash"/></svg> Delete
814
+ </button>
815
+ </div>
816
+
817
+ <!-- Outline buttons -->
818
+ <div class="sub-title">Outline</div>
819
+ <div class="demo-row mb-8">
820
+ <!-- btn-hf-outline-primary: white bg, #24AFE8 border+text, hover=bg:#F1F3F6 -->
821
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-white hover:bg-muted text-primary text-action font-semibold rounded border border-primary transition-all duration-200 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary disabled:opacity-60 disabled:cursor-not-allowed">
822
+ <svg class="w-4 h-4"><use href="#ic-eye"/></svg> Outline Primary
823
+ </button>
824
+ <!-- btn-hf-outline-default: white bg, #485B78 text, #D1D6DD border + shadow, hover=bg:#F1F3F6 -->
825
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-white hover:bg-muted text-ink-steel text-action font-semibold rounded border border-border shadow-outline transition-all duration-200 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-strong disabled:opacity-60 disabled:cursor-not-allowed">
826
+ <svg class="w-4 h-4"><use href="#ic-settings"/></svg> Outline Default
827
+ </button>
828
+ <!-- btn-hf-outline-mixed: white bg, #24AFE8 text, #D1D6DD border (neutral border + primary text), hover=bg:#F1F3F6 -->
829
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-white hover:bg-muted text-primary text-action font-semibold rounded border border-border transition-all duration-200 disabled:opacity-60 disabled:cursor-not-allowed">
830
+ <svg class="w-4 h-4"><use href="#ic-copy"/></svg> Outline Mixed
831
+ </button>
832
+ <!-- btn-hf-outline-danger: white bg, #F14141 text+border, hover=bg:#F1F3F6 -->
833
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-white hover:bg-muted text-danger-outline text-action font-semibold rounded border border-danger-outline transition-all duration-200 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-danger-outline disabled:opacity-60 disabled:cursor-not-allowed">
834
+ <svg class="w-4 h-4"><use href="#ic-alert-circle"/></svg> Outline Danger
835
+ </button>
836
+ </div>
837
+
838
+ <!-- Cancel & filters -->
839
+ <div class="sub-title">Cancel &amp; Filters</div>
840
+ <div class="demo-row mb-8">
841
+ <!-- btn-cancel: white bg, #50627E text, hover=rgba(190,198,212,.1) -->
842
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-white hover:bg-[rgba(190,198,212,0.1)] text-ink-muted text-action font-semibold rounded transition-all duration-200">
843
+ Cancel
844
+ </button>
845
+ <!-- btn-reset-filters (new): h=38, bg=#EFF6FF, hover=#E5F0FF, #24AFE8, 14px/500 -->
846
+ <button class="inline-flex items-center gap-2 h-[38px] px-[10px] bg-primary-tint hover:bg-primary-tint-hover text-primary text-body font-medium rounded border border-primary/20 transition-all duration-200">
847
+ <svg class="w-4 h-4"><use href="#ic-refresh-cw"/></svg> Reset Filters
848
+ </button>
849
+ <!-- filters-btn: same as btn-reset-filters new style -->
850
+ <button class="inline-flex items-center gap-2 h-[38px] px-[10px] bg-primary-tint hover:bg-primary-tint-hover text-primary text-body font-medium rounded border border-primary/20 transition-all duration-200">
851
+ <svg class="w-4 h-4"><use href="#ic-filter"/></svg> Filters
852
+ </button>
853
+ </div>
854
+
855
+ <!-- Sizes & icon-only -->
856
+ <div class="sub-title">Sizes &amp; icon-only</div>
857
+ <div class="demo-row mb-8">
858
+ <!-- Default 40px -->
859
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-primary hover:bg-primary-hover text-white text-action font-semibold rounded transition-all duration-200">
860
+ Default 40px
861
+ </button>
862
+ <!-- Small 32px (btn-sm): h=32, px=14, fw=600 -->
863
+ <button class="inline-flex items-center gap-2 h-8 px-[14px] bg-primary hover:bg-primary-hover text-white text-action font-semibold rounded transition-all duration-200">
864
+ Small 32px
865
+ </button>
866
+ <!-- Thin 30px (btn-thin): h=30 -->
867
+ <button class="inline-flex items-center gap-2 h-[30px] px-[14px] bg-primary hover:bg-primary-hover text-white text-action font-semibold rounded transition-all duration-200">
868
+ Thin 30px
869
+ </button>
870
+ <!-- Square icon 40px (btn-sqr + outline-primary) -->
871
+ <button class="inline-flex items-center justify-center w-10 h-10 bg-white hover:bg-muted text-primary border border-primary rounded transition-all duration-200">
872
+ <svg class="w-4 h-4"><use href="#ic-plus"/></svg>
873
+ </button>
874
+ <!-- Square icon 32px (btn-sqr_sm + outline-default) -->
875
+ <button class="inline-flex items-center justify-center w-8 h-8 bg-white hover:bg-muted text-ink-steel border border-border shadow-outline rounded transition-all duration-200">
876
+ <svg class="w-4 h-4"><use href="#ic-edit-2"/></svg>
877
+ </button>
878
+ <!-- icon-only transparent (more-vertical) -->
879
+ <button class="inline-flex items-center justify-center w-8 h-8 bg-transparent hover:bg-muted text-ink-steel rounded transition-all duration-200">
880
+ <svg class="w-4 h-4"><use href="#ic-more-vertical"/></svg>
881
+ </button>
882
+ <!-- Text link -->
883
+ <button class="text-primary text-body hover:underline bg-transparent border-0 p-0 cursor-pointer">
884
+ Go to details →
885
+ </button>
886
+ </div>
887
+
888
+ <!-- States -->
889
+ <div class="sub-title">States — Primary</div>
890
+ <div class="flex flex-col gap-3 mb-6">
891
+ <div class="flex items-center gap-4">
892
+ <span class="state-label">Default</span>
893
+ <button class="inline-flex items-center h-10 px-5 bg-primary text-white text-action font-semibold rounded">Save</button>
894
+ </div>
895
+ <div class="flex items-center gap-4">
896
+ <span class="state-label">Hover</span>
897
+ <button class="inline-flex items-center h-10 px-5 bg-primary-hover text-white text-action font-semibold rounded">Save</button>
898
+ </div>
899
+ <div class="flex items-center gap-4">
900
+ <span class="state-label">Focus</span>
901
+ <button class="inline-flex items-center h-10 px-5 bg-primary text-white text-action font-semibold rounded outline-2 outline-offset-2 outline-primary">Save</button>
902
+ </div>
903
+ <div class="flex items-center gap-4">
904
+ <span class="state-label">Disabled</span>
905
+ <button class="inline-flex items-center h-10 px-5 bg-primary text-white text-action font-semibold rounded opacity-60 cursor-not-allowed" disabled>Save</button>
906
+ </div>
907
+ <div class="flex items-center gap-4">
908
+ <span class="state-label">Loading</span>
909
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-primary text-white text-action font-semibold rounded opacity-75 cursor-wait">
910
+ <svg class="w-4 h-4 hf-spin" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>
911
+ Saving…
912
+ </button>
913
+ </div>
914
+ </div>
915
+
916
+ <!-- Compact / inline action variants (discovered from portal sweep) -->
917
+ <div class="sub-title">Compact &amp; Inline Action Variants</div>
918
+ <p class="text-body text-ink-secondary mb-4">Found across hotel dashboard, orders, departments pages. All values from <code class="bg-muted px-1 rounded text-meta">getComputedStyle()</code>.</p>
919
+
920
+ <!-- Gray outline family -->
921
+ <div class="flex items-center gap-3 mb-4 flex-wrap">
922
+ <span class="state-label">Gray outline</span>
923
+ <!-- btn-b-gray: h=32, white bg, #485B78, border=rgba(72,91,120,.15) -->
924
+ <button class="inline-flex items-center gap-1.5 h-8 px-[14px] bg-white hover:bg-muted text-ink-steel text-body font-semibold rounded border border-[rgba(72,91,120,0.15)] transition-all duration-200">
925
+ <svg class="w-3.5 h-3.5"><use href="#ic-filter"/></svg> btn-b-gray
926
+ </button>
927
+ <!-- btn-gray: h=32, rgba(72,91,120,.07) bg, no border, #485B78 -->
928
+ <button class="inline-flex items-center gap-1.5 h-8 px-[14px] bg-[rgba(72,91,120,0.07)] hover:bg-[rgba(72,91,120,0.12)] text-ink-steel text-body font-semibold rounded transition-all duration-200">
929
+ <svg class="w-3.5 h-3.5"><use href="#ic-settings"/></svg> btn-gray
930
+ </button>
931
+ <!-- btn-add-grey: h=40, transparent, #485B78, rgba(72,91,120,.15) border, 14px/500 -->
932
+ <button class="inline-flex items-center gap-2 h-10 px-[10px] bg-transparent hover:bg-[rgba(72,91,120,0.05)] text-ink-steel text-body font-medium rounded border border-[rgba(72,91,120,0.15)] transition-all duration-200">
933
+ <svg class="w-4 h-4"><use href="#ic-plus"/></svg> btn-add-grey
934
+ </button>
935
+ <!-- btn-cancel-red: white bg, #FB5A56 text+border, 40px -->
936
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-white hover:bg-[rgba(251,90,86,0.06)] text-[#FB5A56] text-action font-semibold rounded border border-[#FB5A56] transition-all duration-200">
937
+ <svg class="w-4 h-4"><use href="#ic-x"/></svg> Cancel booking
938
+ </button>
939
+ </div>
940
+
941
+ <!-- Outline / transparent – primary text -->
942
+ <div class="flex items-center gap-3 mb-4 flex-wrap">
943
+ <span class="state-label">Outline alt</span>
944
+ <!-- btn-preview: h=32, transparent, primary text, light border (#E4E8EF) -->
945
+ <button class="inline-flex items-center gap-1.5 h-8 px-[14px] bg-transparent hover:bg-primary-light text-primary text-body font-semibold rounded border border-border-light transition-all duration-200">
946
+ <svg class="w-3.5 h-3.5"><use href="#ic-eye"/></svg> Preview
947
+ </button>
948
+ <!-- btn-go-to: h=40, transparent, primary text+border -->
949
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-transparent hover:bg-primary-light text-primary text-action font-semibold rounded border border-primary transition-all duration-200">
950
+ Go to →
951
+ </button>
952
+ <!-- btn-back-shadow: h=39, white, primary text, rgba(72,91,120,.1) border, shadow, radius=3px -->
953
+ <button class="inline-flex items-center gap-2 h-[39px] px-5 bg-white hover:bg-muted text-primary text-action font-semibold rounded-[3px] border border-[rgba(72,91,120,0.1)] shadow-default transition-all duration-200">
954
+ ← Back
955
+ </button>
956
+ </div>
957
+
958
+ <!-- Small square icon buttons (30–32px) -->
959
+ <div class="flex items-center gap-3 mb-4 flex-wrap">
960
+ <span class="state-label">Icon sq.</span>
961
+ <!-- btn-edit-sm / btn-save-sm: 30×30, primary/20 bg, no border -->
962
+ <button class="inline-flex items-center justify-center w-[30px] h-[30px] bg-primary/20 hover:bg-primary/30 text-primary rounded transition-all duration-200" title="Edit (btn-edit-sm)">
963
+ <svg class="w-3.5 h-3.5"><use href="#ic-edit-2"/></svg>
964
+ </button>
965
+ <button class="inline-flex items-center justify-center w-[30px] h-[30px] bg-primary/20 hover:bg-primary/30 text-primary rounded transition-all duration-200" title="Save (btn-save-sm)">
966
+ <svg class="w-3.5 h-3.5"><use href="#ic-save"/></svg>
967
+ </button>
968
+ <!-- btn-close-sm: 30×30, section bg (#F6F7FB), steel color -->
969
+ <button class="inline-flex items-center justify-center w-[30px] h-[30px] bg-section hover:bg-muted text-ink-steel rounded transition-all duration-200" title="Close (btn-close-sm)">
970
+ <svg class="w-3.5 h-3.5"><use href="#ic-x"/></svg>
971
+ </button>
972
+ <!-- btn-trash: 32×32, #fcefef bg, danger color, no border -->
973
+ <button class="inline-flex items-center justify-center w-8 h-8 bg-[#fcefef] hover:bg-[#fae0e0] text-bad rounded transition-all duration-200" title="Delete (btn-trash)">
974
+ <svg class="w-3.5 h-3.5"><use href="#ic-trash"/></svg>
975
+ </button>
976
+ <!-- btn-copy-sm: h=28, px=10, primary text+border, neutral border -->
977
+ <button class="inline-flex items-center gap-1.5 h-7 px-[10px] bg-transparent hover:bg-primary-light text-primary text-body font-semibold rounded border border-[rgba(72,91,120,0.15)] transition-all duration-200">
978
+ <svg class="w-3.5 h-3.5"><use href="#ic-copy"/></svg> Copy
979
+ </button>
980
+ <!-- btn-sm-db-arrow: 30×30, white, neutral border, navigate -->
981
+ <button class="inline-flex items-center justify-center w-[30px] h-[30px] bg-white hover:bg-muted text-ink-steel rounded border border-[rgba(72,91,120,0.15)] transition-all duration-200" title="Navigate (btn-sm-db-arrow)">
982
+ <svg class="w-3.5 h-3.5"><use href="#ic-chevron-right"/></svg>
983
+ </button>
984
+ </div>
985
+
986
+ <!-- btn-plus-sm: icon square + label inline -->
987
+ <div class="flex items-center gap-3 mb-6 flex-wrap">
988
+ <span class="state-label">btn-plus-sm</span>
989
+ <button class="inline-flex items-center gap-2 bg-transparent hover:opacity-80 text-primary transition-opacity duration-200">
990
+ <span class="inline-flex items-center justify-center w-[30px] h-[30px] bg-primary/20 rounded">
991
+ <svg class="w-3.5 h-3.5"><use href="#ic-plus"/></svg>
992
+ </span>
993
+ <span class="text-body font-medium">Add item</span>
994
+ </button>
995
+ </div>
996
+
997
+ <div class="snippet">
998
+ <button class="copy-btn" onclick="copySnippet(this)">Copy</button>
999
+ <pre>
1000
+ &lt;!-- btn-b-gray — 32px, white bg, steel text, faint border --&gt;
1001
+ &lt;button class="inline-flex items-center gap-1.5 h-8 px-[14px]
1002
+ bg-white hover:bg-muted text-ink-steel text-body font-semibold rounded
1003
+ border border-[rgba(72,91,120,0.15)] transition-all duration-200"&gt;
1004
+ Filter
1005
+ &lt;/button&gt;
1006
+
1007
+ &lt;!-- btn-add-grey — 40px, transparent, steel, faint border, 14px/500 --&gt;
1008
+ &lt;button class="inline-flex items-center gap-2 h-10 px-[10px]
1009
+ bg-transparent text-ink-steel text-body font-medium rounded
1010
+ border border-[rgba(72,91,120,0.15)] transition-all duration-200"&gt;
1011
+ Add department
1012
+ &lt;/button&gt;
1013
+
1014
+ &lt;!-- btn-cancel-red — 40px, white bg, #FB5A56 text+border --&gt;
1015
+ &lt;button class="inline-flex items-center gap-2 h-10 px-5
1016
+ bg-white text-[#FB5A56] text-action font-semibold rounded
1017
+ border border-[#FB5A56] transition-all duration-200"&gt;
1018
+ Cancel booking
1019
+ &lt;/button&gt;
1020
+
1021
+ &lt;!-- btn-edit-sm / btn-save-sm — 30×30, primary/20 bg --&gt;
1022
+ &lt;button class="inline-flex items-center justify-center w-[30px] h-[30px]
1023
+ bg-primary/20 hover:bg-primary/30 text-primary rounded transition-all duration-200"&gt;
1024
+ &lt;svg class="w-3.5 h-3.5"&gt;&lt;use href="#ic-edit-2"/&gt;&lt;/svg&gt;
1025
+ &lt;/button&gt;
1026
+
1027
+ &lt;!-- btn-close-sm — 30×30, section bg --&gt;
1028
+ &lt;button class="inline-flex items-center justify-center w-[30px] h-[30px]
1029
+ bg-section hover:bg-muted text-ink-steel rounded transition-all duration-200"&gt;
1030
+ &lt;svg class="w-3.5 h-3.5"&gt;&lt;use href="#ic-x"/&gt;&lt;/svg&gt;
1031
+ &lt;/button&gt;
1032
+
1033
+ &lt;!-- btn-trash — 32×32, #fcefef bg --&gt;
1034
+ &lt;button class="inline-flex items-center justify-center w-8 h-8
1035
+ bg-[#fcefef] hover:bg-[#fae0e0] text-bad rounded transition-all duration-200"&gt;
1036
+ &lt;svg class="w-3.5 h-3.5"&gt;&lt;use href="#ic-trash"/&gt;&lt;/svg&gt;
1037
+ &lt;/button&gt;
1038
+
1039
+ &lt;!-- btn-copy-sm — 28px, primary text, faint border --&gt;
1040
+ &lt;button class="inline-flex items-center gap-1.5 h-7 px-[10px]
1041
+ bg-transparent text-primary text-body font-semibold rounded
1042
+ border border-[rgba(72,91,120,0.15)] transition-all duration-200"&gt;
1043
+ &lt;svg class="w-3.5 h-3.5"&gt;&lt;use href="#ic-copy"/&gt;&lt;/svg&gt; Copy
1044
+ &lt;/button&gt;
1045
+
1046
+ &lt;!-- btn-plus-sm — icon square + inline label --&gt;
1047
+ &lt;button class="inline-flex items-center gap-2 text-primary"&gt;
1048
+ &lt;span class="inline-flex items-center justify-center w-[30px] h-[30px] bg-primary/20 rounded"&gt;
1049
+ &lt;svg class="w-3.5 h-3.5"&gt;&lt;use href="#ic-plus"/&gt;&lt;/svg&gt;
1050
+ &lt;/span&gt;
1051
+ &lt;span class="text-body font-medium"&gt;Add item&lt;/span&gt;
1052
+ &lt;/button&gt;</pre>
1053
+ </div>
1054
+
1055
+ <div class="snippet" style="margin-top:12px">
1056
+ <button class="copy-btn" onclick="copySnippet(this)">Copy</button>
1057
+ <pre>
1058
+ &lt;!-- Primary (btn-primary) — 40px/600/6px, hover:#149AD1 --&gt;
1059
+ &lt;button class="inline-flex items-center gap-2 h-10 px-5
1060
+ bg-primary hover:bg-primary-hover text-white
1061
+ text-action font-semibold rounded
1062
+ transition-all duration-200
1063
+ focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary
1064
+ disabled:opacity-60 disabled:cursor-not-allowed"&gt;
1065
+ Save
1066
+ &lt;/button&gt;
1067
+
1068
+ &lt;!-- Outline Primary (btn-hf-outline-primary) — hover:bg-muted --&gt;
1069
+ &lt;button class="inline-flex items-center gap-2 h-10 px-5
1070
+ bg-white hover:bg-muted text-primary border border-primary
1071
+ text-action font-semibold rounded transition-all duration-200"&gt;
1072
+ Outline Primary
1073
+ &lt;/button&gt;
1074
+
1075
+ &lt;!-- Outline Default (btn-hf-outline-default) — steel text, neutral border, shadow --&gt;
1076
+ &lt;button class="inline-flex items-center gap-2 h-10 px-5
1077
+ bg-white hover:bg-muted text-ink-steel border border-border shadow-outline
1078
+ text-action font-semibold rounded transition-all duration-200"&gt;
1079
+ Back
1080
+ &lt;/button&gt;
1081
+
1082
+ &lt;!-- Cancel (btn-cancel) — white bg, muted text, very light hover --&gt;
1083
+ &lt;button class="inline-flex items-center h-10 px-5
1084
+ bg-white hover:bg-[rgba(190,198,212,0.1)] text-ink-muted
1085
+ text-action font-semibold rounded transition-all duration-200"&gt;
1086
+ Cancel
1087
+ &lt;/button&gt;
1088
+
1089
+ &lt;!-- Danger (btn-danger) — #D9534F bg --&gt;
1090
+ &lt;button class="inline-flex items-center gap-2 h-10 px-5
1091
+ bg-danger hover:bg-danger-hover text-white
1092
+ text-action font-semibold rounded transition-all duration-200"&gt;
1093
+ Delete
1094
+ &lt;/button&gt;
1095
+
1096
+ &lt;!-- Reset Filters — 38px/500/14px, #EFF6FF --&gt;
1097
+ &lt;button class="inline-flex items-center gap-2 h-[38px] px-[10px]
1098
+ bg-primary-tint hover:bg-primary-tint-hover text-primary
1099
+ text-body font-medium rounded border border-primary/20 transition-all duration-200"&gt;
1100
+ Reset Filters
1101
+ &lt;/button&gt;</pre>
1102
+ </div>
1103
+ </section>
1104
+
1105
+ <!-- ════════════════════════════════════════════════════════════════ -->
1106
+ <!-- INPUTS -->
1107
+ <!-- ════════════════════════════════════════════════════════════════ -->
1108
+ <section id="inputs" class="mb-16">
1109
+ <div class="section-title">Inputs</div>
1110
+ <div class="section-desc">h-[39px] · 14px/400 · 6px radius · border #D1D6DD · focus: border darkens to #B2BAC4 (portal exact) · placeholder/disabled: #AEBCCF.</div>
1111
+
1112
+ <!-- States -->
1113
+ <div class="sub-title">States</div>
1114
+ <div class="grid grid-cols-2 gap-5 mb-6">
1115
+ <div>
1116
+ <div class="state-label mb-2">Default</div>
1117
+ <input type="text" placeholder="Enter full name"
1118
+ class="w-full h-[39px] px-3 bg-white border border-border rounded text-body text-ink placeholder:text-ink-faint transition-colors hover:border-border-strong focus:outline-none focus:border-border-strong" />
1119
+ </div>
1120
+ <div>
1121
+ <div class="state-label mb-2">Focus <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">portal: border-strong only</span></div>
1122
+ <input type="text" value="John Doe"
1123
+ class="w-full h-[39px] px-3 bg-white border border-border-strong rounded text-body text-ink outline-none" />
1124
+ </div>
1125
+ <div>
1126
+ <div class="state-label mb-2">Focus <span class="text-ok text-caption font-normal normal-case tracking-normal">+ accessible ring ✓</span></div>
1127
+ <input type="text" value="John Doe"
1128
+ class="w-full h-[39px] px-3 bg-white border border-primary ring-2 ring-primary/20 rounded text-body text-ink outline-none" />
1129
+ </div>
1130
+ <div>
1131
+ <div class="state-label mb-2">Disabled</div>
1132
+ <!-- bg=#FBFBFC (page), text=#AEBCCF (ink-faint), border unchanged -->
1133
+ <input type="text" value="Locked value" disabled
1134
+ class="w-full h-[39px] px-3 bg-page border border-border rounded text-body text-ink-faint cursor-not-allowed" />
1135
+ </div>
1136
+ </div>
1137
+
1138
+ <!-- Validation states -->
1139
+ <div class="sub-title">Validation</div>
1140
+ <div class="grid grid-cols-2 gap-5 mb-6">
1141
+ <!-- Error with portal help-block -->
1142
+ <div>
1143
+ <label class="block text-meta font-medium text-ink-secondary mb-1.5">Email <span class="text-bad">*</span></label>
1144
+ <input type="email" value="not-an-email"
1145
+ class="w-full h-[39px] px-3 bg-white border border-bad rounded text-body text-ink focus:outline-none focus:ring-2 focus:ring-bad/20" />
1146
+ <!-- .has-error .help-block: 11px, #ea6565, rgba(234,101,101,.1) bg, 4px radius, padding 7px 10px 9px -->
1147
+ <div class="mt-[5px] pt-[7px] px-[10px] pb-[9px] bg-bad/10 text-bad text-caption rounded-[4px]">
1148
+ Please enter a valid email address.
1149
+ </div>
1150
+ </div>
1151
+ <!-- Error with inline icon tip -->
1152
+ <div>
1153
+ <label class="block text-meta font-medium text-ink-secondary mb-1.5">Hotel name <span class="text-bad">*</span></label>
1154
+ <input type="text" placeholder="Required"
1155
+ class="w-full h-[39px] px-3 bg-white border border-bad rounded text-body text-ink focus:outline-none" />
1156
+ <p class="flex items-center gap-1 text-caption text-bad mt-1">
1157
+ <svg class="w-3 h-3 shrink-0"><use href="#ic-alert-circle"/></svg>
1158
+ This field is required
1159
+ </p>
1160
+ </div>
1161
+ <!-- Valid -->
1162
+ <div>
1163
+ <label class="block text-meta font-medium text-ink-secondary mb-1.5">Username</label>
1164
+ <input type="text" value="john.doe"
1165
+ class="w-full h-[39px] px-3 bg-white border border-ok rounded text-body text-ink focus:outline-none focus:ring-2 focus:ring-ok/20" />
1166
+ <p class="flex items-center gap-1 text-caption text-ok mt-1">
1167
+ <svg class="w-3 h-3 shrink-0"><use href="#ic-check-circle"/></svg>
1168
+ Username is available
1169
+ </p>
1170
+ </div>
1171
+ <!-- Helper text -->
1172
+ <div>
1173
+ <label class="block text-meta font-medium text-ink-secondary mb-1.5">Password</label>
1174
+ <input type="password" placeholder="••••••••"
1175
+ class="w-full h-[39px] px-3 bg-white border border-border rounded text-body text-ink placeholder:text-ink-faint focus:outline-none focus:border-border-strong" />
1176
+ <p class="text-caption text-ink-secondary mt-1">At least 8 characters, mix of letters and numbers.</p>
1177
+ </div>
1178
+ </div>
1179
+
1180
+ <!-- Input variants -->
1181
+ <div class="sub-title">Variants</div>
1182
+ <div class="grid grid-cols-2 gap-5 mb-6">
1183
+ <!-- Search -->
1184
+ <div>
1185
+ <div class="state-label mb-2">Search</div>
1186
+ <div class="relative">
1187
+ <svg class="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-ink-faint pointer-events-none"><use href="#ic-search"/></svg>
1188
+ <input type="text" placeholder="Search bookings…"
1189
+ class="w-full h-[39px] pl-9 pr-3 bg-white border border-border rounded text-body text-ink placeholder:text-ink-faint transition-colors hover:border-border-strong focus:outline-none focus:border-border-strong" />
1190
+ </div>
1191
+ </div>
1192
+ <!-- Icon suffix (date picker) -->
1193
+ <div>
1194
+ <div class="state-label mb-2">With icon suffix</div>
1195
+ <div class="relative">
1196
+ <input type="text" value="2024-12-01" readonly
1197
+ class="w-full h-[39px] pl-3 pr-9 bg-white border border-border rounded text-body text-ink transition-colors hover:border-border-strong focus:outline-none focus:border-border-strong cursor-pointer" />
1198
+ <svg class="w-4 h-4 absolute right-3 top-1/2 -translate-y-1/2 text-ink-faint pointer-events-none"><use href="#ic-calendar"/></svg>
1199
+ </div>
1200
+ </div>
1201
+ <!-- Select -->
1202
+ <div>
1203
+ <div class="state-label mb-2">Select</div>
1204
+ <div class="relative">
1205
+ <select class="w-full h-[39px] pl-3 pr-9 bg-white border border-border rounded text-body text-ink-secondary appearance-none transition-colors hover:border-border-strong focus:outline-none focus:border-border-strong">
1206
+ <option value="">All statuses</option>
1207
+ <option>Confirmed</option><option>Cancelled</option><option>No show</option>
1208
+ </select>
1209
+ <svg class="w-4 h-4 absolute right-3 top-1/2 -translate-y-1/2 text-ink-faint pointer-events-none"><use href="#ic-chevron-down"/></svg>
1210
+ </div>
1211
+ </div>
1212
+ <!-- Textarea -->
1213
+ <div>
1214
+ <div class="state-label mb-2">Textarea</div>
1215
+ <textarea placeholder="Add a note…" rows="3"
1216
+ class="w-full px-3 py-2 bg-white border border-border rounded text-body text-ink placeholder:text-ink-faint resize-none transition-colors hover:border-border-strong focus:outline-none focus:border-border-strong"></textarea>
1217
+ </div>
1218
+ </div>
1219
+
1220
+ <!-- Checkbox & Radio (portal .mt-checkbox-outline: 18×18, 6px radius, 1px #DBDFE9 border, filled primary when checked) -->
1221
+ <div class="sub-title">Checkbox &amp; Radio</div>
1222
+ <div class="grid grid-cols-2 gap-5 mb-6">
1223
+ <div class="space-y-3">
1224
+ <label class="flex items-center gap-2.5 cursor-pointer select-none">
1225
+ <input type="checkbox" checked class="hf-check" />
1226
+ <span class="text-body text-ink">Checked</span>
1227
+ </label>
1228
+ <label class="flex items-center gap-2.5 cursor-pointer select-none">
1229
+ <input type="checkbox" class="hf-check" />
1230
+ <span class="text-body text-ink">Unchecked</span>
1231
+ </label>
1232
+ <label class="flex items-center gap-2.5 cursor-not-allowed select-none">
1233
+ <input type="checkbox" checked disabled class="hf-check" />
1234
+ <span class="text-body text-ink-faint">Disabled — locked on</span>
1235
+ </label>
1236
+ </div>
1237
+ <div class="space-y-3">
1238
+ <label class="flex items-center gap-2.5 cursor-pointer select-none">
1239
+ <input type="radio" name="demo-r" checked class="hf-radio" />
1240
+ <span class="text-body text-ink">Option A</span>
1241
+ </label>
1242
+ <label class="flex items-center gap-2.5 cursor-pointer select-none">
1243
+ <input type="radio" name="demo-r" class="hf-radio" />
1244
+ <span class="text-body text-ink">Option B</span>
1245
+ </label>
1246
+ <label class="flex items-center gap-2.5 cursor-not-allowed select-none">
1247
+ <input type="radio" name="demo-r2" disabled class="hf-radio" />
1248
+ <span class="text-body text-ink-faint">Disabled</span>
1249
+ </label>
1250
+ </div>
1251
+ </div>
1252
+
1253
+ <!-- Toggle (bootstrap-switch equivalent) -->
1254
+ <!-- Off bg: #DFDFDF · On bg: #24AFE8 · thumb: white 20×20, shadow 0 1px 6px rgba(0,0,0,.3) -->
1255
+ <div class="sub-title">Toggle</div>
1256
+ <div class="flex flex-col gap-3 mb-6">
1257
+ <label class="flex items-center gap-3 cursor-pointer select-none">
1258
+ <div class="relative w-[52px] h-[28px]">
1259
+ <input type="checkbox" checked class="sr-only peer" />
1260
+ <div class="absolute inset-0 rounded-full bg-[#DFDFDF] peer-checked:bg-primary transition-colors duration-200"></div>
1261
+ <div class="absolute top-[4px] left-[4px] w-5 h-5 bg-white rounded-full shadow-[0_1px_6px_0_rgba(0,0,0,.3)] transition-transform duration-200 peer-checked:translate-x-6"></div>
1262
+ </div>
1263
+ <span class="text-body text-ink">Enabled (on)</span>
1264
+ </label>
1265
+ <label class="flex items-center gap-3 cursor-pointer select-none">
1266
+ <div class="relative w-[52px] h-[28px]">
1267
+ <input type="checkbox" class="sr-only peer" />
1268
+ <div class="absolute inset-0 rounded-full bg-[#DFDFDF] peer-checked:bg-primary transition-colors duration-200"></div>
1269
+ <div class="absolute top-[4px] left-[4px] w-5 h-5 bg-white rounded-full shadow-[0_1px_6px_0_rgba(0,0,0,.3)] transition-transform duration-200 peer-checked:translate-x-6"></div>
1270
+ </div>
1271
+ <span class="text-body text-ink">Disabled (off)</span>
1272
+ </label>
1273
+ <label class="flex items-center gap-3 cursor-not-allowed select-none opacity-50">
1274
+ <div class="relative w-[52px] h-[28px]">
1275
+ <input type="checkbox" checked disabled class="sr-only peer" />
1276
+ <div class="absolute inset-0 rounded-full bg-primary"></div>
1277
+ <div class="absolute top-[4px] left-[4px] w-5 h-5 bg-white rounded-full shadow-[0_1px_6px_0_rgba(0,0,0,.3)] translate-x-6"></div>
1278
+ </div>
1279
+ <span class="text-body text-ink">Locked on</span>
1280
+ </label>
1281
+ </div>
1282
+
1283
+ <!-- Label + input form card -->
1284
+ <div class="sub-title">Label + input pattern</div>
1285
+ <div class="grid grid-cols-2 gap-5 p-5 bg-white rounded-lg border border-border-light shadow-card mb-4">
1286
+ <div>
1287
+ <label class="block text-meta font-medium text-ink-secondary mb-1.5">First name</label>
1288
+ <input type="text" placeholder="John"
1289
+ class="w-full h-[39px] px-3 bg-white border border-border rounded text-body text-ink placeholder:text-ink-faint focus:outline-none focus:border-border-strong" />
1290
+ </div>
1291
+ <div>
1292
+ <label class="block text-meta font-medium text-ink-secondary mb-1.5">Last name</label>
1293
+ <input type="text" placeholder="Doe"
1294
+ class="w-full h-[39px] px-3 bg-white border border-border rounded text-body text-ink placeholder:text-ink-faint focus:outline-none focus:border-border-strong" />
1295
+ </div>
1296
+ <div class="col-span-2">
1297
+ <label class="block text-meta font-medium text-ink-secondary mb-1.5">
1298
+ Email <span class="text-bad">*</span>
1299
+ </label>
1300
+ <div class="relative">
1301
+ <input type="email" value="not-an-email"
1302
+ class="w-full h-[39px] pl-3 pr-9 bg-white border border-bad rounded text-body text-ink focus:outline-none" />
1303
+ <svg class="w-4 h-4 absolute right-3 top-1/2 -translate-y-1/2 text-bad pointer-events-none"><use href="#ic-alert-circle"/></svg>
1304
+ </div>
1305
+ <div class="mt-[5px] pt-[7px] px-[10px] pb-[9px] bg-bad/10 text-bad text-caption rounded-[4px]">
1306
+ Please enter a valid email address.
1307
+ </div>
1308
+ </div>
1309
+ <div class="col-span-2">
1310
+ <label class="block text-meta font-medium text-ink-secondary mb-1.5">Notes</label>
1311
+ <textarea placeholder="Optional notes…" rows="3"
1312
+ class="w-full px-3 py-2 bg-white border border-border rounded text-body text-ink placeholder:text-ink-faint resize-none focus:outline-none focus:border-border-strong"></textarea>
1313
+ </div>
1314
+ </div>
1315
+
1316
+ <div class="snippet">
1317
+ <button class="copy-btn" onclick="copySnippet(this)">Copy</button>
1318
+ <pre>
1319
+ &lt;!-- Text input — 39px/14px/6px, portal exact --&gt;
1320
+ &lt;input type="text" placeholder="…"
1321
+ class="w-full h-[39px] px-3 bg-white border border-border rounded
1322
+ text-body text-ink placeholder:text-ink-faint
1323
+ transition-colors hover:border-border-strong
1324
+ focus:outline-none focus:border-border-strong
1325
+ disabled:bg-page disabled:text-ink-faint disabled:cursor-not-allowed" /&gt;
1326
+
1327
+ &lt;!-- Accessible ring (recommended for new projects) --&gt;
1328
+ &lt;input type="text"
1329
+ class="… focus:border-primary focus:ring-2 focus:ring-primary/20" /&gt;
1330
+
1331
+ &lt;!-- Error: border + portal .has-error .help-block --&gt;
1332
+ &lt;input class="… border-bad" /&gt;
1333
+ &lt;div class="mt-[5px] pt-[7px] px-[10px] pb-[9px]
1334
+ bg-bad/10 text-bad text-caption rounded-[4px]"&gt;
1335
+ Error message
1336
+ &lt;/div&gt;
1337
+
1338
+ &lt;!-- Select --&gt;
1339
+ &lt;div class="relative"&gt;
1340
+ &lt;select class="w-full h-[39px] pl-3 pr-9 bg-white border border-border rounded
1341
+ text-body text-ink-secondary appearance-none
1342
+ focus:outline-none focus:border-border-strong"&gt;
1343
+ &lt;option&gt;…&lt;/option&gt;
1344
+ &lt;/select&gt;
1345
+ &lt;svg class="w-4 h-4 absolute right-3 top-1/2 -translate-y-1/2 text-ink-faint pointer-events-none"&gt;
1346
+ &lt;use href="#ic-chevron-down"/&gt;
1347
+ &lt;/svg&gt;
1348
+ &lt;/div&gt;
1349
+
1350
+ &lt;!-- Checkbox / Radio — portal .mt-checkbox-outline (18×18, 6px radius, filled primary) --&gt;
1351
+ &lt;label class="flex items-center gap-2.5 cursor-pointer"&gt;
1352
+ &lt;input type="checkbox" class="hf-check" /&gt;
1353
+ &lt;span class="text-body text-ink"&gt;Label&lt;/span&gt;
1354
+ &lt;/label&gt;
1355
+ &lt;label class="flex items-center gap-2.5 cursor-pointer"&gt;
1356
+ &lt;input type="radio" name="opt" class="hf-radio" /&gt;
1357
+ &lt;span class="text-body text-ink"&gt;Option&lt;/span&gt;
1358
+ &lt;/label&gt;
1359
+
1360
+ &lt;!-- Toggle — off:#DFDFDF on:#24AFE8 --&gt;
1361
+ &lt;label class="flex items-center gap-3 cursor-pointer"&gt;
1362
+ &lt;div class="relative w-[52px] h-[28px]"&gt;
1363
+ &lt;input type="checkbox" class="sr-only peer" /&gt;
1364
+ &lt;div class="absolute inset-0 rounded-full bg-[#DFDFDF] peer-checked:bg-primary transition-colors duration-200"&gt;&lt;/div&gt;
1365
+ &lt;div class="absolute top-[4px] left-[4px] w-5 h-5 bg-white rounded-full
1366
+ shadow-[0_1px_6px_0_rgba(0,0,0,.3)] transition-transform duration-200
1367
+ peer-checked:translate-x-6"&gt;&lt;/div&gt;
1368
+ &lt;/div&gt;
1369
+ &lt;span class="text-body text-ink"&gt;Label&lt;/span&gt;
1370
+ &lt;/label&gt;</pre>
1371
+ </div>
1372
+ </section>
1373
+
1374
+ <!-- ════════════════════════════════════════════════════════════════ -->
1375
+ <!-- CARDS -->
1376
+ <!-- ════════════════════════════════════════════════════════════════ -->
1377
+ <section id="cards" class="mb-16">
1378
+ <div class="section-title">Cards</div>
1379
+ <div class="section-desc">Three patterns — bordered (default), elevated (subtle shadow), combined (filters + table). Padding 15–20px.</div>
1380
+
1381
+ <!-- 1. Bordered card (most common — .portlet.light) -->
1382
+ <div class="sub-title">Bordered <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">most common · no shadow · 1px #D1D6DD</span></div>
1383
+ <div class="grid grid-cols-2 gap-5 mb-6">
1384
+ <div class="bg-white rounded-lg border border-border p-5">
1385
+ <div class="text-action font-semibold text-ink mb-1">Section title</div>
1386
+ <div class="text-body text-ink-secondary">List, form, or table panels. Default container in lists/edit pages.</div>
1387
+ </div>
1388
+ <div class="bg-white rounded-lg border border-border p-5">
1389
+ <div class="flex items-center justify-between mb-3">
1390
+ <div class="text-action font-semibold text-ink">Hotel settings</div>
1391
+ <button class="inline-flex items-center justify-center w-8 h-8 bg-transparent hover:bg-muted text-ink-steel rounded transition-all duration-200">
1392
+ <svg class="w-4 h-4"><use href="#ic-more-vertical"/></svg>
1393
+ </button>
1394
+ </div>
1395
+ <div class="text-body text-ink-secondary">With title row + actions slot.</div>
1396
+ </div>
1397
+ </div>
1398
+
1399
+ <!-- 2. Elevated card (.dashboard-card — subtle shadow) -->
1400
+ <div class="sub-title">Elevated <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">.dashboard-card · shadow-subtle · 6px radius</span></div>
1401
+ <div class="grid grid-cols-3 gap-5 mb-6">
1402
+ <!-- KPI card -->
1403
+ <div class="bg-white rounded border border-[rgba(72,91,120,0.05)] shadow-subtle p-4 flex flex-col gap-1">
1404
+ <div class="text-meta font-medium text-ink-secondary">Total bookings</div>
1405
+ <div class="text-3xl font-semibold text-primary">1 284</div>
1406
+ <div class="text-caption text-ok flex items-center gap-1">
1407
+ <svg class="w-3 h-3"><use href="#ic-check"/></svg> +12% vs last week
1408
+ </div>
1409
+ </div>
1410
+ <!-- KPI with icon -->
1411
+ <div class="bg-white rounded border border-[rgba(72,91,120,0.05)] shadow-subtle p-4 flex items-center gap-3">
1412
+ <div class="w-10 h-10 rounded-full bg-primary-light flex items-center justify-center shrink-0">
1413
+ <svg class="w-5 h-5 text-primary"><use href="#ic-check-circle"/></svg>
1414
+ </div>
1415
+ <div class="flex-1 min-w-0">
1416
+ <div class="text-meta font-medium text-ink-secondary">Confirmed</div>
1417
+ <div class="text-title font-semibold text-ink">842</div>
1418
+ </div>
1419
+ </div>
1420
+ <!-- Stacked stats -->
1421
+ <div class="bg-white rounded border border-[rgba(72,91,120,0.05)] shadow-subtle p-4 flex flex-col gap-2">
1422
+ <div class="text-meta font-medium text-ink-secondary">Revenue</div>
1423
+ <div class="text-title font-semibold text-ink">€ 24 850</div>
1424
+ <div class="h-1 bg-muted rounded-full overflow-hidden">
1425
+ <div class="h-full bg-primary rounded-full" style="width: 72%"></div>
1426
+ </div>
1427
+ <div class="text-caption text-ink-secondary">72% of monthly target</div>
1428
+ </div>
1429
+ </div>
1430
+
1431
+ <!-- 3. Combined card (hf-filters + footergrid pattern) -->
1432
+ <div class="sub-title">Combined <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">filters-bar + table · 12px outer radius · shared 1px border</span></div>
1433
+ <div class="border border-border rounded-lg overflow-hidden mb-6">
1434
+ <!-- top: filters bar -->
1435
+ <div class="bg-white p-5 flex items-center gap-3 flex-wrap">
1436
+ <div class="relative">
1437
+ <svg class="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-ink-faint pointer-events-none"><use href="#ic-search"/></svg>
1438
+ <input type="text" placeholder="Search…" class="h-[39px] pl-9 pr-3 bg-white border border-border rounded text-body text-ink placeholder:text-ink-faint focus:outline-none focus:border-border-strong" />
1439
+ </div>
1440
+ <button class="inline-flex items-center gap-2 h-[38px] px-[10px] bg-primary-tint hover:bg-primary-tint-hover text-primary text-body font-medium rounded border border-primary/20 transition-all duration-200">
1441
+ <svg class="w-4 h-4"><use href="#ic-filter"/></svg> Filters
1442
+ </button>
1443
+ <button class="inline-flex items-center gap-2 h-[38px] px-[10px] bg-primary-tint hover:bg-primary-tint-hover text-primary text-body font-medium rounded border border-primary/20 transition-all duration-200">
1444
+ <svg class="w-4 h-4"><use href="#ic-refresh-cw"/></svg> Reset
1445
+ </button>
1446
+ </div>
1447
+ <!-- separator -->
1448
+ <div class="border-t border-border"></div>
1449
+ <!-- body: table -->
1450
+ <div class="bg-white">
1451
+ <table class="w-full text-body">
1452
+ <thead class="bg-section">
1453
+ <tr class="text-meta font-medium text-ink-steel uppercase tracking-wider">
1454
+ <th class="text-left px-5 py-3">ID</th>
1455
+ <th class="text-left px-5 py-3">Guest</th>
1456
+ <th class="text-left px-5 py-3">Status</th>
1457
+ </tr>
1458
+ </thead>
1459
+ <tbody class="divide-y divide-border">
1460
+ <tr class="text-ink">
1461
+ <td class="px-5 py-3">#1284</td>
1462
+ <td class="px-5 py-3">Amanda Peterson</td>
1463
+ <td class="px-5 py-3"><span class="hf-pill status-booking-confirmed">Confirmed</span></td>
1464
+ </tr>
1465
+ <tr class="text-ink">
1466
+ <td class="px-5 py-3">#1283</td>
1467
+ <td class="px-5 py-3">Marcus Schulz</td>
1468
+ <td class="px-5 py-3"><span class="hf-pill status-booking-new">New</span></td>
1469
+ </tr>
1470
+ </tbody>
1471
+ </table>
1472
+ </div>
1473
+ <!-- footer -->
1474
+ <div class="bg-section border-t border-border px-5 py-3 flex items-center justify-between text-body text-ink-secondary">
1475
+ <span>2 of 12 results</span>
1476
+ <div class="flex items-center gap-1">
1477
+ <button class="inline-flex items-center justify-center w-8 h-8 bg-white hover:bg-muted text-ink-steel rounded border border-border-light">
1478
+ <svg class="w-3.5 h-3.5"><use href="#ic-chevron-left"/></svg>
1479
+ </button>
1480
+ <button class="inline-flex items-center justify-center w-8 h-8 bg-white hover:bg-muted text-ink-steel rounded border border-border-light">
1481
+ <svg class="w-3.5 h-3.5"><use href="#ic-chevron-right"/></svg>
1482
+ </button>
1483
+ </div>
1484
+ </div>
1485
+ </div>
1486
+
1487
+ <!-- 4. Sub-tiles (inside cards) -->
1488
+ <div class="sub-title">Sub-tiles <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">empty states · 4px radius · steel-transparent border</span></div>
1489
+ <div class="bg-white rounded-lg border border-border p-5 mb-6">
1490
+ <div class="text-action font-semibold text-ink mb-4">Guest Management</div>
1491
+ <div class="grid grid-cols-3 gap-3">
1492
+ <div class="rounded-[4px] border border-[rgba(72,91,120,0.15)] p-5 flex flex-col items-center justify-center gap-2 min-h-[120px]">
1493
+ <svg class="w-6 h-6 text-ok"><use href="#ic-calendar"/></svg>
1494
+ <div class="text-meta text-ink-secondary">No arrivals yet</div>
1495
+ </div>
1496
+ <div class="rounded-[4px] border border-[rgba(72,91,120,0.15)] p-5 flex flex-col items-center justify-center gap-2 min-h-[120px]">
1497
+ <svg class="w-6 h-6 text-coral"><use href="#ic-calendar"/></svg>
1498
+ <div class="text-meta text-ink-secondary">No departures yet</div>
1499
+ </div>
1500
+ <div class="rounded-[4px] border border-[rgba(72,91,120,0.15)] p-5 flex flex-col items-center justify-center gap-2 min-h-[120px]">
1501
+ <svg class="w-6 h-6 text-primary"><use href="#ic-check"/></svg>
1502
+ <div class="text-meta text-ink-secondary">No guest in house yet</div>
1503
+ </div>
1504
+ </div>
1505
+ </div>
1506
+
1507
+ <!-- 5. Info / accent block -->
1508
+ <div class="sub-title">Info block <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">section bg · no shadow</span></div>
1509
+ <div class="grid grid-cols-2 gap-5 mb-6">
1510
+ <div class="bg-section border border-border-light rounded p-4">
1511
+ <div class="text-meta font-medium text-ink-secondary mb-1">Hint</div>
1512
+ <div class="text-body text-ink">Section bg, 6px radius. Inline notices, helper panels.</div>
1513
+ </div>
1514
+ <div class="bg-primary-tint border border-primary/20 rounded p-4">
1515
+ <div class="flex items-center gap-2 text-primary text-meta font-medium mb-1">
1516
+ <svg class="w-4 h-4"><use href="#ic-info"/></svg> Did you know?
1517
+ </div>
1518
+ <div class="text-body text-ink">Primary-tint accent — for tips, callouts, "what's new".</div>
1519
+ </div>
1520
+ </div>
1521
+
1522
+ <div class="snippet">
1523
+ <button class="copy-btn" onclick="copySnippet(this)">Copy</button>
1524
+ <pre>
1525
+ &lt;!-- 1. Bordered card (most common — .portlet.light, no shadow) --&gt;
1526
+ &lt;div class="bg-white rounded-lg border border-border p-5"&gt; … &lt;/div&gt;
1527
+
1528
+ &lt;!-- 2. Elevated card (.dashboard-card — subtle 2px/4px shadow) --&gt;
1529
+ &lt;div class="bg-white rounded border border-[rgba(72,91,120,0.05)] shadow-subtle p-4"&gt;
1530
+ … KPI / dashboard tile …
1531
+ &lt;/div&gt;
1532
+
1533
+ &lt;!-- 3. Combined card (filters bar + table) — 12px outer radius, shared border --&gt;
1534
+ &lt;div class="border border-border rounded-lg overflow-hidden"&gt;
1535
+ &lt;div class="bg-white p-5 flex items-center gap-3"&gt; … filters … &lt;/div&gt;
1536
+ &lt;div class="border-t border-border"&gt;&lt;/div&gt;
1537
+ &lt;div class="bg-white"&gt; … table … &lt;/div&gt;
1538
+ &lt;div class="bg-section border-t border-border px-5 py-3"&gt; … pagination … &lt;/div&gt;
1539
+ &lt;/div&gt;
1540
+
1541
+ &lt;!-- 4. Sub-tile (empty state inside a card) --&gt;
1542
+ &lt;div class="rounded-[4px] border border-[rgba(72,91,120,0.15)] p-5 flex flex-col items-center justify-center gap-2"&gt;
1543
+ &lt;svg class="w-6 h-6"&gt;&lt;use href="#ic-calendar"/&gt;&lt;/svg&gt;
1544
+ &lt;div class="text-meta text-ink-secondary"&gt;No data yet&lt;/div&gt;
1545
+ &lt;/div&gt;
1546
+
1547
+ &lt;!-- 5. Info block (section bg accent) --&gt;
1548
+ &lt;div class="bg-section border border-border-light rounded p-4"&gt; … &lt;/div&gt;
1549
+ &lt;div class="bg-primary-tint border border-primary/20 rounded p-4"&gt; … tip … &lt;/div&gt;</pre>
1550
+ </div>
1551
+ </section>
1552
+
1553
+ <!-- ════════════════════════════════════════════════════════════════ -->
1554
+ <!-- STATUS PILLS -->
1555
+ <!-- ════════════════════════════════════════════════════════════════ -->
1556
+ <section id="status" class="mb-16">
1557
+ <div class="section-title">Status Pills</div>
1558
+ <div class="section-desc"><code class="bg-muted px-1 rounded text-meta">.hf-pill .status-{domain}-{state}</code> — 6px radius · 14px/500 · padding 6px 20px · 15% bg + 100% color + 1px solid border. Hover: opacity .9.</div>
1559
+
1560
+ <!-- Booking statuses -->
1561
+ <div class="sub-title">Booking</div>
1562
+ <div class="demo-row mb-3">
1563
+ <span class="hf-pill status-booking-new">New</span>
1564
+ <span class="hf-pill status-booking-offer">Offer</span>
1565
+ <span class="hf-pill status-booking-confirmed">Confirmed</span>
1566
+ <span class="hf-pill status-booking-check-in">Check-in</span>
1567
+ <span class="hf-pill status-booking-check-out">Check-out</span>
1568
+ <span class="hf-pill status-booking-no-show">No show</span>
1569
+ <span class="hf-pill status-booking-due-in">Due in</span>
1570
+ <span class="hf-pill status-booking-due-out">Due out</span>
1571
+ </div>
1572
+ <div class="demo-row mb-5">
1573
+ <span class="hf-pill status-booking-canceled-by-hotel">Canceled — by hotel</span>
1574
+ <span class="hf-pill status-booking-canceled-by-guest">Canceled — by guest</span>
1575
+ <span class="hf-pill status-booking-canceled-by-hf">Canceled — by HF</span>
1576
+ <span class="hf-pill status-deleted">Deleted</span>
1577
+ </div>
1578
+
1579
+ <!-- Order statuses -->
1580
+ <div class="sub-title">Order</div>
1581
+ <div class="demo-row mb-3">
1582
+ <span class="hf-pill status-order-waiting">Waiting</span>
1583
+ <span class="hf-pill status-order-confirmed">Confirmed</span>
1584
+ <span class="hf-pill status-order-completed">Completed</span>
1585
+ <span class="hf-pill status-order-in-progress">In progress</span>
1586
+ <span class="hf-pill status-order-action-required">Action required</span>
1587
+ </div>
1588
+ <div class="demo-row mb-5">
1589
+ <span class="hf-pill status-order-canceled-by-hotel">Canceled — by hotel</span>
1590
+ <span class="hf-pill status-order-canceled-by-guest">Canceled — by guest</span>
1591
+ <span class="hf-pill status-order-canceled-by-pos">Canceled — by POS</span>
1592
+ <span class="hf-pill status-deleted">Deleted</span>
1593
+ </div>
1594
+
1595
+ <!-- Front desk + active state demonstration -->
1596
+ <div class="sub-title">Front desk <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">+ <code class="bg-muted px-1 rounded text-meta">.is-active</code> — selected filter chip</span></div>
1597
+ <div class="demo-row mb-3">
1598
+ <span class="hf-pill status-front-desk-quota-free">Quota free</span>
1599
+ <span class="hf-pill status-front-desk-quota-busy">Quota busy</span>
1600
+ <span class="hf-pill status-front-desk-out-of-order">Out of order</span>
1601
+ </div>
1602
+ <div class="demo-row mb-5">
1603
+ <span class="hf-pill status-front-desk-quota-free is-active">Quota free <span class="text-caption opacity-60 ml-1">active</span></span>
1604
+ <span class="hf-pill status-front-desk-quota-busy is-active">Quota busy <span class="text-caption opacity-60 ml-1">active</span></span>
1605
+ </div>
1606
+
1607
+ <!-- Room cleaning + striped -->
1608
+ <div class="sub-title">Room cleaning <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">+ <code class="bg-muted px-1 rounded text-meta">--striped</code> for out-of-service</span></div>
1609
+ <div class="demo-row mb-5">
1610
+ <span class="hf-pill status-room-item-cleaning-clean">Clean</span>
1611
+ <span class="hf-pill status-room-item-cleaning-dirty">Dirty</span>
1612
+ <span class="hf-pill status-room-item-cleaning-cleaning">Cleaning</span>
1613
+ <span class="hf-pill status-room-item-cleaning-inspected">Inspected</span>
1614
+ <span class="hf-pill hf-pill--striped status-room-item-cleaning-out-of-service">Out of service</span>
1615
+ </div>
1616
+
1617
+ <!-- Dropdown variant — clickable status -->
1618
+ <div class="sub-title">Dropdown variant <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">clickable status switcher in tables · <code class="bg-muted px-1 rounded text-meta">.hf-pill--dd</code></span></div>
1619
+ <div class="demo-row mb-5">
1620
+ <span class="hf-pill hf-pill--dd status-booking-confirmed">Confirmed</span>
1621
+ <span class="hf-pill hf-pill--dd status-order-waiting">Waiting</span>
1622
+ <span class="hf-pill hf-pill--dd status-front-desk-quota-free">Quota free</span>
1623
+ </div>
1624
+
1625
+ <!-- Size modifiers (min-width for table alignment) -->
1626
+ <div class="sub-title">Size modifiers <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">min-width for table column alignment</span></div>
1627
+ <div class="demo-row mb-5 items-start">
1628
+ <div class="flex flex-col gap-1.5 items-start">
1629
+ <span class="text-caption text-ink-secondary">default</span>
1630
+ <span class="hf-pill status-booking-confirmed">Confirmed</span>
1631
+ </div>
1632
+ <div class="flex flex-col gap-1.5 items-start">
1633
+ <span class="text-caption text-ink-secondary">min-w-[130px]</span>
1634
+ <span class="hf-pill status-booking-confirmed min-w-[130px]">Confirmed</span>
1635
+ </div>
1636
+ <div class="flex flex-col gap-1.5 items-start">
1637
+ <span class="text-caption text-ink-secondary">min-w-[160px]</span>
1638
+ <span class="hf-pill status-booking-confirmed min-w-[160px]">Confirmed</span>
1639
+ </div>
1640
+ <div class="flex flex-col gap-1.5 items-start">
1641
+ <span class="text-caption text-ink-secondary">min-w-[180px]</span>
1642
+ <span class="hf-pill status-booking-confirmed min-w-[180px]">Confirmed</span>
1643
+ </div>
1644
+ </div>
1645
+
1646
+ <div class="snippet">
1647
+ <button class="copy-btn" onclick="copySnippet(this)">Copy</button>
1648
+ <pre>
1649
+ &lt;!-- Basic usage --&gt;
1650
+ &lt;span class="hf-pill status-booking-confirmed"&gt;Confirmed&lt;/span&gt;
1651
+ &lt;span class="hf-pill status-order-waiting"&gt;Waiting&lt;/span&gt;
1652
+ &lt;span class="hf-pill status-room-item-cleaning-dirty"&gt;Dirty&lt;/span&gt;
1653
+
1654
+ &lt;!-- Cancellation reasons (all use cloud-gray) --&gt;
1655
+ &lt;span class="hf-pill status-booking-canceled-by-hotel"&gt;Canceled — by hotel&lt;/span&gt;
1656
+ &lt;span class="hf-pill status-deleted"&gt;Deleted&lt;/span&gt;
1657
+
1658
+ &lt;!-- Active state — selected filter chip (transparent bg + inset ring) --&gt;
1659
+ &lt;span class="hf-pill status-front-desk-quota-free is-active"&gt;Quota free&lt;/span&gt;
1660
+
1661
+ &lt;!-- Striped — out of service rooms --&gt;
1662
+ &lt;span class="hf-pill hf-pill--striped status-room-item-cleaning-out-of-service"&gt;Out of service&lt;/span&gt;
1663
+
1664
+ &lt;!-- Dropdown variant — clickable switcher --&gt;
1665
+ &lt;span class="hf-pill hf-pill--dd status-booking-confirmed"&gt;Confirmed&lt;/span&gt;
1666
+
1667
+ &lt;!-- Min-width modifier (table column alignment) --&gt;
1668
+ &lt;span class="hf-pill status-booking-confirmed min-w-[160px]"&gt;Confirmed&lt;/span&gt;</pre>
1669
+ </div>
1670
+ </section>
1671
+
1672
+ <!-- ════════════════════════════════════════════════════════════════ -->
1673
+ <!-- TABS -->
1674
+ <!-- ════════════════════════════════════════════════════════════════ -->
1675
+ <section id="tabs" class="mb-16">
1676
+ <div class="section-title">Tabs</div>
1677
+ <div class="section-desc">Three patterns — large underline (page nav), small underline (sub-filters), pill (segmented). Active accent #24AFE8 / inactive #50627E.</div>
1678
+
1679
+ <!-- 1. Large underline tabs (page-level navigation) -->
1680
+ <div class="sub-title">Large underline <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">page nav · 16px/500 · padding 22px 15px · 3px active border</span></div>
1681
+ <div class="bg-white rounded-lg border border-border overflow-hidden mb-6">
1682
+ <div class="flex border-b border-border">
1683
+ <button class="hf-tab is-active">Overview</button>
1684
+ <button class="hf-tab">Bookings <span class="hf-tab__count">12</span></button>
1685
+ <button class="hf-tab">Guests</button>
1686
+ <button class="hf-tab" disabled>Reports</button>
1687
+ <button class="hf-tab">Settings</button>
1688
+ </div>
1689
+ <div class="p-5 text-body text-ink-secondary">Tab panel content for "Overview".</div>
1690
+ </div>
1691
+
1692
+ <!-- 2. Small underline tabs (sub-filters: Today/All) -->
1693
+ <div class="sub-title">Small underline <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">sub-filter · <code class="bg-muted px-1 rounded text-meta">.hf-tab--sm</code> · 15px/500 · padding 10px 15px</span></div>
1694
+ <div class="bg-white rounded-lg border border-border overflow-hidden mb-6">
1695
+ <div class="flex border-b border-border">
1696
+ <button class="hf-tab hf-tab--sm">Today</button>
1697
+ <button class="hf-tab hf-tab--sm is-active">All <span class="hf-tab__count">75</span></button>
1698
+ </div>
1699
+ <div class="p-5 text-body text-ink-secondary">Sub-filter content.</div>
1700
+ </div>
1701
+
1702
+ <!-- 3. Pill tabs (segmented control) -->
1703
+ <div class="sub-title">Pill tabs <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">segmented control · <code class="bg-muted px-1 rounded text-meta">.hf-pill-tabs</code> · in section bg · view-mode switches</span></div>
1704
+ <div class="flex flex-wrap items-center gap-5 mb-6">
1705
+ <div class="hf-pill-tabs">
1706
+ <button class="hf-pill-tab is-active">Day</button>
1707
+ <button class="hf-pill-tab">Week</button>
1708
+ <button class="hf-pill-tab">Month</button>
1709
+ <button class="hf-pill-tab">Year</button>
1710
+ </div>
1711
+ <div class="hf-pill-tabs">
1712
+ <button class="hf-pill-tab is-active"><svg class="w-4 h-4 inline-block mr-1.5"><use href="#ic-calendar"/></svg>List</button>
1713
+ <button class="hf-pill-tab"><svg class="w-4 h-4 inline-block mr-1.5"><use href="#ic-filter"/></svg>Grid</button>
1714
+ </div>
1715
+ </div>
1716
+
1717
+ <!-- 4. With icons in tabs -->
1718
+ <div class="sub-title">With icons</div>
1719
+ <div class="bg-white rounded-lg border border-border overflow-hidden mb-6">
1720
+ <div class="flex border-b border-border">
1721
+ <button class="hf-tab is-active">
1722
+ <svg class="w-4 h-4"><use href="#ic-eye"/></svg> Overview
1723
+ </button>
1724
+ <button class="hf-tab">
1725
+ <svg class="w-4 h-4"><use href="#ic-calendar"/></svg> Bookings
1726
+ </button>
1727
+ <button class="hf-tab">
1728
+ <svg class="w-4 h-4"><use href="#ic-settings"/></svg> Settings
1729
+ </button>
1730
+ </div>
1731
+ <div class="p-5 text-body text-ink-secondary">Tab with leading icons.</div>
1732
+ </div>
1733
+
1734
+ <!-- 5. States -->
1735
+ <div class="sub-title">States</div>
1736
+ <div class="bg-white rounded-lg border border-border overflow-hidden mb-6">
1737
+ <div class="flex border-b border-border">
1738
+ <button class="hf-tab is-active">Active</button>
1739
+ <button class="hf-tab">Default</button>
1740
+ <button class="hf-tab" style="color:#2B2B2B">Hover</button>
1741
+ <button class="hf-tab" disabled>Disabled</button>
1742
+ </div>
1743
+ </div>
1744
+
1745
+ <div class="snippet">
1746
+ <button class="copy-btn" onclick="copySnippet(this)">Copy</button>
1747
+ <pre>
1748
+ &lt;!-- Large underline tabs (page nav) — 16px/500, padding 22px 15px --&gt;
1749
+ &lt;div class="flex border-b border-border"&gt;
1750
+ &lt;button class="hf-tab is-active"&gt;Overview&lt;/button&gt;
1751
+ &lt;button class="hf-tab"&gt;Bookings &lt;span class="hf-tab__count"&gt;12&lt;/span&gt;&lt;/button&gt;
1752
+ &lt;button class="hf-tab" disabled&gt;Reports&lt;/button&gt;
1753
+ &lt;/div&gt;
1754
+
1755
+ &lt;!-- Small underline (sub-filters: Today/All) --&gt;
1756
+ &lt;div class="flex border-b border-border"&gt;
1757
+ &lt;button class="hf-tab hf-tab--sm"&gt;Today&lt;/button&gt;
1758
+ &lt;button class="hf-tab hf-tab--sm is-active"&gt;All&lt;/button&gt;
1759
+ &lt;/div&gt;
1760
+
1761
+ &lt;!-- Pill tabs (segmented control) --&gt;
1762
+ &lt;div class="hf-pill-tabs"&gt;
1763
+ &lt;button class="hf-pill-tab is-active"&gt;Day&lt;/button&gt;
1764
+ &lt;button class="hf-pill-tab"&gt;Week&lt;/button&gt;
1765
+ &lt;/div&gt;
1766
+
1767
+ &lt;!-- With leading icon --&gt;
1768
+ &lt;button class="hf-tab is-active"&gt;
1769
+ &lt;svg class="w-4 h-4"&gt;&lt;use href="#ic-eye"/&gt;&lt;/svg&gt; Overview
1770
+ &lt;/button&gt;</pre>
1771
+ </div>
1772
+ </section>
1773
+
1774
+ <!-- ════════════════════════════════════════════════════════════════ -->
1775
+ <!-- DROPDOWN -->
1776
+ <!-- ════════════════════════════════════════════════════════════════ -->
1777
+ <section id="dropdown" class="mb-16">
1778
+ <div class="section-title">Dropdown</div>
1779
+ <div class="section-desc"><code class="bg-muted px-1 rounded text-meta">.hf-dropdown-menu</code> — 9px radius · shadow <code class="bg-muted px-1 rounded text-meta">0 1px 10px rgba(0,0,0,.1)</code> · items 14px · padding 8px 16px · hover bg #F5F5F5.</div>
1780
+
1781
+ <!-- 1. Row / context action menu (most common in tables) -->
1782
+ <div class="sub-title">Row actions <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">kebab trigger → menu · most common in table rows</span></div>
1783
+ <div class="flex items-start gap-10 mb-6">
1784
+ <!-- trigger button -->
1785
+ <button class="inline-flex items-center justify-center w-8 h-8 bg-transparent hover:bg-muted text-ink-steel rounded transition-all duration-200" aria-label="Open actions">
1786
+ <svg class="w-4 h-4"><use href="#ic-more-vertical"/></svg>
1787
+ </button>
1788
+ <!-- menu -->
1789
+ <div class="hf-dropdown-menu w-52">
1790
+ <div class="hf-dropdown-item"><svg class="hf-dropdown-item__icon"><use href="#ic-eye"/></svg> View details</div>
1791
+ <div class="hf-dropdown-item"><svg class="hf-dropdown-item__icon"><use href="#ic-edit-2"/></svg> Edit <span class="hf-dropdown-item__shortcut">⌘E</span></div>
1792
+ <div class="hf-dropdown-item"><svg class="hf-dropdown-item__icon"><use href="#ic-copy"/></svg> Duplicate</div>
1793
+ <div class="hf-dropdown-item is-disabled"><svg class="hf-dropdown-item__icon"><use href="#ic-refresh-cw"/></svg> Refresh <span class="hf-dropdown-item__shortcut">disabled</span></div>
1794
+ <div class="hf-dropdown-divider"></div>
1795
+ <div class="hf-dropdown-item danger"><svg class="hf-dropdown-item__icon"><use href="#ic-trash"/></svg> Delete</div>
1796
+ </div>
1797
+ </div>
1798
+
1799
+ <!-- 2. Select-like dropdown (filter / picker) -->
1800
+ <div class="sub-title">Select <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">value display + chevron → menu with checkmark</span></div>
1801
+ <div class="flex items-start gap-10 mb-6">
1802
+ <button class="inline-flex items-center justify-between gap-2 h-[39px] px-3 bg-white border border-border rounded text-body text-ink hover:border-border-strong transition-colors min-w-[180px]">
1803
+ <span>All categories</span>
1804
+ <svg class="w-4 h-4 text-ink-faint"><use href="#ic-chevron-down"/></svg>
1805
+ </button>
1806
+ <div class="hf-dropdown-menu w-52">
1807
+ <div class="hf-dropdown-item is-active">
1808
+ <svg class="hf-dropdown-item__icon" style="color:currentColor"><use href="#ic-check"/></svg>
1809
+ All categories
1810
+ </div>
1811
+ <div class="hf-dropdown-item">
1812
+ <span class="w-4 h-4 shrink-0"></span>
1813
+ Food &amp; beverage
1814
+ </div>
1815
+ <div class="hf-dropdown-item">
1816
+ <span class="w-4 h-4 shrink-0"></span>
1817
+ Spa &amp; wellness
1818
+ </div>
1819
+ <div class="hf-dropdown-item">
1820
+ <span class="w-4 h-4 shrink-0"></span>
1821
+ Transfers
1822
+ </div>
1823
+ </div>
1824
+ </div>
1825
+
1826
+ <!-- 3. Multi-select (checkbox list) -->
1827
+ <div class="sub-title">Multi-select <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">checkbox list + apply/reset footer</span></div>
1828
+ <div class="flex items-start gap-10 mb-6">
1829
+ <button class="inline-flex items-center gap-2 h-[39px] px-3 bg-white border border-border rounded text-body text-ink hover:border-border-strong transition-colors">
1830
+ <svg class="w-4 h-4 text-ink-faint"><use href="#ic-filter"/></svg>
1831
+ Status <span class="hf-pill status-booking-confirmed ml-1" style="padding:0 6px;font-size:11px;border:0">3</span>
1832
+ <svg class="w-4 h-4 text-ink-faint ml-1"><use href="#ic-chevron-down"/></svg>
1833
+ </button>
1834
+ <div class="hf-dropdown-menu w-56">
1835
+ <div class="hf-dropdown-header">Filter by status</div>
1836
+ <label class="hf-dropdown-item cursor-pointer">
1837
+ <input type="checkbox" checked class="hf-check" />
1838
+ Confirmed
1839
+ <span class="hf-dropdown-item__shortcut">42</span>
1840
+ </label>
1841
+ <label class="hf-dropdown-item cursor-pointer">
1842
+ <input type="checkbox" checked class="hf-check" />
1843
+ Waiting
1844
+ <span class="hf-dropdown-item__shortcut">18</span>
1845
+ </label>
1846
+ <label class="hf-dropdown-item cursor-pointer">
1847
+ <input type="checkbox" checked class="hf-check" />
1848
+ Completed
1849
+ <span class="hf-dropdown-item__shortcut">88</span>
1850
+ </label>
1851
+ <label class="hf-dropdown-item cursor-pointer">
1852
+ <input type="checkbox" class="hf-check" />
1853
+ Canceled
1854
+ <span class="hf-dropdown-item__shortcut">12</span>
1855
+ </label>
1856
+ <div class="hf-dropdown-divider"></div>
1857
+ <div class="flex items-center justify-between px-4 py-2 gap-2">
1858
+ <button class="text-body text-ink-secondary hover:text-ink transition-colors">Reset</button>
1859
+ <button class="inline-flex items-center h-8 px-[14px] bg-primary hover:bg-primary-hover text-white text-body font-semibold rounded transition-colors">Apply</button>
1860
+ </div>
1861
+ </div>
1862
+ </div>
1863
+
1864
+ <!-- 4. User menu (with header + avatar) -->
1865
+ <div class="sub-title">User menu <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">avatar trigger → menu with user header</span></div>
1866
+ <div class="flex items-start gap-10 mb-6">
1867
+ <button class="inline-flex items-center gap-2 h-10 px-3 bg-transparent hover:bg-muted rounded transition-all">
1868
+ <span class="w-8 h-8 rounded-full bg-primary text-white text-meta font-semibold inline-flex items-center justify-center">QA</span>
1869
+ <span class="text-body text-ink">QA Admin</span>
1870
+ <svg class="w-4 h-4 text-ink-faint"><use href="#ic-chevron-down"/></svg>
1871
+ </button>
1872
+ <div class="hf-dropdown-menu w-56">
1873
+ <!-- user header -->
1874
+ <div class="px-4 py-3 border-b border-border-light">
1875
+ <div class="text-body font-semibold text-ink">QA Admin</div>
1876
+ <div class="text-caption text-ink-secondary">qa@hotelfriend.co</div>
1877
+ </div>
1878
+ <div class="py-1">
1879
+ <div class="hf-dropdown-item"><svg class="hf-dropdown-item__icon"><use href="#ic-settings"/></svg> Account settings</div>
1880
+ <div class="hf-dropdown-item"><svg class="hf-dropdown-item__icon"><use href="#ic-info"/></svg> Help &amp; support</div>
1881
+ </div>
1882
+ <div class="hf-dropdown-divider"></div>
1883
+ <div class="hf-dropdown-item danger"><svg class="hf-dropdown-item__icon"><use href="#ic-log-out"/></svg> Log out</div>
1884
+ </div>
1885
+ </div>
1886
+
1887
+ <!-- 5. States row -->
1888
+ <div class="sub-title">Item states</div>
1889
+ <div class="hf-dropdown-menu w-72 mb-6">
1890
+ <div class="hf-dropdown-item">Default item</div>
1891
+ <div class="hf-dropdown-item" style="background:#F5F5F5">Hover item</div>
1892
+ <div class="hf-dropdown-item is-active"><svg class="hf-dropdown-item__icon" style="color:currentColor"><use href="#ic-check"/></svg> Active / selected</div>
1893
+ <div class="hf-dropdown-item is-disabled">Disabled item</div>
1894
+ <div class="hf-dropdown-divider"></div>
1895
+ <div class="hf-dropdown-item danger">Destructive (delete)</div>
1896
+ </div>
1897
+
1898
+ <div class="snippet">
1899
+ <button class="copy-btn" onclick="copySnippet(this)">Copy</button>
1900
+ <pre>
1901
+ &lt;!-- Row action menu (kebab → menu) --&gt;
1902
+ &lt;div class="hf-dropdown-menu w-52"&gt;
1903
+ &lt;div class="hf-dropdown-item"&gt;
1904
+ &lt;svg class="hf-dropdown-item__icon"&gt;&lt;use href="#ic-edit-2"/&gt;&lt;/svg&gt;
1905
+ Edit
1906
+ &lt;span class="hf-dropdown-item__shortcut"&gt;⌘E&lt;/span&gt;
1907
+ &lt;/div&gt;
1908
+ &lt;div class="hf-dropdown-divider"&gt;&lt;/div&gt;
1909
+ &lt;div class="hf-dropdown-item danger"&gt;
1910
+ &lt;svg class="hf-dropdown-item__icon"&gt;&lt;use href="#ic-trash"/&gt;&lt;/svg&gt;
1911
+ Delete
1912
+ &lt;/div&gt;
1913
+ &lt;/div&gt;
1914
+
1915
+ &lt;!-- Multi-select with apply footer --&gt;
1916
+ &lt;div class="hf-dropdown-menu w-56"&gt;
1917
+ &lt;div class="hf-dropdown-header"&gt;Filter by status&lt;/div&gt;
1918
+ &lt;label class="hf-dropdown-item cursor-pointer"&gt;
1919
+ &lt;input type="checkbox" class="hf-check" /&gt; Confirmed
1920
+ &lt;span class="hf-dropdown-item__shortcut"&gt;42&lt;/span&gt;
1921
+ &lt;/label&gt;
1922
+ &lt;div class="hf-dropdown-divider"&gt;&lt;/div&gt;
1923
+ &lt;div class="flex items-center justify-between px-4 py-2 gap-2"&gt;
1924
+ &lt;button class="text-body text-ink-secondary"&gt;Reset&lt;/button&gt;
1925
+ &lt;button class="h-8 px-[14px] bg-primary text-white rounded"&gt;Apply&lt;/button&gt;
1926
+ &lt;/div&gt;
1927
+ &lt;/div&gt;
1928
+
1929
+ &lt;!-- User menu with header section --&gt;
1930
+ &lt;div class="hf-dropdown-menu w-56"&gt;
1931
+ &lt;div class="px-4 py-3 border-b border-border-light"&gt;
1932
+ &lt;div class="text-body font-semibold text-ink"&gt;User Name&lt;/div&gt;
1933
+ &lt;div class="text-caption text-ink-secondary"&gt;user@example.com&lt;/div&gt;
1934
+ &lt;/div&gt;
1935
+ &lt;div class="py-1"&gt;
1936
+ &lt;div class="hf-dropdown-item"&gt;Settings&lt;/div&gt;
1937
+ &lt;/div&gt;
1938
+ &lt;div class="hf-dropdown-divider"&gt;&lt;/div&gt;
1939
+ &lt;div class="hf-dropdown-item danger"&gt;Log out&lt;/div&gt;
1940
+ &lt;/div&gt;</pre>
1941
+ </div>
1942
+ </section>
1943
+
1944
+ <!-- ════════════════════════════════════════════════════════════════ -->
1945
+ <!-- MODAL -->
1946
+ <!-- ════════════════════════════════════════════════════════════════ -->
1947
+ <section id="modal" class="mb-16">
1948
+ <div class="section-title">Modal</div>
1949
+ <div class="section-desc">Portal <code class="bg-muted px-1 rounded text-meta">.modal-content</code>: 6px radius · border <code class="bg-muted px-1 rounded text-meta">1px rgba(72,91,120,.15)</code> · shadow <code class="bg-muted px-1 rounded text-meta">0 2px 4px rgba(72,91,120,.18)</code>. Title 18px/600 · 20px padding · footer no top-border.</div>
1950
+
1951
+ <!-- 1. Form modal (md, 500px) -->
1952
+ <div class="sub-title">Form modal <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">md · max-w-[500px] · header + form body + footer with primary save</span></div>
1953
+ <div class="relative bg-section rounded p-8 border border-border-light mb-6">
1954
+ <div class="text-caption text-ink-faint mb-4 text-center">↓ inline preview (backdrop simulated by section bg)</div>
1955
+ <div class="hf-modal max-w-[500px] mx-auto">
1956
+ <div class="hf-modal__header">
1957
+ <h2 class="hf-modal__title">Edit Guest</h2>
1958
+ <button class="hf-modal__close" aria-label="Close">
1959
+ <svg class="w-5 h-5"><use href="#ic-x"/></svg>
1960
+ </button>
1961
+ </div>
1962
+ <div class="hf-modal__body flex flex-col gap-4">
1963
+ <div>
1964
+ <label class="block text-meta font-medium text-ink-secondary mb-1.5">Full name <span class="text-bad">*</span></label>
1965
+ <input type="text" value="Amanda Peterson"
1966
+ class="w-full h-[39px] px-3 bg-white border border-border rounded text-body text-ink focus:outline-none focus:border-border-strong"/>
1967
+ </div>
1968
+ <div>
1969
+ <label class="block text-meta font-medium text-ink-secondary mb-1.5">Email</label>
1970
+ <input type="email" placeholder="email@example.com"
1971
+ class="w-full h-[39px] px-3 bg-white border border-border rounded text-body text-ink placeholder:text-ink-faint focus:outline-none focus:border-border-strong"/>
1972
+ </div>
1973
+ <div>
1974
+ <label class="block text-meta font-medium text-ink-secondary mb-1.5">Notes</label>
1975
+ <textarea rows="3" placeholder="Optional notes…"
1976
+ class="w-full px-3 py-2 bg-white border border-border rounded text-body text-ink placeholder:text-ink-faint resize-none focus:outline-none focus:border-border-strong"></textarea>
1977
+ </div>
1978
+ </div>
1979
+ <div class="hf-modal__footer">
1980
+ <button class="inline-flex items-center h-10 px-5 bg-white hover:bg-[rgba(190,198,212,0.1)] text-ink-muted text-action font-semibold rounded transition-all duration-200">Cancel</button>
1981
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-primary hover:bg-primary-hover text-white text-action font-semibold rounded transition-all duration-200">
1982
+ <svg class="w-4 h-4"><use href="#ic-save"/></svg> Save changes
1983
+ </button>
1984
+ </div>
1985
+ </div>
1986
+ </div>
1987
+
1988
+ <!-- 2. Confirm / destructive modal (sm, 420px) -->
1989
+ <div class="sub-title">Confirm — destructive <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">sm · max-w-[420px] · icon + message · danger primary action</span></div>
1990
+ <div class="relative bg-section rounded p-8 border border-border-light mb-6">
1991
+ <div class="hf-modal max-w-[420px] mx-auto">
1992
+ <div class="hf-modal__header">
1993
+ <h2 class="hf-modal__title">Delete booking?</h2>
1994
+ <button class="hf-modal__close" aria-label="Close">
1995
+ <svg class="w-5 h-5"><use href="#ic-x"/></svg>
1996
+ </button>
1997
+ </div>
1998
+ <div class="hf-modal__body">
1999
+ <div class="flex items-start gap-3">
2000
+ <div class="w-10 h-10 rounded-full bg-bad/10 text-bad flex items-center justify-center shrink-0">
2001
+ <svg class="w-5 h-5"><use href="#ic-alert-triangle"/></svg>
2002
+ </div>
2003
+ <div class="flex-1">
2004
+ <div class="text-body text-ink">Booking <strong>#1284</strong> for Amanda Peterson will be permanently removed.</div>
2005
+ <div class="text-caption text-ink-secondary mt-1">This action cannot be undone.</div>
2006
+ </div>
2007
+ </div>
2008
+ </div>
2009
+ <div class="hf-modal__footer">
2010
+ <button class="inline-flex items-center h-10 px-5 bg-white hover:bg-[rgba(190,198,212,0.1)] text-ink-muted text-action font-semibold rounded transition-all duration-200">Cancel</button>
2011
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-danger hover:bg-danger-hover text-white text-action font-semibold rounded transition-all duration-200">
2012
+ <svg class="w-4 h-4"><use href="#ic-trash"/></svg> Delete booking
2013
+ </button>
2014
+ </div>
2015
+ </div>
2016
+ </div>
2017
+
2018
+ <!-- 3. Info modal — no footer -->
2019
+ <div class="sub-title">Info — no footer <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">content-only · close button is the only dismiss</span></div>
2020
+ <div class="relative bg-section rounded p-8 border border-border-light mb-6">
2021
+ <div class="hf-modal max-w-[480px] mx-auto">
2022
+ <div class="hf-modal__header">
2023
+ <h2 class="hf-modal__title">Welcome to v0.1</h2>
2024
+ <button class="hf-modal__close" aria-label="Close">
2025
+ <svg class="w-5 h-5"><use href="#ic-x"/></svg>
2026
+ </button>
2027
+ </div>
2028
+ <div class="hf-modal__body">
2029
+ <div class="flex flex-col gap-3 text-body text-ink">
2030
+ <p>We've shipped a few improvements:</p>
2031
+ <ul class="space-y-2 text-ink-secondary">
2032
+ <li class="flex items-start gap-2"><svg class="w-4 h-4 text-ok mt-0.5 shrink-0"><use href="#ic-check"/></svg> New status pill colors</li>
2033
+ <li class="flex items-start gap-2"><svg class="w-4 h-4 text-ok mt-0.5 shrink-0"><use href="#ic-check"/></svg> Faster table rendering</li>
2034
+ <li class="flex items-start gap-2"><svg class="w-4 h-4 text-ok mt-0.5 shrink-0"><use href="#ic-check"/></svg> Dark-mode token preview</li>
2035
+ </ul>
2036
+ </div>
2037
+ </div>
2038
+ </div>
2039
+ </div>
2040
+
2041
+ <!-- 4. Large modal (lg, 720px) — for tables/multi-column forms -->
2042
+ <div class="sub-title">Large <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">lg · max-w-[720px] · multi-column forms, embedded tables</span></div>
2043
+ <div class="relative bg-section rounded p-8 border border-border-light mb-6">
2044
+ <div class="hf-modal max-w-[720px] mx-auto">
2045
+ <div class="hf-modal__header">
2046
+ <h2 class="hf-modal__title">Booking details — #1284</h2>
2047
+ <button class="hf-modal__close" aria-label="Close">
2048
+ <svg class="w-5 h-5"><use href="#ic-x"/></svg>
2049
+ </button>
2050
+ </div>
2051
+ <div class="hf-modal__body grid grid-cols-2 gap-5">
2052
+ <div>
2053
+ <label class="block text-meta font-medium text-ink-secondary mb-1.5">Guest</label>
2054
+ <input type="text" value="Amanda Peterson" class="w-full h-[39px] px-3 bg-white border border-border rounded text-body text-ink focus:outline-none focus:border-border-strong" />
2055
+ </div>
2056
+ <div>
2057
+ <label class="block text-meta font-medium text-ink-secondary mb-1.5">Room</label>
2058
+ <input type="text" value="304" class="w-full h-[39px] px-3 bg-white border border-border rounded text-body text-ink focus:outline-none focus:border-border-strong" />
2059
+ </div>
2060
+ <div>
2061
+ <label class="block text-meta font-medium text-ink-secondary mb-1.5">Check-in</label>
2062
+ <div class="relative">
2063
+ <input type="text" value="2026-05-22" class="w-full h-[39px] pl-3 pr-9 bg-white border border-border rounded text-body text-ink focus:outline-none focus:border-border-strong" />
2064
+ <svg class="w-4 h-4 absolute right-3 top-1/2 -translate-y-1/2 text-ink-faint pointer-events-none"><use href="#ic-calendar"/></svg>
2065
+ </div>
2066
+ </div>
2067
+ <div>
2068
+ <label class="block text-meta font-medium text-ink-secondary mb-1.5">Check-out</label>
2069
+ <div class="relative">
2070
+ <input type="text" value="2026-05-25" class="w-full h-[39px] pl-3 pr-9 bg-white border border-border rounded text-body text-ink focus:outline-none focus:border-border-strong" />
2071
+ <svg class="w-4 h-4 absolute right-3 top-1/2 -translate-y-1/2 text-ink-faint pointer-events-none"><use href="#ic-calendar"/></svg>
2072
+ </div>
2073
+ </div>
2074
+ <div class="col-span-2">
2075
+ <label class="block text-meta font-medium text-ink-secondary mb-1.5">Status</label>
2076
+ <div class="flex items-center gap-3">
2077
+ <span class="hf-pill status-booking-confirmed">Confirmed</span>
2078
+ <button class="text-primary text-body hover:underline">Change status →</button>
2079
+ </div>
2080
+ </div>
2081
+ </div>
2082
+ <div class="hf-modal__footer">
2083
+ <button class="inline-flex items-center h-10 px-5 bg-white hover:bg-[rgba(190,198,212,0.1)] text-ink-muted text-action font-semibold rounded transition-all duration-200">Close</button>
2084
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-primary hover:bg-primary-hover text-white text-action font-semibold rounded transition-all duration-200">
2085
+ <svg class="w-4 h-4"><use href="#ic-save"/></svg> Update booking
2086
+ </button>
2087
+ </div>
2088
+ </div>
2089
+ </div>
2090
+
2091
+ <!-- 5. Loading state -->
2092
+ <div class="sub-title">Loading state <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">spinner overlay · primary button shows saving…</span></div>
2093
+ <div class="relative bg-section rounded p-8 border border-border-light mb-6">
2094
+ <div class="hf-modal max-w-[420px] mx-auto relative">
2095
+ <div class="hf-modal__header">
2096
+ <h2 class="hf-modal__title">Saving changes</h2>
2097
+ </div>
2098
+ <div class="hf-modal__body flex flex-col items-center gap-3 py-8">
2099
+ <svg class="w-10 h-10 hf-spin text-primary" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>
2100
+ <div class="text-body text-ink-secondary">Please wait — saving booking #1284…</div>
2101
+ </div>
2102
+ </div>
2103
+ </div>
2104
+
2105
+ <div class="snippet">
2106
+ <button class="copy-btn" onclick="copySnippet(this)">Copy</button>
2107
+ <pre>
2108
+ &lt;!-- Backdrop + container --&gt;
2109
+ &lt;div class="fixed inset-0 z-50 bg-black/40 flex items-start justify-center pt-[30px] p-4"&gt;
2110
+ &lt;div class="hf-modal w-full max-w-[500px]"&gt;
2111
+ &lt;div class="hf-modal__header"&gt;
2112
+ &lt;h2 class="hf-modal__title"&gt;Title&lt;/h2&gt;
2113
+ &lt;button class="hf-modal__close" aria-label="Close"&gt;
2114
+ &lt;svg class="w-5 h-5"&gt;&lt;use href="#ic-x"/&gt;&lt;/svg&gt;
2115
+ &lt;/button&gt;
2116
+ &lt;/div&gt;
2117
+ &lt;div class="hf-modal__body"&gt; … form / content … &lt;/div&gt;
2118
+ &lt;div class="hf-modal__footer"&gt;
2119
+ &lt;button class="btn-cancel"&gt;Cancel&lt;/button&gt;
2120
+ &lt;button class="btn-primary"&gt;Save&lt;/button&gt;
2121
+ &lt;/div&gt;
2122
+ &lt;/div&gt;
2123
+ &lt;/div&gt;
2124
+
2125
+ &lt;!-- Sizes — set max-w on .hf-modal --&gt;
2126
+ &lt;!-- sm : max-w-[420px] · confirm / single message --&gt;
2127
+ &lt;!-- md : max-w-[500px] · form (default) --&gt;
2128
+ &lt;!-- lg : max-w-[720px] · multi-column / table --&gt;
2129
+ &lt;!-- xl : max-w-[960px] · drill-downs --&gt;</pre>
2130
+ </div>
2131
+ </section>
2132
+
2133
+ <!-- ════════════════════════════════════════════════════════════════ -->
2134
+ <!-- ALERTS -->
2135
+ <!-- ════════════════════════════════════════════════════════════════ -->
2136
+ <section id="alerts" class="mb-16">
2137
+ <div class="section-title">Alerts &amp; Toasts</div>
2138
+ <div class="section-desc">Portal <code class="bg-muted px-1 rounded text-meta">.alert</code> — white bg + 1px <code class="bg-muted px-1 rounded text-meta">rgba(72,91,120,.15)</code> border + 3px top accent bar + 26×26 square icon. Title 18px/500 · text 15px/normal.</div>
2139
+
2140
+ <!-- 1. Standard alerts (4 variants) -->
2141
+ <div class="sub-title">Standard <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">in-page alerts · 3px top color bar · 26×26 squared icon · title + description</span></div>
2142
+ <div class="flex flex-col gap-3 mb-6">
2143
+ <!-- Success -->
2144
+ <div class="hf-alert hf-alert--success">
2145
+ <div class="hf-alert__icon"><svg><use href="#ic-check"/></svg></div>
2146
+ <div class="hf-alert__body">
2147
+ <div class="hf-alert__title">Saved successfully</div>
2148
+ <p class="hf-alert__text">Booking #1284 has been updated. Changes are visible to all team members.</p>
2149
+ </div>
2150
+ <button class="hf-alert__close" aria-label="Dismiss"><svg class="w-3 h-3"><use href="#ic-x"/></svg></button>
2151
+ </div>
2152
+
2153
+ <!-- Info -->
2154
+ <div class="hf-alert hf-alert--info">
2155
+ <div class="hf-alert__icon"><svg><use href="#ic-info"/></svg></div>
2156
+ <div class="hf-alert__body">
2157
+ <div class="hf-alert__title">Sync scheduled</div>
2158
+ <p class="hf-alert__text">Channel data will be refreshed tonight at 00:00 CET. New bookings continue to sync in real time.</p>
2159
+ </div>
2160
+ <button class="hf-alert__close" aria-label="Dismiss"><svg class="w-3 h-3"><use href="#ic-x"/></svg></button>
2161
+ </div>
2162
+
2163
+ <!-- Warning -->
2164
+ <div class="hf-alert hf-alert--warn">
2165
+ <div class="hf-alert__icon"><svg><use href="#ic-alert-triangle"/></svg></div>
2166
+ <div class="hf-alert__body">
2167
+ <div class="hf-alert__title">Channel is offline</div>
2168
+ <p class="hf-alert__text">Booking.com hasn't responded in 12 minutes. Check the channel manager.</p>
2169
+ </div>
2170
+ <button class="hf-alert__close" aria-label="Dismiss"><svg class="w-3 h-3"><use href="#ic-x"/></svg></button>
2171
+ </div>
2172
+
2173
+ <!-- Error -->
2174
+ <div class="hf-alert hf-alert--error">
2175
+ <div class="hf-alert__icon"><svg><use href="#ic-alert-circle"/></svg></div>
2176
+ <div class="hf-alert__body">
2177
+ <div class="hf-alert__title">Payment failed</div>
2178
+ <p class="hf-alert__text">Stripe returned <code class="bg-muted px-1 rounded text-meta">card_declined</code>. Please retry with another payment method.</p>
2179
+ </div>
2180
+ <button class="hf-alert__close" aria-label="Dismiss"><svg class="w-3 h-3"><use href="#ic-x"/></svg></button>
2181
+ </div>
2182
+ </div>
2183
+
2184
+ <!-- 2. Tinted variant -->
2185
+ <div class="sub-title">Tinted <span class="text-ink-faint text-caption font-normal normal-case tracking-normal"><code class="bg-muted px-1 rounded text-meta">--tinted</code> — accent-coloured background instead of white</span></div>
2186
+ <div class="flex flex-col gap-3 mb-6">
2187
+ <div class="hf-alert hf-alert--tinted hf-alert--success">
2188
+ <div class="hf-alert__icon"><svg><use href="#ic-check"/></svg></div>
2189
+ <div class="hf-alert__body">
2190
+ <div class="hf-alert__title">All checks passed</div>
2191
+ <p class="hf-alert__text">Hotel profile is complete and verified.</p>
2192
+ </div>
2193
+ </div>
2194
+ <div class="hf-alert hf-alert--tinted hf-alert--warn">
2195
+ <div class="hf-alert__icon"><svg><use href="#ic-alert-triangle"/></svg></div>
2196
+ <div class="hf-alert__body">
2197
+ <div class="hf-alert__title">2 rooms missing photos</div>
2198
+ <p class="hf-alert__text">Photos affect search ranking on connected channels.</p>
2199
+ </div>
2200
+ </div>
2201
+ </div>
2202
+
2203
+ <!-- 3. Page banner (full-width strip, no rounded corners) -->
2204
+ <div class="sub-title">Page banner <span class="text-ink-faint text-caption font-normal normal-case tracking-normal"><code class="bg-muted px-1 rounded text-meta">--banner</code> — full-width top-of-page critical strip (e.g. contract expired)</span></div>
2205
+ <div class="flex flex-col gap-3 mb-6">
2206
+ <div class="hf-alert hf-alert--banner hf-alert--error">
2207
+ <div class="hf-alert__icon"><svg><use href="#ic-alert-circle"/></svg></div>
2208
+ <div class="hf-alert__body">
2209
+ <div class="text-body">Unfortunately the contract has expired. Contact our Support to continue using HotelFriend.</div>
2210
+ </div>
2211
+ <button class="hf-alert__close" aria-label="Dismiss"><svg class="w-3 h-3"><use href="#ic-x"/></svg></button>
2212
+ </div>
2213
+ <div class="hf-alert hf-alert--banner hf-alert--info">
2214
+ <div class="hf-alert__icon"><svg><use href="#ic-info"/></svg></div>
2215
+ <div class="hf-alert__body">
2216
+ <div class="text-body">Scheduled maintenance on Sunday 22:00–22:30 CET. The portal may be briefly unavailable.</div>
2217
+ </div>
2218
+ <button class="hf-alert__close" aria-label="Dismiss"><svg class="w-3 h-3"><use href="#ic-x"/></svg></button>
2219
+ </div>
2220
+ </div>
2221
+
2222
+ <!-- 4. Compact (inside cards) -->
2223
+ <div class="sub-title">Compact <span class="text-ink-faint text-caption font-normal normal-case tracking-normal"><code class="bg-muted px-1 rounded text-meta">--compact</code> — for inside cards / forms · 13px text · smaller padding</span></div>
2224
+ <div class="flex flex-col gap-3 mb-6 max-w-[500px]">
2225
+ <div class="hf-alert hf-alert--compact hf-alert--info">
2226
+ <div class="hf-alert__icon"><svg><use href="#ic-info"/></svg></div>
2227
+ <div class="hf-alert__body">
2228
+ <div class="hf-alert__title">Heads up</div>
2229
+ <p class="hf-alert__text">Saving this will trigger a re-sync with all channels.</p>
2230
+ </div>
2231
+ <button class="hf-alert__close" aria-label="Dismiss"><svg class="w-2.5 h-2.5"><use href="#ic-x"/></svg></button>
2232
+ </div>
2233
+ <div class="hf-alert hf-alert--compact hf-alert--warn">
2234
+ <div class="hf-alert__icon"><svg><use href="#ic-alert-triangle"/></svg></div>
2235
+ <div class="hf-alert__body">
2236
+ <p class="hf-alert__text">Without title — single-line compact alert for inline form hints.</p>
2237
+ </div>
2238
+ </div>
2239
+ </div>
2240
+
2241
+ <!-- 5. Toast (floating notification) -->
2242
+ <div class="sub-title">Toast <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">floating bottom-right · 14px · 9px radius · shadow-modal · single-line</span></div>
2243
+ <div class="flex flex-col gap-3 mb-6">
2244
+ <div class="hf-toast">
2245
+ <svg class="hf-toast__icon text-ok"><use href="#ic-check-circle"/></svg>
2246
+ <span class="hf-toast__text">Booking <strong>#2841</strong> confirmed</span>
2247
+ <button class="hf-toast__close" aria-label="Dismiss"><svg class="w-3 h-3"><use href="#ic-x"/></svg></button>
2248
+ </div>
2249
+ <div class="hf-toast">
2250
+ <svg class="hf-toast__icon text-bad"><use href="#ic-alert-circle"/></svg>
2251
+ <span class="hf-toast__text">Failed to send email — retrying in 30s</span>
2252
+ <button class="hf-toast__close" aria-label="Dismiss"><svg class="w-3 h-3"><use href="#ic-x"/></svg></button>
2253
+ </div>
2254
+ <div class="hf-toast">
2255
+ <svg class="hf-toast__icon text-primary"><use href="#ic-refresh-cw"/></svg>
2256
+ <span class="hf-toast__text">Syncing inventory… <span class="text-ink-secondary">3 of 12 channels</span></span>
2257
+ </div>
2258
+ </div>
2259
+
2260
+ <div class="snippet">
2261
+ <button class="copy-btn" onclick="copySnippet(this)">Copy</button>
2262
+ <pre>
2263
+ &lt;!-- Standard alert (success / info / warn / error) --&gt;
2264
+ &lt;div class="hf-alert hf-alert--info"&gt;
2265
+ &lt;div class="hf-alert__icon"&gt;&lt;svg&gt;&lt;use href="#ic-info"/&gt;&lt;/svg&gt;&lt;/div&gt;
2266
+ &lt;div class="hf-alert__body"&gt;
2267
+ &lt;div class="hf-alert__title"&gt;Sync scheduled&lt;/div&gt;
2268
+ &lt;p class="hf-alert__text"&gt;Channel data will be refreshed tonight at 00:00 CET.&lt;/p&gt;
2269
+ &lt;/div&gt;
2270
+ &lt;button class="hf-alert__close" aria-label="Dismiss"&gt;
2271
+ &lt;svg class="w-3 h-3"&gt;&lt;use href="#ic-x"/&gt;&lt;/svg&gt;
2272
+ &lt;/button&gt;
2273
+ &lt;/div&gt;
2274
+
2275
+ &lt;!-- Tinted (accent-bg) — add --tinted --&gt;
2276
+ &lt;div class="hf-alert hf-alert--tinted hf-alert--success"&gt; … &lt;/div&gt;
2277
+
2278
+ &lt;!-- Page banner — full-width critical strip --&gt;
2279
+ &lt;div class="hf-alert hf-alert--banner hf-alert--error"&gt; … &lt;/div&gt;
2280
+
2281
+ &lt;!-- Compact — inside cards / forms --&gt;
2282
+ &lt;div class="hf-alert hf-alert--compact hf-alert--info"&gt; … &lt;/div&gt;
2283
+
2284
+ &lt;!-- Toast (floating) --&gt;
2285
+ &lt;div class="hf-toast"&gt;
2286
+ &lt;svg class="hf-toast__icon text-ok"&gt;&lt;use href="#ic-check-circle"/&gt;&lt;/svg&gt;
2287
+ &lt;span class="hf-toast__text"&gt;Booking confirmed&lt;/span&gt;
2288
+ &lt;button class="hf-toast__close"&gt;&lt;svg class="w-3 h-3"&gt;&lt;use href="#ic-x"/&gt;&lt;/svg&gt;&lt;/button&gt;
2289
+ &lt;/div&gt;
2290
+
2291
+ &lt;!-- Positioning toast stack (top-right, fixed) --&gt;
2292
+ &lt;div class="fixed top-4 right-4 z-50 flex flex-col gap-2"&gt;
2293
+ &lt;!-- toasts --&gt;
2294
+ &lt;/div&gt;</pre>
2295
+ </div>
2296
+ </section>
2297
+
2298
+ <!-- ════════════════════════════════════════════════════════════════ -->
2299
+ <!-- PAGINATION -->
2300
+ <!-- ════════════════════════════════════════════════════════════════ -->
2301
+ <section id="pagination" class="mb-16">
2302
+ <div class="section-title">Pagination</div>
2303
+ <div class="section-desc">Portal pattern — 34×34 items · 8px radius · 14px/400 · Active: <code class="bg-muted px-1 rounded text-meta">#E4E8EF</code> bg + <code class="bg-muted px-1 rounded text-meta">#252F4A</code> text (subtle, not primary). Inactive: transparent · ink-steel #485B78.</div>
2304
+
2305
+ <!-- 1. Standard numeric pagination -->
2306
+ <div class="sub-title">Standard <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">prev/next + numbered pages + ellipsis</span></div>
2307
+ <div class="hf-pagination mb-6">
2308
+ <button class="hf-pagination__item" disabled aria-label="Previous">
2309
+ <svg class="w-4 h-4"><use href="#ic-chevron-left"/></svg>
2310
+ </button>
2311
+ <button class="hf-pagination__item is-active">1</button>
2312
+ <button class="hf-pagination__item">2</button>
2313
+ <button class="hf-pagination__item">3</button>
2314
+ <span class="hf-pagination__ellipsis">…</span>
2315
+ <button class="hf-pagination__item">12</button>
2316
+ <button class="hf-pagination__item" aria-label="Next">
2317
+ <svg class="w-4 h-4"><use href="#ic-chevron-right"/></svg>
2318
+ </button>
2319
+ </div>
2320
+
2321
+ <!-- 2. Many pages with both ellipsis -->
2322
+ <div class="sub-title">With both ellipses <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">large result sets · current page in the middle</span></div>
2323
+ <div class="hf-pagination mb-6">
2324
+ <button class="hf-pagination__item" aria-label="Previous">
2325
+ <svg class="w-4 h-4"><use href="#ic-chevron-left"/></svg>
2326
+ </button>
2327
+ <button class="hf-pagination__item">1</button>
2328
+ <span class="hf-pagination__ellipsis">…</span>
2329
+ <button class="hf-pagination__item">23</button>
2330
+ <button class="hf-pagination__item">24</button>
2331
+ <button class="hf-pagination__item is-active">25</button>
2332
+ <button class="hf-pagination__item">26</button>
2333
+ <button class="hf-pagination__item">27</button>
2334
+ <span class="hf-pagination__ellipsis">…</span>
2335
+ <button class="hf-pagination__item">99</button>
2336
+ <button class="hf-pagination__item" aria-label="Next">
2337
+ <svg class="w-4 h-4"><use href="#ic-chevron-right"/></svg>
2338
+ </button>
2339
+ </div>
2340
+
2341
+ <!-- 3. Few pages (≤7) — no ellipsis -->
2342
+ <div class="sub-title">Few pages <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">total ≤ 7 · show all</span></div>
2343
+ <div class="hf-pagination mb-6">
2344
+ <button class="hf-pagination__item" aria-label="Previous">
2345
+ <svg class="w-4 h-4"><use href="#ic-chevron-left"/></svg>
2346
+ </button>
2347
+ <button class="hf-pagination__item">1</button>
2348
+ <button class="hf-pagination__item">2</button>
2349
+ <button class="hf-pagination__item is-active">3</button>
2350
+ <button class="hf-pagination__item">4</button>
2351
+ <button class="hf-pagination__item">5</button>
2352
+ <button class="hf-pagination__item" aria-label="Next">
2353
+ <svg class="w-4 h-4"><use href="#ic-chevron-right"/></svg>
2354
+ </button>
2355
+ </div>
2356
+
2357
+ <!-- 4. Pagination with summary + page size -->
2358
+ <div class="sub-title">In table footer <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">summary text + page-size selector + pager</span></div>
2359
+ <div class="bg-section border-t border-border px-5 py-3 rounded-b-lg flex items-center justify-between flex-wrap gap-4 mb-6">
2360
+ <div class="text-body text-ink-secondary">
2361
+ Showing <strong class="text-ink">21–40</strong> of <strong class="text-ink">237</strong> bookings
2362
+ </div>
2363
+ <div class="flex items-center gap-4">
2364
+ <div class="flex items-center gap-2 text-body text-ink-secondary">
2365
+ <span>Rows per page</span>
2366
+ <div class="relative">
2367
+ <select class="h-8 pl-2 pr-7 bg-white border border-border rounded text-body text-ink appearance-none focus:outline-none focus:border-border-strong">
2368
+ <option>20</option><option>50</option><option>100</option>
2369
+ </select>
2370
+ <svg class="w-3.5 h-3.5 absolute right-2 top-1/2 -translate-y-1/2 text-ink-faint pointer-events-none"><use href="#ic-chevron-down"/></svg>
2371
+ </div>
2372
+ </div>
2373
+ <div class="hf-pagination">
2374
+ <button class="hf-pagination__item" aria-label="Previous">
2375
+ <svg class="w-4 h-4"><use href="#ic-chevron-left"/></svg>
2376
+ </button>
2377
+ <button class="hf-pagination__item">1</button>
2378
+ <button class="hf-pagination__item is-active">2</button>
2379
+ <button class="hf-pagination__item">3</button>
2380
+ <button class="hf-pagination__item">4</button>
2381
+ <button class="hf-pagination__item" aria-label="Next">
2382
+ <svg class="w-4 h-4"><use href="#ic-chevron-right"/></svg>
2383
+ </button>
2384
+ </div>
2385
+ </div>
2386
+ </div>
2387
+
2388
+ <!-- 5. States -->
2389
+ <div class="sub-title">States</div>
2390
+ <div class="hf-pagination mb-6">
2391
+ <button class="hf-pagination__item">Default</button>
2392
+ <button class="hf-pagination__item is-active">Active</button>
2393
+ <button class="hf-pagination__item" style="background:#F1F3F6; color:#2B2B2B">Hover</button>
2394
+ <button class="hf-pagination__item" disabled>Disabled</button>
2395
+ </div>
2396
+
2397
+ <div class="snippet">
2398
+ <button class="copy-btn" onclick="copySnippet(this)">Copy</button>
2399
+ <pre>
2400
+ &lt;!-- Standard pagination — portal-exact (subtle gray active) --&gt;
2401
+ &lt;nav class="hf-pagination"&gt;
2402
+ &lt;button class="hf-pagination__item" disabled aria-label="Previous"&gt;
2403
+ &lt;svg class="w-4 h-4"&gt;&lt;use href="#ic-chevron-left"/&gt;&lt;/svg&gt;
2404
+ &lt;/button&gt;
2405
+ &lt;button class="hf-pagination__item is-active"&gt;1&lt;/button&gt;
2406
+ &lt;button class="hf-pagination__item"&gt;2&lt;/button&gt;
2407
+ &lt;button class="hf-pagination__item"&gt;3&lt;/button&gt;
2408
+ &lt;span class="hf-pagination__ellipsis"&gt;…&lt;/span&gt;
2409
+ &lt;button class="hf-pagination__item"&gt;12&lt;/button&gt;
2410
+ &lt;button class="hf-pagination__item" aria-label="Next"&gt;
2411
+ &lt;svg class="w-4 h-4"&gt;&lt;use href="#ic-chevron-right"/&gt;&lt;/svg&gt;
2412
+ &lt;/button&gt;
2413
+ &lt;/nav&gt;
2414
+
2415
+ &lt;!-- Color tokens reference --&gt;
2416
+ &lt;!-- .is-active : bg #E4E8EF / text #252F4A / 8px radius (NOT primary!) --&gt;
2417
+ &lt;!-- inactive : transparent / text #485B78 (ink-steel) --&gt;
2418
+ &lt;!-- hover : bg #F1F3F6 / text #2B2B2B --&gt;
2419
+ &lt;!-- disabled : color #AEBCCF / pointer-events:none --&gt;</pre>
2420
+ </div>
2421
+ </section>
2422
+
2423
+ <!-- ════════════════════════════════════════════════════════════════ -->
2424
+ <!-- EMPTY / SKELETON -->
2425
+ <!-- ════════════════════════════════════════════════════════════════ -->
2426
+ <section id="empty" class="mb-16">
2427
+ <div class="section-title">Empty &amp; Skeleton</div>
2428
+ <div class="section-desc">Empty states for no-data scenarios + skeleton loaders for async content. Use empty states when the request succeeds with no results; use skeletons while the request is in flight.</div>
2429
+
2430
+ <!-- 1. Full empty state — page-level -->
2431
+ <div class="sub-title">Full empty state <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">page-level · icon + title + description + CTA</span></div>
2432
+ <div class="bg-white rounded-lg border border-border p-10 flex flex-col items-center gap-3 text-center mb-6">
2433
+ <div class="w-16 h-16 rounded-full bg-muted flex items-center justify-center text-ink-faint">
2434
+ <svg class="w-7 h-7"><use href="#ic-search"/></svg>
2435
+ </div>
2436
+ <div class="text-heading font-semibold text-ink">No bookings found</div>
2437
+ <div class="text-body text-ink-secondary max-w-md">Try adjusting your filters or create a new booking. Active filters are shown above the table.</div>
2438
+ <div class="flex items-center gap-3 mt-2">
2439
+ <button class="inline-flex items-center gap-2 h-10 px-[10px] bg-transparent hover:bg-[rgba(72,91,120,0.05)] text-ink-steel text-body font-medium rounded border border-[rgba(72,91,120,0.15)] transition-all duration-200">
2440
+ <svg class="w-4 h-4"><use href="#ic-refresh-cw"/></svg> Reset filters
2441
+ </button>
2442
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-primary hover:bg-primary-hover text-white text-action font-semibold rounded transition-all duration-200">
2443
+ <svg class="w-4 h-4"><use href="#ic-plus"/></svg> New booking
2444
+ </button>
2445
+ </div>
2446
+ </div>
2447
+
2448
+ <!-- 2. Compact empty state — inside cards -->
2449
+ <div class="sub-title">Compact <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">inside cards · 3 variants for different domains</span></div>
2450
+ <div class="grid grid-cols-3 gap-3 mb-6">
2451
+ <div class="rounded-[4px] border border-[rgba(72,91,120,0.15)] p-5 flex flex-col items-center justify-center gap-2 min-h-[140px] text-center">
2452
+ <svg class="w-6 h-6 text-ok"><use href="#ic-calendar"/></svg>
2453
+ <div class="text-meta text-ink-secondary">No arrivals today</div>
2454
+ </div>
2455
+ <div class="rounded-[4px] border border-[rgba(72,91,120,0.15)] p-5 flex flex-col items-center justify-center gap-2 min-h-[140px] text-center">
2456
+ <svg class="w-6 h-6 text-coral"><use href="#ic-calendar"/></svg>
2457
+ <div class="text-meta text-ink-secondary">No departures</div>
2458
+ </div>
2459
+ <div class="rounded-[4px] border border-[rgba(72,91,120,0.15)] p-5 flex flex-col items-center justify-center gap-2 min-h-[140px] text-center">
2460
+ <svg class="w-6 h-6 text-primary"><use href="#ic-check"/></svg>
2461
+ <div class="text-meta text-ink-secondary">All caught up</div>
2462
+ </div>
2463
+ </div>
2464
+
2465
+ <!-- 3. Inline empty (table) -->
2466
+ <div class="sub-title">Inline (table) <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">colspan row · centered message + secondary action</span></div>
2467
+ <div class="bg-white rounded-lg border border-border overflow-hidden mb-6">
2468
+ <table class="w-full text-body">
2469
+ <thead class="bg-section">
2470
+ <tr class="text-meta font-medium text-ink-steel uppercase tracking-wider">
2471
+ <th class="text-left px-5 py-3">Guest</th>
2472
+ <th class="text-left px-5 py-3">Room</th>
2473
+ <th class="text-left px-5 py-3">Status</th>
2474
+ <th class="text-right px-5 py-3">Total</th>
2475
+ </tr>
2476
+ </thead>
2477
+ <tbody>
2478
+ <tr>
2479
+ <td colspan="4" class="px-5 py-12 text-center">
2480
+ <div class="flex flex-col items-center gap-2">
2481
+ <svg class="w-8 h-8 text-ink-faint"><use href="#ic-search"/></svg>
2482
+ <div class="text-body text-ink-secondary">No bookings match your filters</div>
2483
+ <button class="text-primary text-body hover:underline">Clear all filters</button>
2484
+ </div>
2485
+ </td>
2486
+ </tr>
2487
+ </tbody>
2488
+ </table>
2489
+ </div>
2490
+
2491
+ <!-- 4. Error state -->
2492
+ <div class="sub-title">Error state <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">failed to load · retry action</span></div>
2493
+ <div class="bg-white rounded-lg border border-border p-10 flex flex-col items-center gap-3 text-center mb-6">
2494
+ <div class="w-16 h-16 rounded-full bg-bad/10 flex items-center justify-center text-bad">
2495
+ <svg class="w-7 h-7"><use href="#ic-alert-circle"/></svg>
2496
+ </div>
2497
+ <div class="text-heading font-semibold text-ink">Couldn't load bookings</div>
2498
+ <div class="text-body text-ink-secondary max-w-md">The server didn't respond in time. Check your connection and try again.</div>
2499
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-primary hover:bg-primary-hover text-white text-action font-semibold rounded transition-all duration-200 mt-2">
2500
+ <svg class="w-4 h-4"><use href="#ic-refresh-cw"/></svg> Retry
2501
+ </button>
2502
+ </div>
2503
+
2504
+ <!-- 5. Skeleton — card layout -->
2505
+ <div class="sub-title">Skeleton — card <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">avatar + 3 text lines · shimmer 1.4s</span></div>
2506
+ <div class="grid grid-cols-2 gap-5 mb-6">
2507
+ <div class="bg-white rounded-lg border border-border p-5 flex flex-col gap-4">
2508
+ <div class="flex items-center gap-3">
2509
+ <div class="skeleton w-10 h-10 rounded-full"></div>
2510
+ <div class="flex-1 flex flex-col gap-2">
2511
+ <div class="skeleton h-3 w-3/4"></div>
2512
+ <div class="skeleton h-3 w-1/2"></div>
2513
+ </div>
2514
+ </div>
2515
+ <div class="skeleton h-3 w-full"></div>
2516
+ <div class="skeleton h-3 w-5/6"></div>
2517
+ <div class="skeleton h-3 w-4/6"></div>
2518
+ </div>
2519
+ <div class="bg-white rounded-lg border border-border p-5 flex flex-col gap-3">
2520
+ <div class="skeleton h-5 w-2/3 mb-1"></div>
2521
+ <div class="skeleton h-3 w-full"></div>
2522
+ <div class="skeleton h-3 w-full"></div>
2523
+ <div class="skeleton h-3 w-4/5"></div>
2524
+ <div class="flex items-center gap-2 mt-2">
2525
+ <div class="skeleton h-8 w-24 rounded"></div>
2526
+ <div class="skeleton h-8 w-20 rounded"></div>
2527
+ </div>
2528
+ </div>
2529
+ </div>
2530
+
2531
+ <!-- 6. Skeleton — table rows -->
2532
+ <div class="sub-title">Skeleton — table rows <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">5 rows with column-aware widths</span></div>
2533
+ <div class="bg-white rounded-lg border border-border overflow-hidden mb-6">
2534
+ <table class="w-full text-body">
2535
+ <thead class="bg-section">
2536
+ <tr class="text-meta font-medium text-ink-steel uppercase tracking-wider">
2537
+ <th class="text-left px-5 py-3">Guest</th>
2538
+ <th class="text-left px-5 py-3">Room</th>
2539
+ <th class="text-left px-5 py-3">Status</th>
2540
+ <th class="text-right px-5 py-3">Total</th>
2541
+ </tr>
2542
+ </thead>
2543
+ <tbody class="divide-y divide-border">
2544
+ <tr><td class="px-5 py-3"><div class="skeleton h-3 w-32"></div></td><td class="px-5 py-3"><div class="skeleton h-3 w-12"></div></td><td class="px-5 py-3"><div class="skeleton h-6 w-24 rounded"></div></td><td class="px-5 py-3"><div class="skeleton h-3 w-16 ml-auto"></div></td></tr>
2545
+ <tr><td class="px-5 py-3"><div class="skeleton h-3 w-40"></div></td><td class="px-5 py-3"><div class="skeleton h-3 w-10"></div></td><td class="px-5 py-3"><div class="skeleton h-6 w-20 rounded"></div></td><td class="px-5 py-3"><div class="skeleton h-3 w-14 ml-auto"></div></td></tr>
2546
+ <tr><td class="px-5 py-3"><div class="skeleton h-3 w-28"></div></td><td class="px-5 py-3"><div class="skeleton h-3 w-14"></div></td><td class="px-5 py-3"><div class="skeleton h-6 w-28 rounded"></div></td><td class="px-5 py-3"><div class="skeleton h-3 w-12 ml-auto"></div></td></tr>
2547
+ <tr><td class="px-5 py-3"><div class="skeleton h-3 w-36"></div></td><td class="px-5 py-3"><div class="skeleton h-3 w-10"></div></td><td class="px-5 py-3"><div class="skeleton h-6 w-22 rounded"></div></td><td class="px-5 py-3"><div class="skeleton h-3 w-16 ml-auto"></div></td></tr>
2548
+ <tr><td class="px-5 py-3"><div class="skeleton h-3 w-32"></div></td><td class="px-5 py-3"><div class="skeleton h-3 w-12"></div></td><td class="px-5 py-3"><div class="skeleton h-6 w-24 rounded"></div></td><td class="px-5 py-3"><div class="skeleton h-3 w-14 ml-auto"></div></td></tr>
2549
+ </tbody>
2550
+ </table>
2551
+ </div>
2552
+
2553
+ <!-- 7. Skeleton — stat tiles -->
2554
+ <div class="sub-title">Skeleton — KPI tiles</div>
2555
+ <div class="grid grid-cols-3 gap-5 mb-6">
2556
+ <div class="bg-white rounded border border-[rgba(72,91,120,0.05)] shadow-subtle p-4 flex flex-col gap-2">
2557
+ <div class="skeleton h-3 w-20"></div>
2558
+ <div class="skeleton h-7 w-24"></div>
2559
+ <div class="skeleton h-2.5 w-32"></div>
2560
+ </div>
2561
+ <div class="bg-white rounded border border-[rgba(72,91,120,0.05)] shadow-subtle p-4 flex flex-col gap-2">
2562
+ <div class="skeleton h-3 w-16"></div>
2563
+ <div class="skeleton h-7 w-20"></div>
2564
+ <div class="skeleton h-2.5 w-28"></div>
2565
+ </div>
2566
+ <div class="bg-white rounded border border-[rgba(72,91,120,0.05)] shadow-subtle p-4 flex flex-col gap-2">
2567
+ <div class="skeleton h-3 w-24"></div>
2568
+ <div class="skeleton h-7 w-28"></div>
2569
+ <div class="skeleton h-2.5 w-24"></div>
2570
+ </div>
2571
+ </div>
2572
+
2573
+ <div class="snippet">
2574
+ <button class="copy-btn" onclick="copySnippet(this)">Copy</button>
2575
+ <pre>
2576
+ &lt;!-- Empty state (page-level) --&gt;
2577
+ &lt;div class="bg-white rounded-lg border border-border p-10 flex flex-col items-center gap-3 text-center"&gt;
2578
+ &lt;div class="w-16 h-16 rounded-full bg-muted flex items-center justify-center text-ink-faint"&gt;
2579
+ &lt;svg class="w-7 h-7"&gt;&lt;use href="#ic-search"/&gt;&lt;/svg&gt;
2580
+ &lt;/div&gt;
2581
+ &lt;div class="text-heading font-semibold text-ink"&gt;Title&lt;/div&gt;
2582
+ &lt;div class="text-body text-ink-secondary max-w-md"&gt;Description.&lt;/div&gt;
2583
+ &lt;button class="… btn-primary mt-2"&gt;Primary action&lt;/button&gt;
2584
+ &lt;/div&gt;
2585
+
2586
+ &lt;!-- Inline empty row (inside table) --&gt;
2587
+ &lt;tr&gt;&lt;td colspan="4" class="px-5 py-12 text-center"&gt;
2588
+ &lt;div class="flex flex-col items-center gap-2"&gt;
2589
+ &lt;svg class="w-8 h-8 text-ink-faint"&gt;&lt;use href="#ic-search"/&gt;&lt;/svg&gt;
2590
+ &lt;div class="text-body text-ink-secondary"&gt;No results&lt;/div&gt;
2591
+ &lt;button class="text-primary text-body hover:underline"&gt;Clear filters&lt;/button&gt;
2592
+ &lt;/div&gt;
2593
+ &lt;/td&gt;&lt;/tr&gt;
2594
+
2595
+ &lt;!-- Skeleton bar (uses .skeleton — shimmer keyframe in &lt;style&gt;) --&gt;
2596
+ &lt;div class="skeleton h-3 w-3/4"&gt;&lt;/div&gt;
2597
+ &lt;div class="skeleton h-3 w-1/2"&gt;&lt;/div&gt;
2598
+ &lt;div class="skeleton w-10 h-10 rounded-full"&gt;&lt;/div&gt;
2599
+
2600
+ &lt;!-- Skeleton CSS (already defined in &lt;style&gt;) --&gt;
2601
+ &lt;style&gt;
2602
+ @keyframes shimmer { 0%{background-position:-200% 0} 100%{background-position:200% 0} }
2603
+ .skeleton {
2604
+ background: linear-gradient(90deg, #F1F3F6 25%, #E4E8EF 50%, #F1F3F6 75%);
2605
+ background-size: 200% 100%;
2606
+ animation: shimmer 1.4s infinite;
2607
+ border-radius: 4px;
2608
+ }
2609
+ &lt;/style&gt;</pre>
2610
+ </div>
2611
+ </section>
2612
+
2613
+ <!-- ════════════════════════════════════════════════════════════════ -->
2614
+ <!-- PAGE LAYOUT -->
2615
+ <!-- ════════════════════════════════════════════════════════════════ -->
2616
+ <section id="layout" class="mb-16">
2617
+ <div class="section-title">Page Layouts</div>
2618
+ <div class="section-desc">Canonical page patterns assembled from the components above. Each layout is the structural recipe for a corresponding portal page.</div>
2619
+
2620
+ <!-- ════ 1. LIST PAGE ════ -->
2621
+ <div class="sub-title">List page <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">title → tabs → filters → table → footer pager</span></div>
2622
+ <div class="border border-border rounded-lg overflow-hidden mb-8">
2623
+ <!-- Title bar -->
2624
+ <div class="flex items-center justify-between px-6 py-4 bg-white">
2625
+ <div>
2626
+ <h1 class="text-title font-semibold text-ink">Bookings (142)</h1>
2627
+ <div class="text-caption text-ink-secondary mt-1">Manage all reservations across channels</div>
2628
+ </div>
2629
+ <div class="flex items-center gap-2">
2630
+ <button class="inline-flex items-center justify-center w-10 h-10 bg-white hover:bg-muted text-ink-steel border border-border shadow-outline rounded transition-all duration-200" aria-label="Export">
2631
+ <svg class="w-4 h-4"><use href="#ic-copy"/></svg>
2632
+ </button>
2633
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-primary hover:bg-primary-hover text-white text-action font-semibold rounded transition-all duration-200">
2634
+ <svg class="w-4 h-4"><use href="#ic-plus"/></svg> New booking
2635
+ </button>
2636
+ </div>
2637
+ </div>
2638
+ <!-- Sub-filter tabs -->
2639
+ <div class="flex border-b border-border bg-white">
2640
+ <button class="hf-tab hf-tab--sm">Today</button>
2641
+ <button class="hf-tab hf-tab--sm is-active">All <span class="hf-tab__count">142</span></button>
2642
+ </div>
2643
+ <!-- Filters bar -->
2644
+ <div class="flex items-center gap-3 px-6 py-3 bg-white border-b border-border flex-wrap">
2645
+ <div class="relative flex-1 min-w-[200px] max-w-xs">
2646
+ <svg class="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-ink-faint pointer-events-none"><use href="#ic-search"/></svg>
2647
+ <input type="text" placeholder="Search guests, rooms…"
2648
+ class="w-full h-[39px] pl-9 pr-3 bg-white border border-border rounded text-body text-ink placeholder:text-ink-faint focus:outline-none focus:border-border-strong"/>
2649
+ </div>
2650
+ <div class="relative">
2651
+ <select class="h-[39px] pl-3 pr-8 bg-white border border-border rounded text-body text-ink-secondary appearance-none focus:outline-none focus:border-border-strong">
2652
+ <option>All statuses</option><option>Confirmed</option>
2653
+ </select>
2654
+ <svg class="w-4 h-4 absolute right-2 top-1/2 -translate-y-1/2 text-ink-faint pointer-events-none"><use href="#ic-chevron-down"/></svg>
2655
+ </div>
2656
+ <button class="inline-flex items-center gap-2 h-[38px] px-[10px] bg-primary-tint hover:bg-primary-tint-hover text-primary text-body font-medium rounded border border-primary/20 transition-all duration-200">
2657
+ <svg class="w-4 h-4"><use href="#ic-filter"/></svg> Filters
2658
+ </button>
2659
+ <button class="inline-flex items-center gap-2 h-[38px] px-[10px] bg-primary-tint hover:bg-primary-tint-hover text-primary text-body font-medium rounded border border-primary/20 transition-all duration-200">
2660
+ <svg class="w-4 h-4"><use href="#ic-refresh-cw"/></svg> Reset
2661
+ </button>
2662
+ </div>
2663
+ <!-- Table -->
2664
+ <div class="bg-white">
2665
+ <table class="w-full text-body">
2666
+ <thead class="bg-section">
2667
+ <tr class="text-meta font-medium text-ink-steel uppercase tracking-wider">
2668
+ <th class="text-left px-5 py-3">Guest</th>
2669
+ <th class="text-left px-5 py-3">Room</th>
2670
+ <th class="text-left px-5 py-3">Status</th>
2671
+ <th class="text-left px-5 py-3">Check-in</th>
2672
+ <th class="text-right px-5 py-3 w-24">Actions</th>
2673
+ </tr>
2674
+ </thead>
2675
+ <tbody class="divide-y divide-border">
2676
+ <tr class="hover:bg-section transition-colors duration-150">
2677
+ <td class="px-5 py-3 text-ink font-medium">Anna Schmidt</td>
2678
+ <td class="px-5 py-3 text-ink-secondary">101</td>
2679
+ <td class="px-5 py-3"><span class="hf-pill status-booking-confirmed">Confirmed</span></td>
2680
+ <td class="px-5 py-3 text-ink-secondary">May 22</td>
2681
+ <td class="px-5 py-3"><div class="flex justify-end gap-1">
2682
+ <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-muted text-ink-secondary transition-colors duration-200"><svg class="w-3.5 h-3.5"><use href="#ic-eye"/></svg></button>
2683
+ <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-muted text-ink-secondary transition-colors duration-200"><svg class="w-3.5 h-3.5"><use href="#ic-edit-2"/></svg></button>
2684
+ </div></td>
2685
+ </tr>
2686
+ <tr class="hover:bg-section transition-colors duration-150">
2687
+ <td class="px-5 py-3 text-ink font-medium">Marco Rossi</td>
2688
+ <td class="px-5 py-3 text-ink-secondary">205</td>
2689
+ <td class="px-5 py-3"><span class="hf-pill status-booking-check-in">Check-in</span></td>
2690
+ <td class="px-5 py-3 text-ink-secondary">May 20</td>
2691
+ <td class="px-5 py-3"><div class="flex justify-end gap-1">
2692
+ <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-muted text-ink-secondary transition-colors duration-200"><svg class="w-3.5 h-3.5"><use href="#ic-eye"/></svg></button>
2693
+ <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-muted text-ink-secondary transition-colors duration-200"><svg class="w-3.5 h-3.5"><use href="#ic-edit-2"/></svg></button>
2694
+ </div></td>
2695
+ </tr>
2696
+ <tr class="hover:bg-section transition-colors duration-150">
2697
+ <td class="px-5 py-3 text-ink font-medium">Lena Weber</td>
2698
+ <td class="px-5 py-3 text-ink-secondary">307</td>
2699
+ <td class="px-5 py-3"><span class="hf-pill status-booking-due-out">Due out</span></td>
2700
+ <td class="px-5 py-3 text-ink-secondary">May 19</td>
2701
+ <td class="px-5 py-3"><div class="flex justify-end gap-1">
2702
+ <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-muted text-ink-secondary transition-colors duration-200"><svg class="w-3.5 h-3.5"><use href="#ic-eye"/></svg></button>
2703
+ <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-muted text-ink-secondary transition-colors duration-200"><svg class="w-3.5 h-3.5"><use href="#ic-edit-2"/></svg></button>
2704
+ </div></td>
2705
+ </tr>
2706
+ </tbody>
2707
+ </table>
2708
+ </div>
2709
+ <!-- Pagination footer -->
2710
+ <div class="flex items-center justify-between bg-section border-t border-border px-6 py-3 flex-wrap gap-3">
2711
+ <div class="text-body text-ink-secondary">Showing <strong class="text-ink">1–3</strong> of <strong class="text-ink">142</strong></div>
2712
+ <div class="hf-pagination">
2713
+ <button class="hf-pagination__item" disabled aria-label="Previous"><svg class="w-4 h-4"><use href="#ic-chevron-left"/></svg></button>
2714
+ <button class="hf-pagination__item is-active">1</button>
2715
+ <button class="hf-pagination__item">2</button>
2716
+ <button class="hf-pagination__item">3</button>
2717
+ <span class="hf-pagination__ellipsis">…</span>
2718
+ <button class="hf-pagination__item">48</button>
2719
+ <button class="hf-pagination__item" aria-label="Next"><svg class="w-4 h-4"><use href="#ic-chevron-right"/></svg></button>
2720
+ </div>
2721
+ </div>
2722
+ </div>
2723
+
2724
+ <!-- ════ 2. DETAIL PAGE ════ -->
2725
+ <div class="sub-title">Detail page <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">breadcrumbs → title bar → tabs → 2-column content</span></div>
2726
+ <div class="border border-border rounded-lg overflow-hidden mb-8 bg-section">
2727
+ <!-- Breadcrumbs -->
2728
+ <div class="px-6 py-3 bg-white border-b border-border">
2729
+ <div class="flex items-center gap-2 text-meta text-ink-secondary">
2730
+ <a class="hover:text-primary cursor-pointer">Bookings</a>
2731
+ <span class="text-ink-faint">/</span>
2732
+ <span class="text-ink">#1284 — Amanda Peterson</span>
2733
+ </div>
2734
+ </div>
2735
+ <!-- Title bar with status -->
2736
+ <div class="flex items-center justify-between px-6 py-4 bg-white border-b border-border flex-wrap gap-3">
2737
+ <div class="flex items-center gap-3 flex-wrap">
2738
+ <h1 class="text-title font-semibold text-ink">Amanda Peterson</h1>
2739
+ <span class="hf-pill status-booking-confirmed">Confirmed</span>
2740
+ <span class="text-meta text-ink-secondary">Created May 16, 2026</span>
2741
+ </div>
2742
+ <div class="flex items-center gap-2">
2743
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-white hover:bg-muted text-ink-steel border border-border shadow-outline text-action font-semibold rounded transition-all duration-200">
2744
+ <svg class="w-4 h-4"><use href="#ic-copy"/></svg> Duplicate
2745
+ </button>
2746
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-white hover:bg-muted text-danger-outline border border-danger-outline text-action font-semibold rounded transition-all duration-200">
2747
+ <svg class="w-4 h-4"><use href="#ic-trash"/></svg> Delete
2748
+ </button>
2749
+ </div>
2750
+ </div>
2751
+ <!-- Tabs -->
2752
+ <div class="flex border-b border-border bg-white">
2753
+ <button class="hf-tab is-active"><svg class="w-4 h-4"><use href="#ic-eye"/></svg> Overview</button>
2754
+ <button class="hf-tab"><svg class="w-4 h-4"><use href="#ic-calendar"/></svg> Stay</button>
2755
+ <button class="hf-tab"><svg class="w-4 h-4"><use href="#ic-info"/></svg> Notes <span class="hf-tab__count">2</span></button>
2756
+ <button class="hf-tab"><svg class="w-4 h-4"><use href="#ic-settings"/></svg> History</button>
2757
+ </div>
2758
+ <!-- 2-column content -->
2759
+ <div class="grid grid-cols-3 gap-5 p-6">
2760
+ <!-- Main (2 cols) -->
2761
+ <div class="col-span-2 flex flex-col gap-5">
2762
+ <div class="bg-white rounded-lg border border-border p-5">
2763
+ <div class="text-action font-semibold text-ink mb-3">Guest details</div>
2764
+ <div class="grid grid-cols-2 gap-4 text-body">
2765
+ <div><div class="text-meta text-ink-secondary mb-0.5">Full name</div><div class="text-ink">Amanda Peterson</div></div>
2766
+ <div><div class="text-meta text-ink-secondary mb-0.5">Email</div><div class="text-ink">amanda@example.com</div></div>
2767
+ <div><div class="text-meta text-ink-secondary mb-0.5">Phone</div><div class="text-ink">+49 30 555 0123</div></div>
2768
+ <div><div class="text-meta text-ink-secondary mb-0.5">Country</div><div class="text-ink">Germany</div></div>
2769
+ </div>
2770
+ </div>
2771
+ <div class="bg-white rounded-lg border border-border p-5">
2772
+ <div class="text-action font-semibold text-ink mb-3">Stay</div>
2773
+ <div class="grid grid-cols-3 gap-4 text-body">
2774
+ <div><div class="text-meta text-ink-secondary mb-0.5">Check-in</div><div class="text-ink">May 22, 2026</div></div>
2775
+ <div><div class="text-meta text-ink-secondary mb-0.5">Check-out</div><div class="text-ink">May 25, 2026</div></div>
2776
+ <div><div class="text-meta text-ink-secondary mb-0.5">Nights</div><div class="text-ink">3</div></div>
2777
+ <div><div class="text-meta text-ink-secondary mb-0.5">Room</div><div class="text-ink">304 — Deluxe Suite</div></div>
2778
+ <div><div class="text-meta text-ink-secondary mb-0.5">Guests</div><div class="text-ink">2 adults</div></div>
2779
+ <div><div class="text-meta text-ink-secondary mb-0.5">Rate plan</div><div class="text-ink">BAR</div></div>
2780
+ </div>
2781
+ </div>
2782
+ </div>
2783
+ <!-- Sidebar (1 col) -->
2784
+ <div class="col-span-1 flex flex-col gap-5">
2785
+ <div class="bg-white rounded border border-[rgba(72,91,120,0.05)] shadow-subtle p-4">
2786
+ <div class="text-meta font-medium text-ink-secondary mb-1">Total</div>
2787
+ <div class="text-title font-semibold text-ink">€ 1,425.00</div>
2788
+ <div class="text-caption text-ok mt-1">Paid in full</div>
2789
+ </div>
2790
+ <div class="bg-white rounded-lg border border-border p-5">
2791
+ <div class="text-action font-semibold text-ink mb-3">Actions</div>
2792
+ <div class="flex flex-col gap-2">
2793
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-primary hover:bg-primary-hover text-white text-action font-semibold rounded transition-all duration-200">
2794
+ <svg class="w-4 h-4"><use href="#ic-edit-2"/></svg> Edit booking
2795
+ </button>
2796
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-white hover:bg-muted text-primary border border-primary text-action font-semibold rounded transition-all duration-200">
2797
+ Check-in guest
2798
+ </button>
2799
+ </div>
2800
+ </div>
2801
+ </div>
2802
+ </div>
2803
+ </div>
2804
+
2805
+ <!-- ════ 3. FORM / EDIT PAGE ════ -->
2806
+ <div class="sub-title">Form page <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">title → sectioned form → sticky footer with Cancel + Save</span></div>
2807
+ <div class="border border-border rounded-lg overflow-hidden mb-8 bg-section">
2808
+ <!-- Title -->
2809
+ <div class="flex items-center justify-between px-6 py-4 bg-white border-b border-border">
2810
+ <div>
2811
+ <div class="text-meta text-ink-secondary mb-1">
2812
+ <a class="hover:text-primary cursor-pointer">Hotel settings</a> <span class="mx-1">/</span> <span class="text-ink">Edit profile</span>
2813
+ </div>
2814
+ <h1 class="text-title font-semibold text-ink">Edit hotel profile</h1>
2815
+ </div>
2816
+ </div>
2817
+ <!-- Form sections -->
2818
+ <div class="p-6 flex flex-col gap-5">
2819
+ <div class="bg-white rounded-lg border border-border p-5">
2820
+ <div class="text-action font-semibold text-ink mb-1">Basic info</div>
2821
+ <div class="text-meta text-ink-secondary mb-4">Public information shown to guests.</div>
2822
+ <div class="grid grid-cols-2 gap-5">
2823
+ <div>
2824
+ <label class="block text-meta font-medium text-ink-secondary mb-1.5">Hotel name <span class="text-bad">*</span></label>
2825
+ <input type="text" value="Dynamic Environment Hotel" class="w-full h-[39px] px-3 bg-white border border-border rounded text-body text-ink focus:outline-none focus:border-border-strong"/>
2826
+ </div>
2827
+ <div>
2828
+ <label class="block text-meta font-medium text-ink-secondary mb-1.5">Star rating</label>
2829
+ <div class="relative">
2830
+ <select class="w-full h-[39px] pl-3 pr-9 bg-white border border-border rounded text-body text-ink appearance-none focus:outline-none focus:border-border-strong">
2831
+ <option>4 stars</option>
2832
+ </select>
2833
+ <svg class="w-4 h-4 absolute right-3 top-1/2 -translate-y-1/2 text-ink-faint pointer-events-none"><use href="#ic-chevron-down"/></svg>
2834
+ </div>
2835
+ </div>
2836
+ <div class="col-span-2">
2837
+ <label class="block text-meta font-medium text-ink-secondary mb-1.5">Description</label>
2838
+ <textarea rows="3" class="w-full px-3 py-2 bg-white border border-border rounded text-body text-ink resize-none focus:outline-none focus:border-border-strong">Boutique hotel in the heart of Berlin.</textarea>
2839
+ </div>
2840
+ </div>
2841
+ </div>
2842
+ <div class="bg-white rounded-lg border border-border p-5">
2843
+ <div class="text-action font-semibold text-ink mb-1">Preferences</div>
2844
+ <div class="text-meta text-ink-secondary mb-4">Behaviour and notifications.</div>
2845
+ <div class="flex flex-col gap-3">
2846
+ <label class="flex items-center gap-3 cursor-pointer select-none">
2847
+ <div class="relative w-[52px] h-[28px]">
2848
+ <input type="checkbox" checked class="sr-only peer" />
2849
+ <div class="absolute inset-0 rounded-full bg-[#DFDFDF] peer-checked:bg-primary transition-colors duration-200"></div>
2850
+ <div class="absolute top-[4px] left-[4px] w-5 h-5 bg-white rounded-full shadow-[0_1px_6px_0_rgba(0,0,0,.3)] transition-transform duration-200 peer-checked:translate-x-6"></div>
2851
+ </div>
2852
+ <span class="text-body text-ink">Send daily activity summary</span>
2853
+ </label>
2854
+ <label class="flex items-center gap-3 cursor-pointer select-none">
2855
+ <div class="relative w-[52px] h-[28px]">
2856
+ <input type="checkbox" class="sr-only peer" />
2857
+ <div class="absolute inset-0 rounded-full bg-[#DFDFDF] peer-checked:bg-primary transition-colors duration-200"></div>
2858
+ <div class="absolute top-[4px] left-[4px] w-5 h-5 bg-white rounded-full shadow-[0_1px_6px_0_rgba(0,0,0,.3)] transition-transform duration-200 peer-checked:translate-x-6"></div>
2859
+ </div>
2860
+ <span class="text-body text-ink">Auto-confirm bookings from channels</span>
2861
+ </label>
2862
+ </div>
2863
+ </div>
2864
+ </div>
2865
+ <!-- Sticky footer -->
2866
+ <div class="flex items-center justify-end gap-3 bg-white border-t border-border px-6 py-4 sticky bottom-0">
2867
+ <button class="inline-flex items-center h-10 px-5 bg-white hover:bg-[rgba(190,198,212,0.1)] text-ink-muted text-action font-semibold rounded transition-all duration-200">Cancel</button>
2868
+ <button class="inline-flex items-center gap-2 h-10 px-5 bg-primary hover:bg-primary-hover text-white text-action font-semibold rounded transition-all duration-200">
2869
+ <svg class="w-4 h-4"><use href="#ic-save"/></svg> Save changes
2870
+ </button>
2871
+ </div>
2872
+ </div>
2873
+
2874
+ <!-- ════ 4. DASHBOARD ════ -->
2875
+ <div class="sub-title">Dashboard <span class="text-ink-faint text-caption font-normal normal-case tracking-normal">title with date · KPI grid · content cards</span></div>
2876
+ <div class="border border-border rounded-lg overflow-hidden mb-8 bg-section">
2877
+ <!-- Title bar -->
2878
+ <div class="flex items-center justify-between px-6 py-4 bg-white border-b border-border flex-wrap gap-3">
2879
+ <h1 class="text-title font-semibold text-ink">Dashboard</h1>
2880
+ <div class="flex items-center gap-2">
2881
+ <div class="hf-pill-tabs">
2882
+ <button class="hf-pill-tab is-active">Today</button>
2883
+ <button class="hf-pill-tab">Week</button>
2884
+ <button class="hf-pill-tab">Month</button>
2885
+ </div>
2886
+ <div class="relative">
2887
+ <input type="text" value="20 May 2026" readonly class="h-[39px] pl-3 pr-9 w-[160px] bg-white border border-border rounded text-body text-ink cursor-pointer focus:outline-none focus:border-border-strong"/>
2888
+ <svg class="w-4 h-4 absolute right-3 top-1/2 -translate-y-1/2 text-ink-faint pointer-events-none"><use href="#ic-calendar"/></svg>
2889
+ </div>
2890
+ </div>
2891
+ </div>
2892
+ <!-- KPI grid -->
2893
+ <div class="p-6 grid grid-cols-4 gap-4">
2894
+ <div class="bg-white rounded border border-[rgba(72,91,120,0.05)] shadow-subtle p-4 flex flex-col gap-1">
2895
+ <div class="text-meta font-medium text-ink-secondary">Arrivals</div>
2896
+ <div class="text-3xl font-semibold text-ink">12</div>
2897
+ <div class="text-caption text-ok flex items-center gap-1">
2898
+ <svg class="w-3 h-3"><use href="#ic-check"/></svg> +3 vs yesterday
2899
+ </div>
2900
+ </div>
2901
+ <div class="bg-white rounded border border-[rgba(72,91,120,0.05)] shadow-subtle p-4 flex flex-col gap-1">
2902
+ <div class="text-meta font-medium text-ink-secondary">Departures</div>
2903
+ <div class="text-3xl font-semibold text-ink">8</div>
2904
+ <div class="text-caption text-ink-secondary">5 checked out</div>
2905
+ </div>
2906
+ <div class="bg-white rounded border border-[rgba(72,91,120,0.05)] shadow-subtle p-4 flex flex-col gap-1">
2907
+ <div class="text-meta font-medium text-ink-secondary">Occupancy</div>
2908
+ <div class="text-3xl font-semibold text-primary">87%</div>
2909
+ <div class="h-1 bg-muted rounded-full overflow-hidden mt-1">
2910
+ <div class="h-full bg-primary rounded-full" style="width: 87%"></div>
2911
+ </div>
2912
+ </div>
2913
+ <div class="bg-white rounded border border-[rgba(72,91,120,0.05)] shadow-subtle p-4 flex flex-col gap-1">
2914
+ <div class="text-meta font-medium text-ink-secondary">Revenue</div>
2915
+ <div class="text-3xl font-semibold text-ink">€ 12.4k</div>
2916
+ <div class="text-caption text-ok flex items-center gap-1">
2917
+ <svg class="w-3 h-3"><use href="#ic-check"/></svg> +18% MoM
2918
+ </div>
2919
+ </div>
2920
+ </div>
2921
+ <!-- Content sections -->
2922
+ <div class="px-6 pb-6 grid grid-cols-2 gap-5">
2923
+ <div class="bg-white rounded-lg border border-border p-5">
2924
+ <div class="flex items-center justify-between mb-3">
2925
+ <div class="text-action font-semibold text-ink">Today's arrivals</div>
2926
+ <a class="text-primary text-body hover:underline cursor-pointer">View all →</a>
2927
+ </div>
2928
+ <div class="flex flex-col gap-2">
2929
+ <div class="flex items-center justify-between py-2 border-b border-border-light">
2930
+ <div><div class="text-body text-ink font-medium">Anna Schmidt</div><div class="text-caption text-ink-secondary">Room 101 · 3 nights</div></div>
2931
+ <span class="hf-pill status-booking-confirmed">Confirmed</span>
2932
+ </div>
2933
+ <div class="flex items-center justify-between py-2">
2934
+ <div><div class="text-body text-ink font-medium">Marco Rossi</div><div class="text-caption text-ink-secondary">Room 205 · 5 nights</div></div>
2935
+ <span class="hf-pill status-booking-check-in">Check-in</span>
2936
+ </div>
2937
+ </div>
2938
+ </div>
2939
+ <div class="bg-white rounded-lg border border-border p-5">
2940
+ <div class="text-action font-semibold text-ink mb-3">Quick actions</div>
2941
+ <div class="grid grid-cols-2 gap-3">
2942
+ <button class="rounded-[4px] border border-[rgba(72,91,120,0.15)] p-3 flex flex-col items-center gap-1 hover:bg-section transition-colors">
2943
+ <svg class="w-5 h-5 text-primary"><use href="#ic-plus"/></svg>
2944
+ <div class="text-caption text-ink-secondary">New booking</div>
2945
+ </button>
2946
+ <button class="rounded-[4px] border border-[rgba(72,91,120,0.15)] p-3 flex flex-col items-center gap-1 hover:bg-section transition-colors">
2947
+ <svg class="w-5 h-5 text-ok"><use href="#ic-check"/></svg>
2948
+ <div class="text-caption text-ink-secondary">Check-in</div>
2949
+ </button>
2950
+ <button class="rounded-[4px] border border-[rgba(72,91,120,0.15)] p-3 flex flex-col items-center gap-1 hover:bg-section transition-colors">
2951
+ <svg class="w-5 h-5 text-coral"><use href="#ic-log-out"/></svg>
2952
+ <div class="text-caption text-ink-secondary">Check-out</div>
2953
+ </button>
2954
+ <button class="rounded-[4px] border border-[rgba(72,91,120,0.15)] p-3 flex flex-col items-center gap-1 hover:bg-section transition-colors">
2955
+ <svg class="w-5 h-5 text-ink-steel"><use href="#ic-settings"/></svg>
2956
+ <div class="text-caption text-ink-secondary">Settings</div>
2957
+ </button>
2958
+ </div>
2959
+ </div>
2960
+ </div>
2961
+ </div>
2962
+
2963
+ <div class="snippet">
2964
+ <button class="copy-btn" onclick="copySnippet(this)">Copy</button>
2965
+ <pre>
2966
+ &lt;!-- LIST PAGE structure --&gt;
2967
+ &lt;div class="border border-border rounded-lg overflow-hidden"&gt;
2968
+ &lt;div class="px-6 py-4 bg-white"&gt; &lt;!-- title + primary action --&gt; &lt;/div&gt;
2969
+ &lt;div class="flex border-b border-border bg-white"&gt; &lt;!-- sub-filter tabs --&gt; &lt;/div&gt;
2970
+ &lt;div class="px-6 py-3 bg-white border-b border-border"&gt; &lt;!-- filters bar --&gt; &lt;/div&gt;
2971
+ &lt;div class="bg-white"&gt; &lt;!-- &lt;table&gt; --&gt; &lt;/div&gt;
2972
+ &lt;div class="bg-section border-t border-border px-6 py-3"&gt; &lt;!-- footer pager --&gt; &lt;/div&gt;
2973
+ &lt;/div&gt;
2974
+
2975
+ &lt;!-- DETAIL PAGE structure --&gt;
2976
+ &lt;div class="border border-border rounded-lg overflow-hidden bg-section"&gt;
2977
+ &lt;div class="px-6 py-3 bg-white border-b border-border"&gt; &lt;!-- breadcrumbs --&gt; &lt;/div&gt;
2978
+ &lt;div class="px-6 py-4 bg-white border-b border-border"&gt; &lt;!-- title + status + actions --&gt; &lt;/div&gt;
2979
+ &lt;div class="flex border-b border-border bg-white"&gt; &lt;!-- tabs --&gt; &lt;/div&gt;
2980
+ &lt;div class="grid grid-cols-3 gap-5 p-6"&gt;
2981
+ &lt;div class="col-span-2"&gt; &lt;!-- main content cards --&gt; &lt;/div&gt;
2982
+ &lt;div class="col-span-1"&gt; &lt;!-- sidebar: KPI + actions --&gt; &lt;/div&gt;
2983
+ &lt;/div&gt;
2984
+ &lt;/div&gt;
2985
+
2986
+ &lt;!-- FORM PAGE structure (sticky footer) --&gt;
2987
+ &lt;div class="border border-border rounded-lg overflow-hidden bg-section"&gt;
2988
+ &lt;div class="px-6 py-4 bg-white border-b border-border"&gt; &lt;!-- breadcrumb + title --&gt; &lt;/div&gt;
2989
+ &lt;div class="p-6 flex flex-col gap-5"&gt;
2990
+ &lt;div class="bg-white rounded-lg border border-border p-5"&gt; &lt;!-- section 1 --&gt; &lt;/div&gt;
2991
+ &lt;div class="bg-white rounded-lg border border-border p-5"&gt; &lt;!-- section 2 --&gt; &lt;/div&gt;
2992
+ &lt;/div&gt;
2993
+ &lt;div class="bg-white border-t border-border px-6 py-4 sticky bottom-0"&gt; &lt;!-- Cancel + Save --&gt; &lt;/div&gt;
2994
+ &lt;/div&gt;
2995
+
2996
+ &lt;!-- DASHBOARD structure --&gt;
2997
+ &lt;div class="border border-border rounded-lg overflow-hidden bg-section"&gt;
2998
+ &lt;div class="px-6 py-4 bg-white border-b border-border"&gt; &lt;!-- title + pill-tabs + date --&gt; &lt;/div&gt;
2999
+ &lt;div class="p-6 grid grid-cols-4 gap-4"&gt; &lt;!-- KPI tiles (shadow-subtle) --&gt; &lt;/div&gt;
3000
+ &lt;div class="px-6 pb-6 grid grid-cols-2 gap-5"&gt; &lt;!-- content cards --&gt; &lt;/div&gt;
3001
+ &lt;/div&gt;</pre>
3002
+ </div>
3003
+ </section>
3004
+
3005
+ </main>
3006
+ </div>
3007
+
3008
+ <script>
3009
+ function copySnippet(btn) {
3010
+ const pre = btn.closest('.snippet').querySelector('pre');
3011
+ navigator.clipboard.writeText(pre.textContent.trim()).then(() => {
3012
+ btn.textContent = 'Copied!'; btn.classList.add('copied');
3013
+ setTimeout(() => { btn.textContent = 'Copy'; btn.classList.remove('copied'); }, 2000);
3014
+ });
3015
+ }
3016
+ </script>
3017
+ </body>
3018
+ </html>