You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .trellis/spec/frontend/design-system.md
+42Lines changed: 42 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,6 +15,22 @@ Core principles already landed in code:
15
15
- motion durations centralized in tokens
16
16
- spotlight / ambient effects must degrade cleanly under `prefers-reduced-motion`
17
17
- shared button / badge / panel classes should be reused before adding new component-specific styling
18
+
- admin / control surfaces are **data-dense first**: clarity, trust, and readable form structure beat decorative flourish
19
+
20
+
### Product Fit: Admin / Gateway Console
21
+
22
+
For this project, external design research best matches a dark enterprise control surface:
23
+
24
+
- “enterprise gateway” / admin dashboard visual language
25
+
- conservative accent usage
26
+
- high-contrast dark mode
27
+
- technical typography for ids / model refs / machine-readable strings
28
+
29
+
This means new UI should feel like an operator console, not a marketing page:
30
+
31
+
- prefer calm, conservative surfaces over playful highlight colors
32
+
- reserve semantic colors for explicit status signals, not ordinary content labels
33
+
- treat forms and control panels as operational UI, not decorative cards
18
34
19
35
---
20
36
@@ -72,6 +88,14 @@ Use shared button classes for interaction states. Only add local styles for spac
72
88
-`.status-badge` and its tone variants are the default status capsule.
73
89
- Use semantic tones (`ok`, `warn`, `bad`, `accent`, `dynamic`) consistently across views.
74
90
-**Warning**: light theme keeps a broad base `.status-badge` restyle. Existing tones used by the app have dedicated overrides, but any newly introduced badge tone must add its own light-theme override instead of assuming the base badge style will preserve meaning.
91
+
- For admin/data chips (model ids, provider names, route labels), default to the neutral chip language first.
92
+
- Do **not** recolor normal text/chips to green/yellow/red just because the underlying item is “available”, “default”, or “selected”.
93
+
- If a state matters, expose it through:
94
+
- a nearby `.status-badge`
95
+
- helper copy
96
+
- explicit label text / icon
97
+
- layout grouping
98
+
rather than colorizing the content token itself.
75
99
76
100
### Spotlight-enabled cards
77
101
- Add `data-spotlight` to interactive elevated surfaces that should receive pointer-driven light.
@@ -80,6 +104,12 @@ Use shared button classes for interaction states. Only add local styles for spac
80
104
### Form / modal system
81
105
- Reuse the existing modal shell, field spacing, and focus behaviors.
82
106
- Inputs should inherit token-based backgrounds/borders and rely on the global `:focus-visible` outline instead of custom ad-hoc rings.
107
+
- In form-heavy admin modals, use **visible field labels** and helper text before inventing new control metaphors.
108
+
- One-off custom switches / glowing pills / chip-toggles should be avoided unless there is already a shared primitive in the repo.
109
+
- For policy-like choices (“enabled”, “default”, “allow”), prefer native checkbox / radio inputs with clear labels unless a shared existing control family is already established.
110
+
- Dense forms should be structured in two layers:
111
+
- field rows for raw values
112
+
- a separate options / policy row for toggles and secondary choices
83
113
84
114
---
85
115
@@ -110,6 +140,7 @@ When adding a new animation, wire it through the shared motion tokens or the sam
110
140
### Focus and keyboard
111
141
- Rely on the global `:focus-visible` outline (`public/styles.css:96-106`) unless a component has a stronger documented reason.
112
142
- Modal and drawer interactions must keep keyboard flow intact; visual polish must not break Tab / Escape behavior.
143
+
- Inputs, radios, and checkboxes in admin forms should remain obviously interactive in both themes without requiring hover to reveal affordance.
113
144
114
145
### Theme switching
115
146
- Dark mode is the baseline in `:root`.
@@ -119,6 +150,15 @@ When adding a new animation, wire it through the shared motion tokens or the sam
119
150
### Color independence
120
151
- Accent color is emphasis, not the only source of meaning.
121
152
- Pair state colors with iconography, label text, or placement when the state matters.
153
+
- If a user cannot distinguish green from neutral, or if the UI is viewed in grayscale, critical state should still be understandable.
154
+
155
+
### Admin Form Rules
156
+
157
+
- Placeholder text is an example, not the primary label.
158
+
- Technical inputs (model ids, provider keys, API endpoints, aliases) should keep labels visible at all times.
159
+
- Required-ness should be explicit when applicable.
160
+
- Submission feedback must have a visible loading / success / error state.
161
+
- Inline validation and field-local errors are preferred over a single generic error area at the top.
122
162
123
163
---
124
164
@@ -175,6 +215,8 @@ When adding a new animation, wire it through the shared motion tokens or the sam
Copy file name to clipboardExpand all lines: .trellis/spec/guides/code-reuse-thinking-guide.md
+23Lines changed: 23 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -97,6 +97,29 @@ When you've made similar changes to multiple files:
97
97
98
98
---
99
99
100
+
## Gotcha: Form State Exists in More Than One Helper Path
101
+
102
+
**Problem**: A UI feature adds a new state dimension (for example `allowlisted`, `isDefault`, selected filters, derived toggles), but only updates the obvious render/save path. Older helper paths such as:
103
+
104
+
-`render*()`
105
+
-`collect*()`
106
+
-`sync*FromForm()`
107
+
-`fill*FromJson()`
108
+
109
+
still operate on the old state shape.
110
+
111
+
**Symptom**:
112
+
- the UI looks correct while editing
113
+
- clicking save silently drops the new selection
114
+
- reopening the form shows the old value
115
+
116
+
**Prevention checklist**:
117
+
-[ ] When adding any new form state, search for *all* render / collect / sync / fill helpers for that surface
118
+
-[ ] If the form supports both raw JSON and structured controls, make JSON backfill explicit instead of automatic in submit helpers
119
+
-[ ] Search for every call site of the normalization helper, not only the helper definition itself
0 commit comments