@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,80 @@
1
+ # Project AI Instructions
2
+
3
+ > Drop this file into the **root** of a new project (e.g. `/CLAUDE.md` next to `package.json`). Claude Code, Cursor (`@CLAUDE.md`), and Aider (`/add CLAUDE.md`) read it automatically. Replace `{{PROJECT_NAME}}` placeholders.
4
+
5
+ ## Project: {{PROJECT_NAME}}
6
+
7
+ This project follows the **HotelFriend Design System v0.1.0**. The design system is the SSOT for all UI work — tokens, components, states, spacing, typography. Do NOT introduce off-system colors, sizes, or one-off shadows.
8
+
9
+ ## Where the design system lives in this repo
10
+
11
+ - **`docs/portable-design/components.html`** — **PRIMARY visual reference** (open in browser). Canonical rendering of every component. When in doubt, look here.
12
+ - `docs/portable-design/UI_DESIGN.md` — narrative SSOT (read this first for context, anatomy, decision rationale)
13
+ - `docs/portable-design/tokens.figma.json` — atomic tokens (Tokens Studio format)
14
+ - `docs/portable-design/states-canonical.json` — canonical interactive states for 24 components (modal, alert, pagination, dropdown items, checkboxes etc.)
15
+ - `docs/portable-design/pre-built/`:
16
+ - `tailwind.css` (Tailwind v4, recommended) — `@theme {}` token bindings
17
+ - `tailwind.preset.js` (Tailwind v3 legacy)
18
+ - `tokens.css` (vanilla CSS variables)
19
+ - `_tokens.scss` (SCSS variables)
20
+ - `tokens.ts` (TypeScript const)
21
+ - `shadcn-tokens.css` (shadcn/ui contract)
22
+ - **`components.css`** — `.hf-*` component primitives (extracted from components.html — import this in your CSS!)
23
+ - `docs/portable-design/portal-audit.html` — **archival** legacy portal snapshot. Do NOT copy patterns from here for new code.
24
+
25
+ ## Hard rules — never violate these
26
+
27
+ 1. **Colors:** Use only tokens defined in `pre-built/tailwind.css` / `pre-built/tokens.css`. Never hard-code hex codes. The primary brand color is `#24AFE8` (CSS var `--color-primary`, Tailwind `primary`). The four status colors are success `#59B59D`, warning `#FFBD5A`, error `#EA6565`, coral `#F87921`.
28
+ 2. **Status badges:** Use `.hf-pill .status-{domain}-{state}`. Color is `var(--color-badge-{domain}-{state}-color)`, background is `var(--color-badge-{domain}-{state}-bg)` (15% alpha). Cancellation reasons (`canceled-by-hotel/guest/hf/pos`) all share the `.status-cancel` alias. Do NOT invent new status colors.
29
+ 3. **Component primitives — reuse, never rebuild:** Before writing a modal, alert, dropdown, pagination, tabs, checkbox, or toggle, **check `pre-built/components.css` for an existing `.hf-*` primitive**. Use `.hf-modal`, `.hf-alert`, `.hf-pagination`, `.hf-dropdown-menu`, `.hf-check`, etc. with their BEM-style children (`__header`, `__body`, `__footer`, `__icon`, `__title`, `__close`, etc.) and modifiers (`--success`, `--tinted`, `--banner`, `--compact`, `--sm`). See `UI_DESIGN.md` §5.1 for the full list.
30
+ 4. **Typography:** Family is **Roboto**. Sizes from canonical scale only: 11/13/14/15/16/18/20/24/26/30 px. Weights only 400 / 500 / 600. Line-heights 1.2 (headings), 1.5 (body), 1 (chips).
31
+ 5. **Spacing:** Multiples of 4 only. Default section gap is 20px. Never write 7px / 13px / 18px — round to the scale. (Exception: portal-exact padding `7px 10px 9px` for `.hf-alert` `help-block` is documented in components.html.)
32
+ 6. **Border radius:** `6px` (buttons/inputs/checkboxes/modals/alerts), `8px` (pagination items), `9px` (dropdowns/toasts/pill-tabs), `12px` (large cards), `99px` (status pills are 6px square — pills are NOT round). Never invent intermediate values.
33
+ 7. **Transitions:** Default `200ms ease-in-out`. Use this for hover, focus, state changes — not `0.3s` or arbitrary timings.
34
+ 8. **Shadows:** Pick from the 7 documented shadows in `UI_DESIGN.md` §3 Border-radius & Shadows: `--shadow-default`, `--shadow-subtle`, `--shadow-wrapper`, `--shadow-card`, `--shadow-modal`, `--shadow-outline`, `--shadow-hover`. Don't roll one-off `box-shadow` declarations.
35
+ 9. **Pagination active state:** Pagination active is a **subtle gray** (`bg: #E4E8EF; color: #252F4A`) — NOT primary blue. This is portal-exact and easy to get wrong. Use `.hf-pagination__item.is-active`.
36
+ 10. **Components:** Before creating a new component, check `components.html` for an existing equivalent (open in browser, search section IDs `#buttons`, `#inputs`, `#cards`, `#status`, `#tabs`, `#dropdown`, `#modal`, `#alerts`, `#pagination`, `#empty`, `#layout`). Reuse beats duplicate.
37
+
38
+ ## When the user asks for UI work
39
+
40
+ 1. **Read `UI_DESIGN.md`** — start here for new sessions.
41
+ 2. **Open `components.html`** in a browser — see the canonical rendering.
42
+ 3. **Pick existing `.hf-*` primitives** from `pre-built/components.css` first. Use Tailwind utility classes only for layout (flex/grid/spacing) — not for component chrome (colors, shadows, borders).
43
+ 4. **States matter:** every interactive element needs default + hover + focus + disabled + loading. See `states-canonical.json` for the exact declarations to mirror.
44
+ 5. **No "raw HTML" answers** — wrap markup in the documented component class system. If the design system lacks something, propose a NEW token or primitive in a comment, do not silently introduce one.
45
+
46
+ ## When the user asks for "the same look as the portal"
47
+
48
+ The visual reference is `components.html`. If the user asks "make a settings page like the portal", do this in order:
49
+
50
+ 1. Open `components.html`, find Page Layouts section (`#layout`). Pick the matching pattern (List / Detail / Form / Dashboard).
51
+ 2. Replicate the structure (Title bar → Tabs → Filters → Data grid → Footer pagination).
52
+ 3. Use only `.btn-primary`, `.btn-outline-primary`, `.btn-cancel`, `.btn-danger` for buttons.
53
+ 4. Use `.hf-pill .status-{domain}-{state}` for status indicators.
54
+ 5. Wrap data sections in `.bg-white rounded-lg border border-border p-5` (the bordered card pattern — most common in portal).
55
+ 6. Use `.hf-pagination` for pager.
56
+ 7. Use `.hf-modal` / `.hf-alert` / `.hf-dropdown-menu` for floating UI.
57
+
58
+ ## Anti-patterns
59
+
60
+ - ❌ `<button class="bg-blue-500 text-white px-4 py-2 rounded">Save</button>` (Tailwind native classes for what should be a `.btn.btn-primary`)
61
+ - ❌ Inventing colors like `#1F8FCE` because "it's close to primary"
62
+ - ❌ Border-radius `8px` because "it looks better than 6px" (8px is reserved for pagination items only)
63
+ - ❌ Adding a new shadow `0 4px 12px rgba(...)` instead of `var(--shadow-hf-modal)`
64
+ - ❌ Bypassing the status-pill system with bespoke `<span class="bg-green-100 text-green-800">Active</span>`
65
+ - ❌ Building a modal from scratch with `<div class="fixed inset-0 bg-black/40">…</div>` instead of using `.hf-modal`
66
+ - ❌ Building an alert with `border-l-4 border-red` instead of `.hf-alert.hf-alert--error` (the portal alert has TOP border, not left)
67
+ - ❌ Pagination with `bg-hf-primary text-white` active — use `.hf-pagination__item.is-active` (subtle gray)
68
+ - ❌ Using native `<input type="checkbox" class="accent-primary">` instead of `<input type="checkbox" class="hf-check">` — accent-color doesn't match portal's filled-blue-with-white-tick design
69
+ - ❌ Mixing icon sets (Lucide + Font Awesome + Heroicons in the same screen)
70
+ - ❌ Copying patterns from `portal-audit.html` — that's the legacy snapshot, NOT canonical reference
71
+
72
+ ## When in doubt
73
+
74
+ Ask the user. Better to pause for 5 seconds than ship a one-off color that drifts the design system.
75
+
76
+ ---
77
+
78
+ **System version:** Design System v0.1.0
79
+ **Maintained:** alongside `UI_DESIGN.md`
80
+ **Refresh policy:** when `tokens.figma.json` changes, run `node generate-tokens.cjs --target=tailwind-v4 > pre-built/tailwind.css` (and repeat for other targets as needed). Script is in the same folder as `tokens.figma.json`. The `pre-built/components.css` file is hand-extracted from `components.html`'s `@layer components` block — re-sync manually after component changes.
@@ -0,0 +1,39 @@
1
+ # Drop this file at the project root as `.cursorrules` (or `.cursor/rules/00-design-system.md` in newer Cursor).
2
+ # Cursor reads it automatically and prepends it to every AI request.
3
+
4
+ You are working in a project that uses the **HotelFriend Design System v0.1.0**. The canonical visual reference is `docs/portable-design/components.html` (open in browser). Narrative SSOT in `docs/portable-design/UI_DESIGN.md`. Token bindings in `pre-built/tailwind.css` (v4, recommended) or `pre-built/tokens.css` (vanilla). Component primitives in `pre-built/components.css`.
5
+
6
+ # Inviolable rules
7
+
8
+ - **Colors:** only use tokens. Primary `#24AFE8` (`--color-primary` / Tailwind `primary`). Status colors success `#59B59D`, warning `#FFBD5A`, error `#EA6565`, coral `#F87921`. Cancellation reasons share `.status-cancel`. Never hard-code other hex codes.
9
+ - **Status badges:** use `.hf-pill .status-{domain}-{state}`. Color via `var(--color-badge-{domain}-{state}-color)`, bg via `var(--color-badge-{domain}-{state}-bg)`. Never invent new status colors.
10
+ - **Component primitives — reuse, never rebuild:** Use `.hf-modal`, `.hf-alert`, `.hf-pagination`, `.hf-dropdown-menu`, `.hf-tab`, `.hf-check`, `.hf-radio`, `.hf-toast` from `pre-built/components.css` BEFORE writing new component CSS. BEM children with `__` (e.g. `__header`, `__body`, `__footer`, `__icon`). Variants with `--` (`--success`, `--banner`, `--compact`). State classes with `.is-*` (`.is-active`, `.is-disabled`).
11
+ - **Typography:** Roboto only. Sizes: 11 / 13 / 14 / 15 / 16 / 18 / 20 / 24 / 26 / 30 px. Weights: 400 / 500 / 600.
12
+ - **Spacing:** multiples of 4. Default section gap 20px.
13
+ - **Border radius:** 6 (buttons/inputs/modals/alerts), 8 (pagination items), 9 (dropdowns/toasts), 12 (cards), 99 (pills are square 6px, not round).
14
+ - **Transitions:** `200ms ease-in-out`.
15
+ - **Shadows:** pick from the 7 documented (`default`, `subtle`, `wrapper`, `card`, `modal`, `outline`, `hover`). No bespoke shadows.
16
+ - **Pagination active state:** subtle gray `bg: #E4E8EF; color: #252F4A` — NOT primary blue. Use `.hf-pagination__item.is-active`.
17
+ - **Components:** check `components.html` (open in browser, search anchors `#buttons`, `#modal`, etc.) for an existing equivalent before writing new component code. Reuse beats duplicate.
18
+
19
+ # Workflow
20
+
21
+ 1. Open `docs/portable-design/UI_DESIGN.md` whenever starting a UI task.
22
+ 2. Open `docs/portable-design/components.html` in a browser to verify visual decisions.
23
+ 3. Reuse `.hf-*` primitives from `pre-built/components.css` before creating new ones.
24
+ 4. For interactive elements, mirror states declared in `states-canonical.json` (default + hover + focus + disabled + loading).
25
+ 5. If a token is missing for what the user asks, propose adding one in `tokens.figma.json` rather than hard-coding.
26
+
27
+ # Anti-patterns to refuse
28
+
29
+ - Hard-coded hex colors not in `tokens.css`.
30
+ - Tailwind utility-only components for things that have primitives (e.g. building a modal with raw `<div class="fixed inset-0 bg-black/40">` instead of using `.hf-modal`).
31
+ - One-off shadows / radii / paddings outside the documented scale.
32
+ - Mixing icon sets within a single screen (Lucide + FA + Heroicons).
33
+ - Pagination with `bg-hf-primary text-white` active state (it's subtle gray — use `.hf-pagination__item.is-active`).
34
+ - Native checkboxes with `accent-color` (use `.hf-check`).
35
+ - Alerts with left-border accent (portal uses TOP 3px accent bar — use `.hf-alert`).
36
+ - Copying patterns from `portal-audit.html` (legacy archival snapshot — NOT canonical).
37
+ - Skipping component states (always provide hover / focus / disabled at minimum).
38
+
39
+ When unsure, prefer asking the user over inventing.
@@ -0,0 +1,45 @@
1
+ # GitHub Copilot instructions
2
+
3
+ > Drop this file at `.github/copilot-instructions.md`. Copilot reads it for repository-wide context.
4
+
5
+ This project uses the **HotelFriend Design System v0.1.0**. Canonical visual reference: `docs/portable-design/components.html` (open in browser). Token bindings: `pre-built/tailwind.css` (v4, recommended) or `pre-built/tokens.css` (vanilla). Component primitives: `pre-built/components.css`. Narrative SSOT: `docs/portable-design/UI_DESIGN.md`.
6
+
7
+ ## Hard rules — never violate
8
+
9
+ 1. **Colors:** use only tokens. Brand accent `#24AFE8` (`var(--color-hf-accent)` / Tailwind `bg-hf-accent`). Status colors via `var(--color-hf-status-{success|warning|error|info})`. Cancellation reasons share `.status-cancel`. Never hard-code other hex codes.
10
+ 2. **Status badges:** use `.hf-pill .status-{domain}-{state}`. Color via `var(--color-badge-{domain}-{state}-color)`, background via `var(--color-badge-{domain}-{state}-bg)` (15% alpha). Never invent new status colors.
11
+ 3. **Component primitives — reuse, never rebuild:** Use `.hf-modal`, `.hf-alert`, `.hf-pagination`, `.hf-dropdown-menu`, `.hf-tab`, `.hf-check`, `.hf-radio`, `.hf-toast` from `pre-built/components.css` BEFORE writing new component CSS.
12
+ 4. **Typography:** Roboto only. Sizes from scale: 11 / 13 / 14 / 15 / 16 / 18 / 20 / 24 / 26 / 30 px. Weights: 400 / 500 / 600. Line-heights: 1.2 (headings), 1.5 (body), 1 (chips).
13
+ 5. **Spacing:** multiples of 4 only. Default section gap 20 px. Never write 7 / 13 / 18 px.
14
+ 6. **Border radius:** `6px` (buttons/inputs/modals/alerts), `8px` (pagination items), `9px` (dropdowns/toasts), `12px` (large cards), `99px` (pill-rounded). No intermediate values.
15
+ 7. **Transitions:** `200ms ease-in-out` for all hover/focus/state changes. No `0.3s`, no arbitrary timings.
16
+ 8. **Shadows:** pick from documented set (`default`, `subtle`, `wrapper`, `card`, `modal`, `outline`, `hover`). No bespoke `box-shadow`.
17
+ 9. **Pagination active state:** subtle gray (`bg: #E4E8EF; color: #252F4A`) — NOT primary blue. Use `.hf-pagination__item.is-active`.
18
+ 10. **Components:** check `components.html` (open in browser, search anchors `#buttons`, `#modal`, etc.) for an existing equivalent before writing new component code.
19
+
20
+ ## When generating UI code
21
+
22
+ - **Button classes:** `.btn-primary`, `.btn-hf-outline-primary`, `.btn-cancel`, `.btn-danger`, `.btn-reset-filters` + compact variants (`btn-b-gray`, `btn-add-grey`, `btn-edit-sm`, `btn-trash`, `btn-copy-sm`, `btn-plus-sm`)
23
+ - **Form primitives:** `.form-control` (inputs), `.hf-check` (checkbox), `.hf-radio` (radio), toggle pattern
24
+ - **Containers:** `.hf-modal` + `__header/__title/__body/__footer/__close`, `.hf-alert` + variants/modifiers, `.hf-toast`, bordered card `<div class="bg-white rounded-lg border border-border p-5">`, elevated card with `shadow-subtle`
25
+ - **Navigation:** `.hf-tab` + `--sm` + `__count`, `.hf-pill-tabs` + `.hf-pill-tab`, `.hf-pagination` + `__item/__ellipsis`, `.hf-dropdown-menu` + `__header/__item/__shortcut/__icon/__divider`
26
+ - **Status:** `.hf-pill .status-{domain}-{state}` + modifiers (`--striped`, `--dd`, `.is-active`, `min-w-*`)
27
+ - **Loading:** `.skeleton` for shimmer, `.hf-spin` for spinner
28
+ - Every interactive element needs: default + `:hover` + `:focus-visible` + `:disabled` states at minimum. See `states-canonical.json`.
29
+
30
+ ## Forbidden patterns
31
+
32
+ - Hard-coded hex colors not in `pre-built/tokens.css`.
33
+ - Building modals/alerts/dropdowns/pagination from scratch when `pre-built/components.css` has primitives.
34
+ - Tailwind utility classes for component chrome — only use them for layout (flex/grid/spacing).
35
+ - Border-radius outside `6 / 8 / 9 / 12 / 99`.
36
+ - Spacing values outside the 4-multiple scale.
37
+ - Bespoke `box-shadow` declarations.
38
+ - Mixing icon libraries (Lucide + Font Awesome + Heroicons) in the same screen.
39
+ - Pagination active state with primary blue (use subtle gray).
40
+ - Native checkboxes with `accent-color` (use `.hf-check`).
41
+ - Left-border alerts (portal uses top accent bar — use `.hf-alert`).
42
+ - Copying patterns from `portal-audit.html` (archival snapshot, NOT canonical).
43
+ - Skipping component states.
44
+
45
+ When unsure, mirror an example from `components.html`.
@@ -0,0 +1,43 @@
1
+ # HotelFriend Design System — AI Reference (compact)
2
+
3
+ ## Colors
4
+ Primary: `#24AFE8` · Hover: `#149AD1` · Light tint: `#E9F6FC`
5
+ Neutrals: page-bg `#FBFBFC` · section-bg `#F6F7FB` · very-light `#F1F3F6` · border `#D1D6DD` · text `#2B2B2B` · secondary-text `#4B5675` · placeholder `#AEBCCF`
6
+ Status: success `#59B59D` · warning `#FFBD5A` · error `#EA6565` · coral `#F87921` · violet `#5761D8` · cancellation/deleted `#7F8FA4`
7
+ Status badges use `--color-badge-{domain}-{state}-color` + `--color-badge-{domain}-{state}-bg` (15% alpha). Domains: booking · order · fd (frontDesk) · clean (roomItem.cleaning). Cancellation reasons all share `.status-cancel`.
8
+
9
+ ## Typography
10
+ Font: Roboto · Sizes: 11 / 13 / 14 / 15 / 16 / 18 / 20 / 24 / 26 / 30 px · Weights: 400 / 500 / 600
11
+ Body: 14px/400 · Buttons: 15px/600 · Tabs (large): 16px/500 · Tabs (small/sub-filter): 15px/500 · Modal title: 18px/600 · Page title: 26px/600
12
+
13
+ ## Spacing & Shape
14
+ Spacing: multiples of 4 px (4 / 8 / 12 / 16 / 20 / 24 / 30 / 32)
15
+ Radius: 6 px (buttons/inputs/modals/alerts) · 8 px (pagination items) · 9 px (dropdowns/toasts/pill-tabs) · 12 px (large cards) · 99 px (rounded pills only)
16
+ Shadows: default `0 1px 8px rgba(0,0,0,.1)` · subtle `0 2px 4px rgba(0,0,0,.05)` (dashboard cards) · modal `0 6px 18px rgba(0,0,0,.1)` · outline `0 1px 2px rgba(72,91,120,.18)` · hover `0 2px 3px rgba(0,0,0,.06)`
17
+
18
+ ## Component primitives (`.hf-*`)
19
+
20
+ **Buttons** — `.btn-primary` 40 h / 15px / 600 / `#24AFE8` · `.btn-cancel` white bg muted text · `.btn-danger` red bg · `.btn-outline-primary` 1px primary border · `.btn-reset-filters` 38 h `#EFF6FF` bg
21
+ **Inputs** — `.form-control` 39 h / 6 r / placeholder `#AEBCCF` / focus border darkens to `#B2BAC4` (portal) or add `box-shadow: 0 0 0 2px rgba(36,175,232,.2)` for accessibility
22
+ **Checkbox/Radio** — `.hf-check` / `.hf-radio` 18×18 · transparent + 1px `#DBDFE9` border · checked = filled `#26ADE4` + white tick or dot
23
+ **Toggle** — 52×28 track · off `#DFDFDF` / on `#24AFE8` · thumb 20×20 white shadow `0 1px 6px rgba(0,0,0,.3)`
24
+ **Cards** — bordered `bg-white rounded-lg border border-border p-5` (no shadow, most common) · elevated `bg-white rounded border-[rgba(72,91,120,.05)] shadow-subtle p-4` (dashboard KPIs)
25
+ **Status pills** — `.hf-pill.status-{domain}-{state}` 6 r · 15% bg + 100% text + 1px border · modifiers: `.is-active` (transparent + inset ring) / `--striped` / `--dd` (chevron) / `min-w-[130/160/180px]`
26
+ **Tabs** — `.hf-tab` 16/500 padding 22 15 / `--sm` 15/500 padding 10 15 · active `#24AFE8` + 3px bottom · `__count` badge inside · `.hf-pill-tabs > .hf-pill-tab` segmented (Day/Week/Month)
27
+ **Dropdown** — `.hf-dropdown-menu` 9 r shadow `0 1px 10px rgba(0,0,0,.1)` · `__header` (uppercase 11px) · `__item` 14/normal hover `#F5F5F5` · `__shortcut` right-aligned · `.is-active` primary-tint · `.danger`
28
+ **Modal** — `.hf-modal` 6 r border `1px rgba(72,91,120,.15)` shadow `0 2px 4px rgba(72,91,120,.18)` · `__header` bottom border / `__footer` NO top border · sizes sm 420 / md 500 / lg 720 / xl 960
29
+ **Alerts** — `.hf-alert` white bg + 3px top accent bar + 26×26 squared icon · variants `--success/--info/--warn/--error` · modifiers `--tinted/--banner/--compact`
30
+ **Toast** — `.hf-toast` 9 r modal-shadow · `__icon` 20×20 · floating bottom-right
31
+ **Pagination** — `.hf-pagination__item` 34×34 8 r · active SUBTLE GRAY `bg: #E4E8EF` `color: #252F4A` (NOT primary blue!) · hover `bg: #F1F3F6`
32
+ **Skeleton/spinner** — `.skeleton` shimmer 1.4 s · `.hf-spin` rotate
33
+ **Icons** — Lucide preferred (inline SVG `<use>`) · Font Awesome 4 legacy (avoid in new code)
34
+
35
+ ## Hard Rules
36
+ 1. Never hard-code hex — use tokens (`--color-primary`, `$colorPrimaryDefault`, Tailwind class `primary`).
37
+ 2. Use `.hf-*` primitives BEFORE writing new component CSS — check `pre-built/components.css` first.
38
+ 3. Every interactive element must have hover, focus, and disabled states.
39
+ 4. No mixed icon sets in one component.
40
+ 5. Status badge colors via `--color-badge-{domain}-{state}-color` / `--color-badge-{domain}-{state}-bg` — never raw hex.
41
+ 6. Canonical primary is `#24AFE8`. The portal renders `#26ADE4` (`$light__Blue` SCSS) — visually identical but tokens use canonical.
42
+ 7. Pagination active is subtle gray, NOT primary blue (`.hf-pagination__item.is-active`).
43
+ 8. Alerts use TOP 3px accent bar (`.hf-alert`), NOT left-border. Modal footer has NO top border.