trdr-ds-install 1.6.0 β 1.6.5
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/package.json
CHANGED
|
@@ -6,7 +6,7 @@ argument-hint: "[analyze|apply|foundation|violations|components|final|resume|sta
|
|
|
6
6
|
allowed-tools: [Read, Glob, Grep, Edit, Write, Bash, WebFetch]
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
**Skill version:** 1.6.
|
|
9
|
+
**Skill version:** 1.6.5
|
|
10
10
|
**npm package:** trdr-ds-install
|
|
11
11
|
|
|
12
12
|
You are implementing the **TRDR Design System** in a developer's project. The Design Hub is the single source of truth and lives at **https://trdr.mrocontent.com.br**.
|
|
@@ -53,13 +53,13 @@ Run this command silently via Bash:
|
|
|
53
53
|
npm show trdr-ds-install version 2>/dev/null
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
Compare the result with the **Skill version** constant at the top of this file (`1.6.
|
|
56
|
+
Compare the result with the **Skill version** constant at the top of this file (`1.6.5`).
|
|
57
57
|
|
|
58
58
|
- If the command fails or returns empty (no internet / npm unavailable): skip silently, continue.
|
|
59
59
|
- If registry version == local version: skip silently, continue.
|
|
60
60
|
- If registry version > local version:
|
|
61
61
|
```
|
|
62
|
-
π Nova versΓ£o da skill disponΓvel: trdr-ds-install@[registry-version] (instalada: 1.6.
|
|
62
|
+
π Nova versΓ£o da skill disponΓvel: trdr-ds-install@[registry-version] (instalada: 1.6.5)
|
|
63
63
|
|
|
64
64
|
Responda:
|
|
65
65
|
- `"atualizar"` / `"update"` β instalar a nova versΓ£o agora (requer reiniciar /trdr-ds apΓ³s)
|
|
@@ -114,6 +114,18 @@ Read `package.json` at the project root. Identify:
|
|
|
114
114
|
|
|
115
115
|
Save `stylingMode` β it must be referenced throughout Phase 2 wherever the output format differs by framework.
|
|
116
116
|
|
|
117
|
+
**Dual stylingMode β tailwind + styled-components simultaneously:**
|
|
118
|
+
If `package.json` contains BOTH `tailwindcss` AND `styled-components` (or `@emotion/*`):
|
|
119
|
+
- Set `stylingMode: 'tailwind'` (dominant β utility classes in className)
|
|
120
|
+
- Set `hasStyledComponents: true` to activate additional scan
|
|
121
|
+
- In Step 3, add a styled-components scan alongside the normal CSS scan:
|
|
122
|
+
- Pattern in `*.tsx, *.ts, *.jsx, *.js`: `` styled\.\w+`[^`]*(?:#[0-9A-Fa-f]{3,8}|font-family|rgba\()[^`]*` ``
|
|
123
|
+
- For each template literal matched: run A, B, F violation checks against its content (even though it's not a `.css` file)
|
|
124
|
+
- Fix: replace hardcoded values inside template literals with CSS var tokens:
|
|
125
|
+
`background: #00A8CC` β `background: var(--action-brand-default);`
|
|
126
|
+
`font-family: 'Inter'` β `font-family: var(--font-secondary);`
|
|
127
|
+
- Document in `CLAUDE.md` of the project: "This project uses styled-components AND Tailwind. New components: prefer Tailwind + DS classes. Existing styled-components: use DS tokens via CSS vars in template literals."
|
|
128
|
+
|
|
117
129
|
### Step 2 β Map style structure
|
|
118
130
|
|
|
119
131
|
Search for all style files:
|
|
@@ -133,6 +145,14 @@ Determine the best directory for new CSS files:
|
|
|
133
145
|
- React CRA/Vite with `src/`: β `src/styles/` or `src/assets/`
|
|
134
146
|
- Plain HTML: β `css/` or `styles/`
|
|
135
147
|
|
|
148
|
+
**For `tailwind` stylingMode β additional scan:**
|
|
149
|
+
Read `tailwind.config.js` (or `tailwind.config.ts`) and check `theme.colors` and `theme.extend.colors`:
|
|
150
|
+
- If any color value is a hardcoded `#hex` that matches a TRDR DS token, flag it
|
|
151
|
+
- Add `tailwind.config.js` to "FILES TO MODIFY" in the plan
|
|
152
|
+
- Fix during Sub-fase B: replace each `'#hex'` with `'var(--semantic-token)'`
|
|
153
|
+
- Example: `brand: '#00A8CC'` β `brand: 'var(--content-brand)'`
|
|
154
|
+
- This allows Tailwind classes like `text-brand` to use the DS token automatically
|
|
155
|
+
|
|
136
156
|
### Step 3 β Find violations
|
|
137
157
|
|
|
138
158
|
Search for TRDR rule violations across all source files (*.css, *.scss, *.tsx, *.jsx, *.ts, *.js, *.vue, *.html):
|
|
@@ -140,15 +160,30 @@ Search for TRDR rule violations across all source files (*.css, *.scss, *.tsx, *
|
|
|
140
160
|
**A β Hardcoded colors** (should be CSS vars):
|
|
141
161
|
Search pattern: `#[0-9A-Fa-f]{3,8}` in CSS/SCSS files; `#[0-9A-Fa-f]{3,8}` in component files within style props or className strings.
|
|
142
162
|
|
|
163
|
+
**Special case β SVG attribute colors** (`stroke=`, `fill=`, `stop-color=` in HTML/JSX/Vue):
|
|
164
|
+
When `#hex` is found inside an SVG attribute (not a CSS property), the fix is different β CSS variables do NOT work in SVG attributes. Instead:
|
|
165
|
+
- If the SVG is a simple icon with a single solid color β replace with `stroke="currentColor"` / `fill="currentColor"` and control color via a CSS class (e.g., `.icon-brand { color: var(--content-brand); }`)
|
|
166
|
+
- If the SVG has multiple distinct colors (multi-tone icon) β it should be replaced as a Category J violation (inline SVG β icon library)
|
|
167
|
+
- Do NOT write `stroke="var(--token)"` β it is invalid in HTML SVG attributes
|
|
168
|
+
|
|
169
|
+
Track SVG attribute color violations separately as **A\*** in DS_ANALYSIS.md with the note "SVG attribute β requires currentColor + CSS class approach, not var()."
|
|
170
|
+
|
|
143
171
|
**B β Hardcoded font-family** (should be var(--font-primary/secondary/mono)):
|
|
144
172
|
Search: `font-family.*Inter|font-family.*JetBrains Mono|font-family.*Space Grotesk|font-family.*Roboto Mono`
|
|
145
173
|
|
|
174
|
+
**Note β JSX camelCase:** In React/Next.js files, font-family appears as `fontFamily` inside `style={{}}` objects. These are NOT detected by Category B (which scans CSS). They are captured by Category I (inline styles with `font` keyword). Do NOT double-count them in Category B; address them in Category I fix instead.
|
|
175
|
+
|
|
146
176
|
**C β Hardcoded px spacing** (should be var(--spacing-*)):
|
|
147
177
|
Search: `(margin|padding|gap):\s*\d+px` in CSS/SCSS
|
|
148
178
|
|
|
149
179
|
**D β Primitive token usage** (should be semantic):
|
|
150
180
|
Search: `var\(--color-|var\(--space-` in CSS/SCSS/component files
|
|
151
181
|
|
|
182
|
+
Also search for **custom CSS variable definitions with primitive naming** in `:root {}` blocks:
|
|
183
|
+
- Pattern: `--color-[a-z]|--space-[0-9]|--font-size-[0-9]` inside `:root {`
|
|
184
|
+
- Flag as: "Custom CSS variable using primitive-style name: `--color-brand`. This duplicates DS token naming. Remove and replace all `var(--color-brand)` usages with the appropriate semantic token."
|
|
185
|
+
- Do NOT auto-remove β flag for manual review in DS_MIGRATION.md
|
|
186
|
+
|
|
152
187
|
**E β Missing tokens.css**:
|
|
153
188
|
Check if `tokens.css` already exists in the project and if it's imported in the global CSS.
|
|
154
189
|
|
|
@@ -159,10 +194,29 @@ Search: `rgba\(` in CSS/SCSS/HTML files (excluding node_modules, vendor)
|
|
|
159
194
|
Search: `linear-gradient|radial-gradient` in CSS/SCSS/HTML files
|
|
160
195
|
Flag any gradient that doesn't reference a TRDR gradient token (`var(--gradient-*)`)
|
|
161
196
|
|
|
197
|
+
**Gradients with hex stops:** Compare against TRDR gradient token approximate values:
|
|
198
|
+
- `--gradient-bg-hero` β `linear-gradient(180deg, #0E0E0E 0%, #141519 100%)`
|
|
199
|
+
- `--gradient-bg-surface` β `linear-gradient(180deg, #141519 0%, #0E0E0E 100%)`
|
|
200
|
+
- `--gradient-brand` β `linear-gradient(90deg, #00A8CC 0%, #00D4FF 100%)`
|
|
201
|
+
If a gradient closely matches one of these: replace with `var(--gradient-name)`.
|
|
202
|
+
If no match: flag in DS_MIGRATION.md as "Custom gradient β no DS token available."
|
|
203
|
+
Non-DS colors in gradient stops (e.g. `#0a1520`) are also A violations β flag separately.
|
|
204
|
+
|
|
205
|
+
**Gradients with rgba stops:** When gradient stops use `rgba()` instead of hex:
|
|
206
|
+
1. Extract the base color from each rgba stop and identify it in the TRDR color mapping table.
|
|
207
|
+
2. If the base color has a DS token: recommend `rgba(var(--token-rgb), opacity)` if the DS exposes RGB variables, otherwise flag in DS_MIGRATION.md.
|
|
208
|
+
3. **Fade-to-transparent** pattern (e.g. `rgba(0,212,255,0.04) 0%, transparent 100%`):
|
|
209
|
+
- This is a glow/haze effect. Very unlikely to have a DS token.
|
|
210
|
+
- Flag as: "Glow effect gradient β no DS token. Consider converting to `box-shadow: 0 0 Xpx var(--token)` or remove if purely decorative."
|
|
211
|
+
4. **Overlay gradient** (e.g. `rgba(255,204,64,0.1) 0%, rgba(255,204,64,0.05) 100%`):
|
|
212
|
+
- Flag as: "Tinted overlay gradient β no DS equivalent. Map rgba base color to token; keep gradient as-is or convert to a solid rgba with semantic token."
|
|
213
|
+
|
|
162
214
|
**H β Hardcoded font-size in px** (should use .trdr-h* / .trdr-body-* text style classes):
|
|
163
215
|
Search: `font-size:\s*\d+px` in CSS/SCSS files (skip tokens.css itself)
|
|
164
216
|
|
|
165
217
|
**I β Inline styles with design properties** (should be CSS classes with tokens):
|
|
218
|
+
|
|
219
|
+
**I.1 β JSX/HTML style attribute** (standard inline styles):
|
|
166
220
|
Search in `*.html, *.tsx, *.jsx, *.vue, *.svelte`:
|
|
167
221
|
- HTML/Vue: `style="[^"]*(?:color|background|font|padding|margin|gap|border)[^"]*"`
|
|
168
222
|
- React/JSX: `style=\{\{[^}]*(?:color|background|font|padding|margin|gap|border)[^}]*\}\}`
|
|
@@ -173,20 +227,85 @@ Do NOT flag (these are acceptable exceptions):
|
|
|
173
227
|
- `style="--custom-prop: value"` β CSS custom property passing a dynamic value to CSS (e.g. `style="--card-delay:0.1s"`)
|
|
174
228
|
- `style={{ '--custom-prop': value }}` β same in JSX
|
|
175
229
|
|
|
230
|
+
**I.2 β Dynamic DOM style assignment** (imperative JS manipulation, NOT covered by I.1):
|
|
231
|
+
Search in `*.tsx, *.jsx, *.js, *.ts`:
|
|
232
|
+
- Pattern: `\.style\.[a-zA-Z]+\s*=\s*['"]`
|
|
233
|
+
- Example: `e.currentTarget.style.background = 'rgba(255,255,255,0.03)'`
|
|
234
|
+
- Example: `ref.current.style.color = '#00D4FF'`
|
|
235
|
+
|
|
236
|
+
This pattern is common in hover handlers (`onMouseEnter/onMouseLeave`) and imperative animations. The assigned value is a hardcoded design value that must be replaced.
|
|
237
|
+
|
|
238
|
+
**I.2 fix procedure:**
|
|
239
|
+
|
|
240
|
+
*CASE 1 β onMouseEnter/onMouseLeave hover effect:*
|
|
241
|
+
This is the most common case. Convert to a CSS `:hover` rule:
|
|
242
|
+
```css
|
|
243
|
+
/* Before: onMouseEnter sets background imperatively */
|
|
244
|
+
.item { transition: background 0.15s; }
|
|
245
|
+
.item:hover { background: var(--surface-hover); }
|
|
246
|
+
```
|
|
247
|
+
Remove the `onMouseEnter` and `onMouseLeave` handlers. Add `className="item"` to the element.
|
|
248
|
+
|
|
249
|
+
*CASE 2 β State-driven imperative style (non-hover):*
|
|
250
|
+
If the DOM assignment is driven by JS logic beyond simple hover, replace the hardcoded value only:
|
|
251
|
+
```tsx
|
|
252
|
+
// Before
|
|
253
|
+
el.style.background = 'rgba(255,255,255,0.03)';
|
|
254
|
+
// After
|
|
255
|
+
el.style.background = 'var(--surface-hover)';
|
|
256
|
+
```
|
|
257
|
+
Document in DS_PROGRESS.md as "I.2 fix β dynamic style value replaced with token."
|
|
258
|
+
|
|
259
|
+
PRIORITY: Always prefer CASE 1 (CSS pseudo-class) β it's more performant and idiomatic than CASE 2.
|
|
260
|
+
|
|
176
261
|
**J β SVG icons inline** (should use an icon library):
|
|
177
262
|
Search in `*.html, *.tsx, *.jsx, *.vue`:
|
|
178
263
|
- Pattern: `<svg` in source files (NOT in logo files, NOT in `node_modules/`, `references/`, `assets/icons/`)
|
|
179
264
|
- Do NOT flag: `<svg` in known logo files (those with the official TRDR fingerprint)
|
|
180
265
|
- Count distinct files with inline SVGs, not total occurrences
|
|
181
266
|
|
|
267
|
+
**Severity sub-classification:**
|
|
268
|
+
- **J.high**: `<svg>` with hardcoded `stroke="#hex"` or `fill="#hex"` β both a J and A* violation; replace with icon library ASAP
|
|
269
|
+
- **J.medium**: `<svg>` with dynamic JSX fill/stroke expression (e.g. `fill={isActive ? 'currentColor' : 'none'}`) β no hex hardcoded, but state-driven SVG attribute that must be preserved during migration; replace with icon library using conditional CSS class
|
|
270
|
+
- **J.low**: `<svg>` using ONLY `currentColor` / `inherit` (no hardcoded colors) β still prefer icon library, but lower priority; note in plan: "SVG uses currentColor (color is CSS-controlled). Migration to Material Icons recommended but non-urgent."
|
|
271
|
+
|
|
272
|
+
**J.medium fix procedure β dynamic SVG attributes:**
|
|
273
|
+
When an SVG has `fill={condition ? 'currentColor' : 'none'}` or `stroke={value}` (JSX expression):
|
|
274
|
+
1. Identify the two visual states (filled/outlined, active/inactive)
|
|
275
|
+
2. Create CSS classes for each state:
|
|
276
|
+
```css
|
|
277
|
+
.icon-star { color: var(--content-tertiary); }
|
|
278
|
+
.icon-star.active { color: var(--context-trading-signal); }
|
|
279
|
+
```
|
|
280
|
+
3. Replace the SVG with a Material Icon (or equivalent DS icon) using a conditional className:
|
|
281
|
+
```tsx
|
|
282
|
+
<span className={`material-icons icon-star ${isWatching ? 'active' : ''}`}>star</span>
|
|
283
|
+
```
|
|
284
|
+
4. The `fill`/`stroke` logic is handled entirely by CSS β never pass state to icon attributes.
|
|
285
|
+
|
|
182
286
|
**K β Logo missing or incorrect in HTML/JSX** (should use official logo-trdr.svg):
|
|
183
|
-
Search in `*.html, *.tsx, *.jsx, *.vue
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
- `
|
|
287
|
+
Search in `*.html, *.tsx, *.jsx, *.vue` using **two separate Grep calls** (the combined pattern is unreliable in ripgrep):
|
|
288
|
+
|
|
289
|
+
Call 1 β Non-official img logo (HTML):
|
|
290
|
+
- Pattern: `src="[^"]*logo(?!-trdr)[^"]*"` β img/Image with logo in the src value itself (covers JSX where src is first attribute)
|
|
291
|
+
- Secondary: `<img[^>]*(?:logo|brand|mark)[^>]*src="(?!.*logo-trdr)[^"]*"` β catches cases where logo/brand/mark appears in alt= or class= before src=
|
|
292
|
+
|
|
293
|
+
Call 1b β Next.js `<Image>` component (Next.js projects only):
|
|
294
|
+
- Pattern: `<Image[^>]*src="[^"]*logo(?!-trdr)[^"]*"` β next/image component with non-official logo
|
|
295
|
+
- Also flag `<Image[^>]*src=\{[^}]*logo(?!Trdr)[^}]*\}` for dynamic src with variable name not matching logoTrdr
|
|
296
|
+
|
|
297
|
+
Call 2 β Text span as logo (use this pattern, NOT the combined version):
|
|
298
|
+
- Pattern: `>\s*TRDR\s*<` β finds any element with text content "TRDR"
|
|
299
|
+
- Then check if the surrounding element is `<span>` or `<div>` (not `<img alt="TRDR">`)
|
|
300
|
+
- Simpler alternative: `class="[^"]*logo[^"]*"` + check if no `<img` tag on the same line
|
|
301
|
+
|
|
302
|
+
Call 3 β Wrong logo import:
|
|
303
|
+
- Pattern: `import\s+\w+\s+from\s+['"][^'"]*logo(?!-trdr)[^'"]*['"]` β logo import that isn't logo-trdr
|
|
187
304
|
|
|
188
305
|
Do NOT flag: `logo-trdr.svg` references β those are correct.
|
|
189
306
|
|
|
307
|
+
**Note:** The pattern `<span[^>]*>[^<]*TRDR[^<]*</span>` is known to fail in ripgrep β do NOT use it.
|
|
308
|
+
|
|
190
309
|
Track:
|
|
191
310
|
- `total_violations` = sum of all AβH occurrences
|
|
192
311
|
- `total_files_with_violations` = count of unique files with β₯ 1 violation
|
|
@@ -829,10 +948,12 @@ For each batch listed as PENDING in `DS_PROGRESS.md` Β§ Sub-fase B:
|
|
|
829
948
|
**Font mapping:**
|
|
830
949
|
| Hardcoded | Replace with |
|
|
831
950
|
|-----------|-------------|
|
|
832
|
-
| `font-family: 'Inter'` | `font-family: var(--font-secondary)` |
|
|
833
|
-
| `font-family: 'JetBrains Mono'` | `font-family: var(--font-primary)` |
|
|
951
|
+
| `font-family: 'Inter'` or `font-family: 'Inter', -apple-system, ...` | `font-family: var(--font-secondary)` |
|
|
952
|
+
| `font-family: 'JetBrains Mono'` or `font-family: 'JetBrains Mono', monospace` | `font-family: var(--font-primary)` |
|
|
834
953
|
| `font-family: 'Space Grotesk'` | `font-family: var(--font-primary)` |
|
|
835
|
-
| `font-family: 'Roboto Mono'` | `font-family: var(--font-mono)` |
|
|
954
|
+
| `font-family: 'Roboto Mono'` or `font-family: 'Roboto Mono', monospace` | `font-family: var(--font-mono)` |
|
|
955
|
+
|
|
956
|
+
**Note:** System font fallbacks (`-apple-system`, `BlinkMacSystemFont`, `sans-serif`) are removed when replacing with a DS token. The token's value in tokens.css already defines the complete font stack including fallbacks β no manual fallback needed.
|
|
836
957
|
|
|
837
958
|
**Spacing mapping:**
|
|
838
959
|
| Hardcoded | Replace with |
|
|
@@ -844,26 +965,102 @@ For each batch listed as PENDING in `DS_PROGRESS.md` Β§ Sub-fase B:
|
|
|
844
965
|
| `20px` | `var(--spacing-xl)` |
|
|
845
966
|
| `24px` | `var(--spacing-2xl)` |
|
|
846
967
|
| `32px` | `var(--spacing-3xl)` |
|
|
968
|
+
| `0` / `0px` | Keep as `0` (no token needed) |
|
|
969
|
+
| Any other value (48px, 64px, 96px, etc.) | **Keep the value as-is** β no DS token exists for it. Flag in DS_MIGRATION.md as "Custom spacing value: [Npx] in [file:line] β consider refactoring or proposing a new token in the Hub." Do NOT invent a `--spacing-4xl` or similar that doesn't exist in tokens.css. |
|
|
970
|
+
|
|
971
|
+
**Multi-value spacing shorthands** (`padding: 16px 32px`, `margin: 12px 0 8px`):
|
|
972
|
+
- Replace each value independently using the mapping above
|
|
973
|
+
- Example: `padding: 16px 32px` β `padding: var(--spacing-lg) var(--spacing-3xl)`
|
|
974
|
+
- Example: `margin: 12px 0 8px` β `margin: var(--spacing-md) 0 var(--spacing-sm)`
|
|
975
|
+
- If one value has no token: replace only the mappable ones; keep the others as-is and flag
|
|
976
|
+
|
|
977
|
+
**Ambiguous colors:** Use property context to decide β `background-color` β bg/surface token, `color` β content token, `border-color` β border token, `accent-color` β action token.
|
|
978
|
+
|
|
979
|
+
**Tailwind arbitrary value colors** (only when `stylingMode: tailwind`):
|
|
980
|
+
|
|
981
|
+
Detect in `*.tsx, *.jsx, *.html, *.vue`:
|
|
982
|
+
- Pattern: `(?:bg|text|border|ring|from|to|via|outline|fill|stroke)-\[#[0-9A-Fa-f]{3,8}\]`
|
|
983
|
+
- Also detect `hover:`, `focus:`, `active:`, `dark:` prefixed variants
|
|
984
|
+
|
|
985
|
+
Fix strategy β apply in order of preference:
|
|
847
986
|
|
|
848
|
-
**
|
|
987
|
+
1. **DS class exists for element role β OpΓ§Γ£o A (DS class):**
|
|
988
|
+
Replace the arbitrary Tailwind classes with the DS class, keeping non-color utilities:
|
|
989
|
+
```jsx
|
|
990
|
+
// Before
|
|
991
|
+
className="bg-[#005266] text-white px-4 py-2 rounded cursor-pointer"
|
|
992
|
+
// After
|
|
993
|
+
className="trdr-btn trdr-btn-primary px-4 rounded"
|
|
994
|
+
```
|
|
995
|
+
|
|
996
|
+
2. **No DS class, but color maps to DS token β OpΓ§Γ£o B (CSS var arbitrary):**
|
|
997
|
+
```jsx
|
|
998
|
+
// Before
|
|
999
|
+
className="bg-[#1A1A1A] border border-[#222222]"
|
|
1000
|
+
// After
|
|
1001
|
+
className="bg-[var(--bg-tertiary)] border border-[var(--border-subtle)]"
|
|
1002
|
+
```
|
|
1003
|
+
Token mapping (use same color β semantic table as CSS):
|
|
1004
|
+
- `bg-[#0E0E0E]` β `bg-[var(--bg-primary)]`
|
|
1005
|
+
- `bg-[#141519]` β `bg-[var(--bg-secondary)]`
|
|
1006
|
+
- `bg-[#1A1A1A]` β `bg-[var(--bg-tertiary)]`
|
|
1007
|
+
- `text-[#FFFFFF]` β `text-[var(--content-primary)]`
|
|
1008
|
+
- `text-[#A4A4A4]` β `text-[var(--content-tertiary)]`
|
|
1009
|
+
- `border-[#222222]` β `border-[var(--border-subtle)]`
|
|
1010
|
+
- `border-[#4A4A4A]` β `border-[var(--border-default)]`
|
|
1011
|
+
- `focus:border-[#00D4FF]` β `focus:border-[var(--border-focus)]`
|
|
1012
|
+
- `text-[#4FE290]` β `text-[var(--context-trading-up)]`
|
|
1013
|
+
- `text-[#F34F45]` β `text-[var(--context-trading-down)]`
|
|
1014
|
+
|
|
1015
|
+
3. **Color has no DS token (e.g. `hover:bg-[#3DD980]`, `hover:bg-[#E03D3A]`):**
|
|
1016
|
+
- Flag in DS_MIGRATION.md: "Custom hover color `#hex` β no DS token equivalent"
|
|
1017
|
+
- Suggestion: replace with CSS hover effect: `hover:[filter:brightness(1.15)]` or use a utility class
|
|
1018
|
+
- Do NOT invent a token or leave the hardcoded color silently
|
|
1019
|
+
|
|
1020
|
+
**`accent-color` property:** Controls native checkbox/radio/range styling.
|
|
1021
|
+
- `accent-color: #00A8CC` β `accent-color: var(--action-brand-default)`
|
|
1022
|
+
- `accent-color: #4FE290` β `accent-color: var(--content-success)`
|
|
849
1023
|
|
|
850
1024
|
**rgba() mapping:**
|
|
851
1025
|
| Hardcoded pattern | Context | Replace with |
|
|
852
1026
|
|-------------------|---------|-------------|
|
|
853
1027
|
| `rgba(0,0,0,*)` | box-shadow | No TRDR shadow token exists β flag in DS_PROGRESS.md / DS_MIGRATION.md as "Missing shadow token" |
|
|
1028
|
+
| `rgba(255,255,255,0.03β0.08)` | border / subtle divider | `var(--border-subtle)` if token exists, otherwise flag |
|
|
1029
|
+
| `rgba(255,255,255,0.10β0.20)` | hover/hover overlay | `var(--surface-hover)` if token exists, otherwise flag |
|
|
854
1030
|
| `rgba(255,255,255,.29)` approx | overlay/backdrop | `var(--bg-overlay)` |
|
|
855
1031
|
| `rgba(255,255,255,*)` other | overlay | flag |
|
|
1032
|
+
| `rgba(0,212,255,*)` | focus glow/shadow | No alpha token exists for `--border-focus` β flag as "Missing focus-alpha token" |
|
|
1033
|
+
| `rgba(0,168,204,*)` | brand alpha bg | Use `var(--surface-brand)` if available, otherwise flag |
|
|
1034
|
+
| `rgba(79,226,144,*)` | success alpha bg | Use `var(--surface-success)` if available, otherwise flag |
|
|
1035
|
+
| `rgba(243,79,69,*)` | error alpha bg | Use `var(--surface-error)` if available, otherwise flag |
|
|
1036
|
+
| `rgba(255,204,64,*)` | warning alpha bg | Use `var(--surface-warning)` if available, otherwise flag |
|
|
856
1037
|
| Any other `rgba(N,N,N,*)` | various | Map to nearest semantic alpha token (--surface-brand, --surface-info, --action-*-alpha, etc.) or flag |
|
|
857
1038
|
|
|
858
1039
|
**Gradient mapping:**
|
|
1040
|
+
|
|
1041
|
+
Known TRDR gradient token values (use to match):
|
|
1042
|
+
| Token | Approximate value |
|
|
1043
|
+
|-------|------------------|
|
|
1044
|
+
| `--gradient-text-brand` | `linear-gradient(90deg, var(--content-brand), var(--border-focus))` β cyan to bright-cyan, horizontal |
|
|
1045
|
+
| `--gradient-bg-hero` | `linear-gradient(180deg, var(--bg-secondary), var(--bg-primary))` β dark vertical fade |
|
|
1046
|
+
| `--gradient-bg-fade` | `linear-gradient(180deg, var(--bg-tertiary) 0%, transparent 100%)` β surface to transparent |
|
|
1047
|
+
|
|
859
1048
|
| Pattern | Replace with |
|
|
860
1049
|
|---------|-------------|
|
|
861
|
-
|
|
|
1050
|
+
| Gradient whose colors map to `--content-brand` + `--border-focus` (horizontal) | `var(--gradient-text-brand)` |
|
|
1051
|
+
| Gradient whose colors map to `--bg-secondary` β `--bg-primary` (vertical fade) | `var(--gradient-bg-hero)` |
|
|
1052
|
+
| Gradient whose colors map to `--bg-tertiary` β transparent | `var(--gradient-bg-fade)` |
|
|
1053
|
+
| Gradient using only TRDR bg colors but not matching any token above | Flag β add comment `/* gradient-bg-custom: consider adding to Hub */` |
|
|
862
1054
|
| `linear-gradient(...)` using any non-DS colors | Flag β developer must decide: remove, replace with TRDR gradient token, or add new token to Hub |
|
|
863
1055
|
| Gradient inside SVG data URI embedded in CSS | Flag |
|
|
864
1056
|
|
|
865
1057
|
**Font-size mapping (bidirectional β CSS + HTML/JSX/Vue):**
|
|
866
1058
|
|
|
1059
|
+
**Exception for global selectors:** If `font-size: Npx` is inside a `body {}`, `html {}`, `:root {}`, or `* {}` rule:
|
|
1060
|
+
- **Remove the `font-size` property entirely** β do NOT add a DS class to the element
|
|
1061
|
+
- Document in DS_MIGRATION.md: "Global font-size reset removed β TRDR DS typography classes manage sizes per-element"
|
|
1062
|
+
- Do NOT apply DS text class to `<body>` or `<html>` tags
|
|
1063
|
+
|
|
867
1064
|
When a CSS class has a `font-size` that maps to a DS text style, the fix is **two-part**:
|
|
868
1065
|
|
|
869
1066
|
**Part 1 β In the CSS file**: remove the properties already provided by the DS class:
|
|
@@ -879,6 +1076,12 @@ When a CSS class has a `font-size` that maps to a DS text style, the fix is **tw
|
|
|
879
1076
|
| Vue | `<h1 class="hero-title trdr-h2">` or `:class="['hero-title', 'trdr-h2']"` |
|
|
880
1077
|
| `css-modules` | Add `composes: trdr-h2 from global;` inside `.hero-title` in the `.module.css` |
|
|
881
1078
|
|
|
1079
|
+
**CSS Modules local composition:** If a class uses `composes: AnotherClass` (without `from global`), it inherits styles from that class within the same file. When fixing:
|
|
1080
|
+
- Add `composes: trdr-X from global` to the **base class** (AnotherClass)
|
|
1081
|
+
- Do NOT add `composes: trdr-X from global` to the **inheriting class** β it inherits the token transitively
|
|
1082
|
+
- Example: `.select { composes: input; }` β add `composes: trdr-text-input from global` only to `.input`, not to `.select`
|
|
1083
|
+
- Adding `composes: trdr-X from global` to both would apply DS styles twice, causing doubled specificity
|
|
1084
|
+
|
|
882
1085
|
**font-size β DS class table:**
|
|
883
1086
|
| font-size | DS Class | Notes |
|
|
884
1087
|
|-----------|----------|-------|
|
|
@@ -1214,6 +1417,35 @@ Vue:
|
|
|
1214
1417
|
<!-- Keep :style only if the value is truly dynamic (changes at runtime based on data) -->
|
|
1215
1418
|
```
|
|
1216
1419
|
|
|
1420
|
+
**Conditional / ternary values in `style={{}}`** (common in React):
|
|
1421
|
+
When a style value is a ternary expression or computed value:
|
|
1422
|
+
```jsx
|
|
1423
|
+
// Before β conditional style object
|
|
1424
|
+
style={{
|
|
1425
|
+
background: isActive ? '#4A4A4A' : 'transparent',
|
|
1426
|
+
color: isActive ? '#FFFFFF' : '#A4A4A4',
|
|
1427
|
+
}}
|
|
1428
|
+
// After β state classes
|
|
1429
|
+
className={isActive ? 'tab-active' : 'tab-inactive'}
|
|
1430
|
+
// + CSS:
|
|
1431
|
+
// .tab-active { background: var(--surface-primary); color: var(--content-primary); }
|
|
1432
|
+
// .tab-inactive { background: transparent; color: var(--content-tertiary); }
|
|
1433
|
+
```
|
|
1434
|
+
Steps:
|
|
1435
|
+
1. Identify the boolean condition controlling the state
|
|
1436
|
+
2. Create two CSS classes (active/inactive) with semantic token values
|
|
1437
|
+
3. Replace `style={{...}}` with `className={condition ? 'active-class' : 'inactive-class'}`
|
|
1438
|
+
4. Keep all business logic intact β only change how styles are applied
|
|
1439
|
+
5. Document in DS_PROGRESS.md: "Ternary style at [file:line] converted to state classes"
|
|
1440
|
+
|
|
1441
|
+
**Special: trading up/down ternary** β when the two values are `#4FE290`/`#F34F45` (or any trading up/down pair):
|
|
1442
|
+
```css
|
|
1443
|
+
/* Use context.trading tokens, NOT content.success/error */
|
|
1444
|
+
.price-up { color: var(--context-trading-up); }
|
|
1445
|
+
.price-down { color: var(--context-trading-down); }
|
|
1446
|
+
/* WRONG: .price-up { color: var(--content-success); } β success is for non-trading contexts */
|
|
1447
|
+
```
|
|
1448
|
+
|
|
1217
1449
|
**Add new utility classes to the project's main CSS** (not to components.css or tokens.css β those are skill-managed):
|
|
1218
1450
|
Group new classes in a clearly labelled block at the bottom of the project's CSS, e.g.:
|
|
1219
1451
|
```css
|