@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.
- package/LICENSE +21 -0
- package/README.md +558 -0
- package/README.uk.md +377 -0
- package/RFC-0001-cross-project-design-system.md +273 -0
- package/RFC-0002-semantic-tier-naming.md +296 -0
- package/UI_DESIGN.md +608 -0
- package/ai-rules/CLAUDE.md +80 -0
- package/ai-rules/cursorrules.template +39 -0
- package/ai-rules/github-copilot-instructions.md +45 -0
- package/ai-rules/system-prompt-compact.md +43 -0
- package/components.html +3018 -0
- package/generate-tokens.cjs +665 -0
- package/package.json +98 -0
- package/portal-audit.html +2306 -0
- package/pre-built/_tokens.scss +138 -0
- package/pre-built/components.css +515 -0
- package/pre-built/shadcn-tokens.css +67 -0
- package/pre-built/status.css +51 -0
- package/pre-built/stylelint-design-system.cjs +69 -0
- package/pre-built/tailwind.additive.css +158 -0
- package/pre-built/tailwind.css +158 -0
- package/pre-built/tailwind.preset.js +207 -0
- package/pre-built/tokens.css +185 -0
- package/pre-built/tokens.d.ts +240 -0
- package/pre-built/tokens.js +243 -0
- package/pre-built/tokens.ts +240 -0
- package/scripts/integration-smoke.sh +91 -0
- package/scripts/pre-commit.sh +55 -0
- package/scripts/validate-tokens.cjs +113 -0
- package/states-canonical.json +240 -0
- package/states.json +2950 -0
- package/status-map.json +47 -0
- package/tokens.figma.json +230 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
# RFC-0002 — Semantic tier naming (Phase 1B)
|
|
2
|
+
|
|
3
|
+
> **Status:** ✅ Accepted (2026-05-21) — implementation in progress
|
|
4
|
+
> **Author:** Frontend platform
|
|
5
|
+
> **Created:** 2026-05-21
|
|
6
|
+
> **Implements:** RFC-0001 §4.1 (three-tier token architecture)
|
|
7
|
+
> **Blocks:** Phase 1B implementation; Phase 2 component generator
|
|
8
|
+
> **Scope:** naming convention only — does NOT define new color values
|
|
9
|
+
|
|
10
|
+
## Resolutions (decided 2026-05-21)
|
|
11
|
+
|
|
12
|
+
- **Q1, Q3, Q4, Q5, Q6, Q8**: defaults accepted as-is (see §6).
|
|
13
|
+
- **Q2 — override**: keep **only 4 generic fg levels** (`default`, `muted`, `subtle`, `faint`). The portal-specific `fg-steel` (`#485B78`) and `fg-emphasis` (`#252F4A`) **do NOT promote to semantic tier**. They become **component-tier tokens in Phase 2** (used exclusively by `.hf-tab`/`.hf-pagination__item` inactive/active states). Until Phase 2 lands, these stay as bare hex in `components.css` with explicit TODO comments.
|
|
14
|
+
- **Q7 — default + refinement**: drop `badge.*` from tokens (Option B), BUT the domain→semantic mapping (e.g. `booking.confirmed` → `info`) must NOT be hardcoded in `components.css` — that would re-introduce the drift RFC-0001 §5b warned about. Instead: create a new **`status-map.json`** file that the generator reads to emit `.status-{domain}-{state}` CSS classes. For Phase 1B implementation the map MAY temporarily live as a hardcoded block in `components.css`, but only with an explicit `TODO: extract to status-map.json` annotation and a separate Phase 2 task to externalize.
|
|
15
|
+
|
|
16
|
+
## 1. Goal
|
|
17
|
+
|
|
18
|
+
Restructure `tokens.figma.json` into three explicit tiers so:
|
|
19
|
+
|
|
20
|
+
- **App code references roles, not raw values** (`bg-hf-bg-section` instead of `bg-hf-neutral-very-light`).
|
|
21
|
+
- **Themes are swappable** at the semantic layer without touching primitives.
|
|
22
|
+
- **AI agents have a stable, predictable token-set** to lean on when generating new products from the Blueprint.
|
|
23
|
+
- **`pre-built/components.css` can be generated** from a single token source (Phase 2), instead of hand-mirrored from `components.html`.
|
|
24
|
+
|
|
25
|
+
## 2. Conceptual model
|
|
26
|
+
|
|
27
|
+
Three tiers, per W3C DTCG + Tokens Studio conventions:
|
|
28
|
+
|
|
29
|
+
| Tier | Example | Purpose | Used by app code? |
|
|
30
|
+
|------|---------|---------|-------------------|
|
|
31
|
+
| **1. Primitive** | `hf-blue-500: #24AFE8` | Raw values, palette ramps | ❌ No |
|
|
32
|
+
| **2. Semantic** | `hf-color-accent: {hf-blue-500}` | Role tokens — what app code references | ✅ Yes |
|
|
33
|
+
| **3. Component** *(deferred → Phase 2)* | `hf-button-bg: {hf-color-accent}` | Component-specific overrides | ✅ Yes, if defined |
|
|
34
|
+
|
|
35
|
+
> **Why three tiers, not two:** primitives are the only place colors actually live. Semantic aliases them by role. Components MAY alias semantics for cases where one component needs to drift (e.g. dark-mode-only overrides). Without primitives there's no source-of-truth; without semantics there's no theming.
|
|
36
|
+
|
|
37
|
+
## 3. Naming conventions
|
|
38
|
+
|
|
39
|
+
### 3.1 Primitive tier
|
|
40
|
+
|
|
41
|
+
**Pattern:** `{type}-{family}-{step}`
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
hf-blue-500 — color, family=blue, step=500
|
|
45
|
+
hf-gray-300 — color, family=gray, step=300
|
|
46
|
+
hf-radius-md — radius, family=md (single step)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- **Type:** `color`, `radius`, `space`, `shadow`, `font-size`, `font-weight`, `line-height`, `z`
|
|
50
|
+
- **Family:** color-family-name OR direct value name (for non-color types)
|
|
51
|
+
- **Step:** Tailwind-style numeric `50 / 100 / 200 / 300 / 400 / 500 / 600 / 700 / 800 / 900 / 950`. Lower = lighter (for light-on-dark families like gray, blue) or sparser (for accents).
|
|
52
|
+
|
|
53
|
+
**Color families we need:**
|
|
54
|
+
|
|
55
|
+
| Family | Anchor | Used by | Likely steps |
|
|
56
|
+
|--------|--------|---------|--------------|
|
|
57
|
+
| `blue` | `#24AFE8` @ 500 | primary brand | 50, 100, 500, 600 (anchored to portal) |
|
|
58
|
+
| `gray` | `#2B2B2B` @ 900 | neutrals, text, borders | 25, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950 (most populated ramp) |
|
|
59
|
+
| `green` | `#59B59D` @ 500 | success, due-in, clean | 500 (single — phase 2 extend) |
|
|
60
|
+
| `amber` | `#FFBD5A` @ 400 | warning, waiting, new | 400, 600 (#FFC900 frontdesk-OOO) |
|
|
61
|
+
| `red` | `#EA6565` @ 400 | error, no-show, dirty | 400, 500 (#FB5A56), 700 (#D9534F) |
|
|
62
|
+
| `orange` | `#F87921` @ 500 | coral, check-out, in-progress | 500, 700 (#A55505 due-out) |
|
|
63
|
+
| `violet` | `#5761D8` @ 500 | offer, inspected | 500 |
|
|
64
|
+
| `slate` | `#7F8FA4` @ 500 | canceled, deleted, OOS | 500 |
|
|
65
|
+
| `olive` | `#5B7A02` @ 700 | check-in (lime) | 700 |
|
|
66
|
+
|
|
67
|
+
**Why this granularity:** the portal palette is *already* sparse. Forcing full 50–950 ramps everywhere would mean inventing colors that don't exist in production. Phase 1B defines only what we actually use; Phase 2+ extends ramps if/when designer needs them (e.g. for dark mode).
|
|
68
|
+
|
|
69
|
+
### 3.2 Semantic tier
|
|
70
|
+
|
|
71
|
+
**Pattern:** `{type}-{slot}-{variant?}`
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
hf-color-fg-default — type=color, slot=fg, variant=default (implicit)
|
|
75
|
+
hf-color-fg-muted — type=color, slot=fg, variant=muted
|
|
76
|
+
hf-color-bg-surface — slot=bg, variant=surface
|
|
77
|
+
hf-color-accent-hover — slot=accent, variant=hover
|
|
78
|
+
hf-color-status-success — slot=status, variant=success
|
|
79
|
+
hf-color-status-success-bg — slot=status, variant=success, sub-variant=bg
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
- **Slot** answers *"what role does this color play"*: `accent`, `bg`, `fg`, `border`, `status-*`
|
|
83
|
+
- **Variant** answers *"what flavor of that role"*: `default` (implicit, dropped from emitted name), `muted`, `subtle`, `emphasis`, `hover`, `disabled`
|
|
84
|
+
|
|
85
|
+
**Industry inspiration:**
|
|
86
|
+
|
|
87
|
+
- GitHub Primer: `fgColor-default`, `fgColor-muted`, `bgColor-emphasis`
|
|
88
|
+
- Atlassian: `ds-text-subtle`, `ds-background-input`
|
|
89
|
+
- Radix / shadcn: `--primary` + `--primary-foreground` pair convention
|
|
90
|
+
|
|
91
|
+
We borrow **slot.variant nesting** from Primer + the **`-foreground` pair** idea from Radix where it helps (e.g. `accent` + `on-accent` for text on top of accent backgrounds).
|
|
92
|
+
|
|
93
|
+
### 3.3 Component tier (deferred)
|
|
94
|
+
|
|
95
|
+
Component tokens come ONLY when a component diverges from the semantic layer. For Phase 1B we deliberately ship ZERO component tokens — everything binds to semantic. Phase 2 will introduce component tokens for cases like:
|
|
96
|
+
|
|
97
|
+
- Button — if we want a primary button bg ≠ accent (e.g. dark variant)
|
|
98
|
+
- Modal — if modal shadow ≠ generic floating-UI shadow
|
|
99
|
+
- Pagination active — currently uses a unique `#252F4A` not represented by any other slot
|
|
100
|
+
|
|
101
|
+
## 4. Proposed semantic tier — complete list
|
|
102
|
+
|
|
103
|
+
### 4.1 Accent / brand (5 tokens)
|
|
104
|
+
|
|
105
|
+
| Token | Aliases primitive | Replaces (Phase 1A name) |
|
|
106
|
+
|-------|-------------------|-------------------------|
|
|
107
|
+
| `hf-color-accent` | `hf-blue-500` | `--color-hf-primary` |
|
|
108
|
+
| `hf-color-accent-hover` | `hf-blue-600` | `--color-hf-primary-hover` |
|
|
109
|
+
| `hf-color-accent-subtle` | `hf-blue-100` | `--color-hf-primary-light-tint` (#E9F6FC) |
|
|
110
|
+
| `hf-color-accent-subtler` | `hf-blue-50` | `--color-hf-primary-tint-bg` (#EFF6FF) |
|
|
111
|
+
| `hf-color-on-accent` | `white` | implicit — for text on accent bg |
|
|
112
|
+
|
|
113
|
+
### 4.2 Background slots (5 tokens)
|
|
114
|
+
|
|
115
|
+
| Token | Aliases | Replaces |
|
|
116
|
+
|-------|---------|----------|
|
|
117
|
+
| `hf-color-bg-page` | `hf-gray-25` | `color-hf-neutral-light-grey` (#FBFBFC) |
|
|
118
|
+
| `hf-color-bg-section` | `hf-gray-50` | `color-hf-neutral-bg-accent` (#F6F7FB) |
|
|
119
|
+
| `hf-color-bg-muted` | `hf-gray-100` | `color-hf-neutral-very-light` (#F1F3F6) — used for hover, inputs |
|
|
120
|
+
| `hf-color-bg-surface` | `white` | the "card" background |
|
|
121
|
+
| `hf-color-bg-hover` | `#F5F5F5` | currently bare hex in `components.css` (dropdown hover) |
|
|
122
|
+
|
|
123
|
+
> **Decision needed (Q1):** is `hf-color-bg-hover` (`#F5F5F5`) really distinct from `hf-color-bg-muted` (`#F1F3F6`)? Or fold them into one?
|
|
124
|
+
|
|
125
|
+
### 4.3 Foreground (text) slots (6 tokens)
|
|
126
|
+
|
|
127
|
+
| Token | Aliases | Replaces |
|
|
128
|
+
|-------|---------|----------|
|
|
129
|
+
| `hf-color-fg` *(no -default — see §6 Q4)* | `hf-gray-900` | `color-hf-text-primary` (#2B2B2B) |
|
|
130
|
+
| `hf-color-fg-muted` | `hf-gray-700` | `color-hf-text-secondary` (#4B5675) |
|
|
131
|
+
| `hf-color-fg-subtle` | `hf-gray-600` | `color-hf-text-useful` (#7E8EA6) — for hints |
|
|
132
|
+
| `hf-color-fg-faint` | `hf-gray-400` | `color-hf-text-placeholder` (#AEBCCF) — placeholder, disabled |
|
|
133
|
+
| `hf-color-fg-steel` | `hf-gray-800` | `color-hf-text-steel-blue` (#485B78) — tab/nav inactive |
|
|
134
|
+
| `hf-color-fg-emphasis` | `hf-gray-950` | currently bare hex `#252F4A` in pagination active |
|
|
135
|
+
|
|
136
|
+
> **Decision needed (Q2):** four levels of fg (default/muted/subtle/faint) plus two specific roles (steel, emphasis) — is that the right axis-count? Primer uses 4. Radix uses 2 (`fg` + `fg-muted`). Our portal currently uses 6+.
|
|
137
|
+
|
|
138
|
+
### 4.4 Border slots (3 tokens)
|
|
139
|
+
|
|
140
|
+
| Token | Aliases | Replaces |
|
|
141
|
+
|-------|---------|----------|
|
|
142
|
+
| `hf-color-border` | `hf-gray-300` | `color-hf-neutral-border` (#D1D6DD) — default |
|
|
143
|
+
| `hf-color-border-subtle` | `hf-gray-200` | `color-hf-neutral-light-blue-gray` (#E4E8EF) — dividers |
|
|
144
|
+
| `hf-color-border-strong` | `hf-gray-400` | `color-hf-neutral-border-hover` (#B2BAC4) — hover/focus |
|
|
145
|
+
|
|
146
|
+
Plus implicitly: `hf-color-border-accent` = `hf-color-accent` for primary-bordered things.
|
|
147
|
+
|
|
148
|
+
### 4.5 Status slots (semantic feedback)
|
|
149
|
+
|
|
150
|
+
We need both `color` (text+border) and `bg` (15% alpha tint) per status. Two naming options:
|
|
151
|
+
|
|
152
|
+
**Option A — flat slot suffix:**
|
|
153
|
+
```
|
|
154
|
+
hf-color-status-success
|
|
155
|
+
hf-color-status-success-bg
|
|
156
|
+
hf-color-status-success-fg (same as -status-success — for text on the badge)
|
|
157
|
+
hf-color-status-warning, -warning-bg, ...
|
|
158
|
+
hf-color-status-error, -error-bg, ...
|
|
159
|
+
hf-color-status-info, -info-bg, ...
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Option B — Radix-style pair:**
|
|
163
|
+
```
|
|
164
|
+
hf-color-success
|
|
165
|
+
hf-color-success-foreground
|
|
166
|
+
hf-color-success-subtle (the 15% bg)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
→ **Recommended: Option A** (mirrors GitHub Primer + closer to Tailwind utility derivation).
|
|
170
|
+
|
|
171
|
+
Full list (Option A):
|
|
172
|
+
|
|
173
|
+
| Token | Aliases | Note |
|
|
174
|
+
|-------|---------|------|
|
|
175
|
+
| `hf-color-status-success` | `hf-green-500` (#59B59D) | success, due-in, clean |
|
|
176
|
+
| `hf-color-status-success-bg` | `rgba(89,181,157,.15)` | 15% alpha — used in pills + alert tints |
|
|
177
|
+
| `hf-color-status-warning` | `hf-amber-400` (#FFBD5A) | warning, waiting, new |
|
|
178
|
+
| `hf-color-status-warning-bg` | `rgba(255,189,90,.15)` | |
|
|
179
|
+
| `hf-color-status-warning-strong` | `hf-amber-600` (#FFC900) | frontdesk out-of-order (more saturated) |
|
|
180
|
+
| `hf-color-status-error` | `hf-red-400` (#EA6565) | error, no-show, dirty, action-required |
|
|
181
|
+
| `hf-color-status-error-bg` | `rgba(234,101,101,.15)` | |
|
|
182
|
+
| `hf-color-status-error-strong` | `hf-red-700` (#D9534F) | btn-danger (deeper) |
|
|
183
|
+
| `hf-color-status-error-alt` | `hf-red-500` (#FB5A56) | btn-cancel-red, deleted (between rouge and crimson) |
|
|
184
|
+
| `hf-color-status-info` | `hf-color-accent` (alias) | alert-info uses accent |
|
|
185
|
+
| `hf-color-status-info-bg` | `rgba(36,175,232,.15)` | |
|
|
186
|
+
| `hf-color-status-cancel` | `hf-slate-500` (#7F8FA4) | cancellations, deleted, OOS |
|
|
187
|
+
| `hf-color-status-cancel-bg` | `rgba(127,143,164,.15)` | |
|
|
188
|
+
| `hf-color-status-coral` | `hf-orange-500` (#F87921) | check-out, in-progress |
|
|
189
|
+
| `hf-color-status-coral-bg` | `rgba(248,121,33,.15)` | |
|
|
190
|
+
| `hf-color-status-violet` | `hf-violet-500` (#5761D8) | offer, inspected |
|
|
191
|
+
| `hf-color-status-violet-bg` | `rgba(87,97,216,.15)` | |
|
|
192
|
+
| `hf-color-status-olive` | `hf-olive-700` (#5B7A02) | check-in (rare, very dark) |
|
|
193
|
+
| `hf-color-status-olive-bg` | `rgba(91,122,2,.15)` | |
|
|
194
|
+
| `hf-color-status-orange-deep` | `hf-orange-700` (#A55505) | due-out (rare brown-orange) |
|
|
195
|
+
| `hf-color-status-orange-deep-bg` | `rgba(165,85,5,.15)` | |
|
|
196
|
+
|
|
197
|
+
> **Decision needed (Q3):** the last 5 (coral, violet, olive, orange-deep, cancel) are really portal-specific status colors, not generic semantic feedback. Worth a sub-namespace `hf-color-status-domain-{name}`? Or just leave under `status-*` and document them as "portal status colors"?
|
|
198
|
+
|
|
199
|
+
### 4.6 Domain status badges (replaces `badge.{domain}.{state}`)
|
|
200
|
+
|
|
201
|
+
The current `badge.booking.confirmed.color/bg` structure has 4 levels of nesting — ugly in CSS (`--color-hf-badge-booking-confirmed-color`). Phase 1B options:
|
|
202
|
+
|
|
203
|
+
**Option A — keep, just rebind to semantic:**
|
|
204
|
+
```
|
|
205
|
+
badge.booking.confirmed.color → semantic: {hf-color-status-info}
|
|
206
|
+
badge.booking.confirmed.bg → semantic: {hf-color-status-info-bg}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Pros: backwards-compatible class names (`status-booking-confirmed` still works).
|
|
210
|
+
Cons: keeps the awkward CSS variable names.
|
|
211
|
+
|
|
212
|
+
**Option B — drop `badge.*`, generate CSS classes from semantic tokens directly:**
|
|
213
|
+
```
|
|
214
|
+
.status-booking-confirmed → color: var(--hf-color-status-info); background: var(--hf-color-status-info-bg);
|
|
215
|
+
.status-booking-new → color: var(--hf-color-status-warning); background: var(--hf-color-status-warning-bg);
|
|
216
|
+
...
|
|
217
|
+
```
|
|
218
|
+
The mapping (booking.confirmed→info, booking.new→warning, etc.) lives in `components.css` (or, in Phase 2, in a separate `status-map.json` that the generator reads).
|
|
219
|
+
|
|
220
|
+
Pros: simpler tokens; semantic intent visible.
|
|
221
|
+
Cons: lose the per-status-color granularity in tokens (e.g. can't theme `booking.confirmed` to be green without changing `info` globally).
|
|
222
|
+
|
|
223
|
+
→ **Recommended: Option B**. The portal CURRENTLY uses status colors uniformly — every "confirmed" status is the same blue, every "completed" is the same green. There's no business reason for `booking.confirmed.color` ≠ `order.confirmed.color`. They share an underlying meaning.
|
|
224
|
+
|
|
225
|
+
The CSS classes (`.status-booking-confirmed`, `.status-order-completed`, etc.) stay — they're the public API. They just point to semantic tokens instead of per-domain ones.
|
|
226
|
+
|
|
227
|
+
### 4.7 Non-color types (font/space/radius/shadow)
|
|
228
|
+
|
|
229
|
+
Keep the Phase 1A naming since these don't have a strong semantic layer in the portal:
|
|
230
|
+
|
|
231
|
+
- `text-hf-xs/sm/base/md/lg/xl/2xl/h2/page/hero` (unchanged)
|
|
232
|
+
- `radius-hf-sm/md/lg/xl` (unchanged)
|
|
233
|
+
- `spacing-hf-0..8` (unchanged)
|
|
234
|
+
- `shadow-hf-default/subtle/wrapper/card/modal/outline/hover` (unchanged)
|
|
235
|
+
- `font-hf-sans` (unchanged)
|
|
236
|
+
- `font-weight-hf-regular/medium/semibold` (unchanged)
|
|
237
|
+
- `line-height-hf-headings/body/tight` (unchanged)
|
|
238
|
+
|
|
239
|
+
> **Decision needed (Q5):** do we ALSO want a semantic layer for non-color? E.g. `--hf-radius-card: var(--hf-radius-lg)`, `--hf-shadow-elevated: var(--hf-shadow-card)`. Probably not — current names are role-y enough. Default: no.
|
|
240
|
+
|
|
241
|
+
## 5. Tailwind v4 utility names (after Phase 1B)
|
|
242
|
+
|
|
243
|
+
After re-generating, the Tailwind utilities consumers would write:
|
|
244
|
+
|
|
245
|
+
```html
|
|
246
|
+
<button class="bg-hf-accent hover:bg-hf-accent-hover text-hf-on-accent">
|
|
247
|
+
Save
|
|
248
|
+
</button>
|
|
249
|
+
|
|
250
|
+
<div class="bg-hf-bg-surface text-hf-fg border border-hf-border rounded-hf-lg">
|
|
251
|
+
Card content with <span class="text-hf-fg-muted">muted text</span>
|
|
252
|
+
</div>
|
|
253
|
+
|
|
254
|
+
<span class="text-hf-status-success bg-hf-status-success-bg border border-hf-status-success px-5 py-1.5 rounded-hf-sm">
|
|
255
|
+
Success
|
|
256
|
+
</span>
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Yes — `bg-hf-fg-muted` reads weird (it's a foreground color used as background). Tailwind v4 generates ALL utilities for any `--color-*` token. We can't restrict — just discipline consumers ("use text-* with fg slots, bg-* with bg slots").
|
|
260
|
+
|
|
261
|
+
## 6. Open questions (need user decision)
|
|
262
|
+
|
|
263
|
+
| # | Question | Default |
|
|
264
|
+
|---|----------|---------|
|
|
265
|
+
| Q1 | `bg-hover` (#F5F5F5) vs `bg-muted` (#F1F3F6) — distinct or merge? | Merge — use `bg-muted` everywhere; drop #F5F5F5 as portal drift |
|
|
266
|
+
| Q2 | Number of fg axes — 4 generic (default/muted/subtle/faint) or 6 with portal-specific (steel, emphasis)? | 4 generic + the 2 portal-specific kept as separate `fg-steel`, `fg-emphasis` |
|
|
267
|
+
| Q3 | Domain-specific status colors (coral/olive/orange-deep) — under `status-*` or `status-domain-*`? | Under `status-*` flat (simpler) |
|
|
268
|
+
| Q4 | Drop `-default` suffix (use `hf-color-fg` instead of `hf-color-fg-default`)? | Yes — `default` is implicit |
|
|
269
|
+
| Q5 | Semantic layer for non-color (radius, shadow, spacing)? | No — current names are role-y enough |
|
|
270
|
+
| Q6 | Color ramps (50–950) — generate full, or sparse-as-needed? | Sparse-as-needed; complete in Phase 2 when designer adds dark mode |
|
|
271
|
+
| Q7 | Recommended status badge structure — Option A (keep `badge.*`) or B (drop, map in CSS)? | Option B (drop `badge.*` from tokens) |
|
|
272
|
+
| Q8 | `hf-color-accent` vs `hf-color-primary` for brand slot? | `accent` — matches Radix/Primer; less overloaded than `primary` (which conflicts with "primary text") |
|
|
273
|
+
|
|
274
|
+
## 7. Files affected (Phase 1B implementation, post-approval)
|
|
275
|
+
|
|
276
|
+
- **`tokens.figma.json`** — full restructure into `primitive` + `semantic` groups; `$themes` block becomes meaningful
|
|
277
|
+
- **`generate-tokens.cjs`** — resolve Tokens Studio `{path}` references (alias resolution)
|
|
278
|
+
- **`pre-built/tokens.css` / `tailwind.css`** — regenerated, emits both primitive AND semantic tokens
|
|
279
|
+
- **`pre-built/components.css`** — rebind to semantic (e.g. `var(--hf-color-fg)` instead of `var(--color-hf-text-primary)`)
|
|
280
|
+
- **`components.html`** — `@theme` block + demo markup updated to semantic names (sizeable HTML rewrite)
|
|
281
|
+
- **All docs** — `bg-hf-primary` → `bg-hf-accent` etc.
|
|
282
|
+
|
|
283
|
+
## 8. Recommended decision path
|
|
284
|
+
|
|
285
|
+
1. **You review this RFC** and answer Q1–Q8 (or override any defaults).
|
|
286
|
+
2. I draft the **new `tokens.figma.json` structure** (just the JSON) for one more review pass.
|
|
287
|
+
3. Generator gets alias-resolution; regenerate `pre-built/*`.
|
|
288
|
+
4. Rewrite `components.css` to use semantic tokens.
|
|
289
|
+
5. Update docs + smoke test.
|
|
290
|
+
6. *(Optional)* update `components.html` demo markup to semantic — sizable HTML rewrite, lower priority than the rest.
|
|
291
|
+
|
|
292
|
+
Estimate: 1–2 days post-approval. Bottleneck is Q1–Q8 decisions.
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
**Next step for you:** read §4 and §6, mark up the questions or comment inline. After that I'll execute.
|