@trading-game/design-intelligence-layer 0.9.0 → 0.9.2

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,325 @@
1
+ # trading.game — Brand voice
2
+
3
+ **Version:** 2.0 · April 2026
4
+ **Adds:** Channel-specific voice application per persona mode; anti-AI writing rules for all copy
5
+
6
+ ---
7
+
8
+ ## What this document is for
9
+
10
+ The content style guide covers *what* to write. The personas doc covers *who* you're writing for. The field guide covers what's running in their head when they read it.
11
+
12
+ This document covers the gap between those three: *how the voice changes by channel and by the mode the player is in when they get there*.
13
+
14
+ Read the field guide before writing anything player-facing. These personas aren't audience segments; they're states. The same person is an Edge Seeker at 9am, a System Runner by lunchtime, and a Public Predictor the moment they go on a streak. Copy that lands across all three in one sentence is the goal.
15
+
16
+ ---
17
+
18
+ ## The one thing we're selling
19
+
20
+ Not games. Not a platform. Not a crypto product with a trading UI.
21
+
22
+ The read.
23
+
24
+ Specifically: the moment you call what a market does next, and you're right. The line moves. The number hits. You say *I called it.* That sentence belongs to us. No other product gives people a fast, clean, verifiable reason to say it. Polymarket is too slow. CFD platforms are too opaque. Casinos don't let you call anything — they just spin. trading.game resolves in five ticks. That's the whole pitch.
25
+
26
+ Every headline, button, bust state and push notification either reinforces *I called it* or takes it away. There's no neutral option.
27
+
28
+ ---
29
+
30
+ ## Voice in one sentence
31
+
32
+ Sound like the sharpest person in the room who actually plays the games and doesn't need you to be impressed by either.
33
+
34
+ ---
35
+
36
+ ## The four brand traits
37
+
38
+ These come from the content style guide. They're reproduced here so you don't have to switch between docs.
39
+
40
+ **Instant.** No warm-up. No preamble. Get to the point before the player blinks.
41
+
42
+ **Alive.** The game has a pulse. Copy responds to what just happened; it never reads like something you could have written last Tuesday.
43
+
44
+ **Fearless.** No disclaimers in the player's face. No hedging. When something needs to be said, say it clearly.
45
+
46
+ **For everyone.** The language is never gatekeepy. No jargon without context. A first-time player and someone who's watched charts for five years should both feel like this was built for them.
47
+
48
+ ---
49
+
50
+ ## The three modes — and what to lead with
51
+
52
+ The player field guide calls these Edge Seeker, System Runner, and Public Predictor. The personas doc calls them the Self-Taught Analyst, the Session Tracker, and the Documented Better. Same three people; the field guide is describing what mode they're *in* when they read your copy.
53
+
54
+ Here's the shorthand for writing:
55
+
56
+ **Edge Seeker mode:** They came in with a thesis. Lead with the read, not the platform. The win copy should confirm their judgement. The bust copy should name the market, not the mistake. Never say "your selection was incorrect."
57
+
58
+ **System Runner mode:** They have rules. The rules are probably wrong. It doesn't matter; the system is the thing that keeps them coming back. Loss copy needs to give the bust a shape, not just a result. Session stats are more compelling to this person than any multiplier graphic. Clean withdrawals are not a feature; they're a minimum bar.
59
+
60
+ **Public Predictor mode:** They post wins within minutes of calling them. The result screen is a content piece they'll screenshot. Every win state needs: the mechanic, the USDT figure, the streak or record context. If it's generic, it won't get shared. The UI is a distribution channel for their audience.
61
+
62
+ ---
63
+
64
+ ## Copy that works across all three modes
65
+
66
+ Some copy has to serve the player regardless of which mode they're in when they read it. Bust copy is the best example. Here's the principle from the field guide:
67
+
68
+ > *"One sentence. Three self-images intact. Player goes again."*
69
+
70
+ Test any bust state against all three modes. "Bust. Market barely moved. Tight range." does this:
71
+ - Gives the Edge Seeker an external explanation (the market, not their read)
72
+ - Gives the System Runner information to work with (the setup was fine; the range was wrong)
73
+ - Gives the Public Predictor a way to post the loss without looking bad ("setup was right, vol just wasn't there")
74
+
75
+ Compare that to "Your selection was incorrect." That sentence destroys all three frames simultaneously.
76
+
77
+ ---
78
+
79
+ ## The near-miss — write it specifically
80
+
81
+ When the price lands one tick short of the target, the brain doesn't register a clean loss. It registers *I was right and the resolution was slightly off.* This is neurologically distinct from a normal bust, and it's more motivating than a win; the tension stays alive.
82
+
83
+ Near-miss copy should never say the player was wrong. They nearly weren't.
84
+
85
+ | ✅ | ❌ |
86
+ |---|---|
87
+ | "One tick short. The read was right." | "You missed. Try again." |
88
+ | "55.49. You had 55.50. Next one." | "Incorrect selection." |
89
+ | "Close. Vol reversed at the last second." | "Better luck next time." |
90
+
91
+ ---
92
+
93
+ ## Channel application by mode
94
+
95
+ In-game copy is covered in the style guide. What follows is everything else: social, email, community, announcements.
96
+
97
+ ---
98
+
99
+ ### X (Twitter/X)
100
+
101
+ One idea per post. Hook on the first line. Cut early.
102
+
103
+ The tone is not the same for all three modes. Edge Seekers respond to validation of attention and analysis. System Runners respond to data and provably fair mechanics. Public Predictors respond to things worth posting themselves.
104
+
105
+ **Writing for Edge Seekers on X:**
106
+ Give them something to be early on. Frame the product as a read, not a game.
107
+
108
+ > "Vol 100 has been oscillating inside a 12-point range for three sessions.
109
+ > Rise & Fall is pricing that in. If you've been watching it, now's the time."
110
+
111
+ > "The fastest feedback loop on a market read.
112
+ > Five ticks. Real price data. No waiting for a daily close."
113
+
114
+ **Writing for System Runners on X:**
115
+ State the mechanics plainly. They'll run their own analysis.
116
+
117
+ > "House edge: 2%. Fixed. Not variable, not hidden in a spread.
118
+ > Black-Scholes CDF pricing. Payout shown before you commit."
119
+
120
+ > "Session stats live after every trade.
121
+ > Win rate. Net USDT. Number of trades. That's the data your system runs on."
122
+
123
+ **Writing for Public Predictors on X:**
124
+ Give them something they'd say. Or something that makes trading.game look good to their followers.
125
+
126
+ > "7-tick streak on Vol 75.
127
+ > Some people screenshot the win. Some people post the chart."
128
+
129
+ > "Found this platform three weeks ago. Already at 14-7 on calls.
130
+ > If you want the breakdown, the result screen has everything."
131
+
132
+ **Formatting rules for X:**
133
+ One emoji at most, only if it earns its place. One hashtag maximum, only if it's genuinely relevant. Sentence case always. No triple punctuation. No ALL CAPS.
134
+
135
+ ---
136
+
137
+ ### LinkedIn
138
+
139
+ More room, more considered. The same voice; more weight on the intellectual frame. Lead with a genuine insight or a contrarian point, not a product update dressed as thought leadership.
140
+
141
+ **Good:**
142
+ > "Most trading education teaches theory.
143
+ > trading.game teaches decision-making under uncertainty, in five-second intervals, against a live price feed.
144
+ > Knowing the right move and making it under pressure are different skills. Most platforms only train one of them."
145
+
146
+ > "Prediction markets beat every major poll in the 2024 US election.
147
+ > The edge wasn't smarter models. It was faster feedback loops. People who were wrong found out sooner, adjusted, and were less wrong next time.
148
+ > That's the whole product we built."
149
+
150
+ **Bad:**
151
+ > "We're excited to share that trading.game has launched exciting new features! Our innovative platform is disrupting the traditional trading education space with cutting-edge gamification technology..."
152
+
153
+ One structural rule for LinkedIn: never open with "We're pleased / thrilled / excited to announce." Start with the announcement. If it's good, the announcement earns the excitement. If you have to label your own news as exciting, it probably isn't.
154
+
155
+ ---
156
+
157
+ ### Email
158
+
159
+ Subject line: short, specific, creates a small tension.
160
+ Body: one thing. Then the action.
161
+
162
+ Subject lines that work are different by mode:
163
+
164
+ **Edge Seeker:**
165
+ - "Your read on V_100 paid out."
166
+ - "Rise & Fall is running on Vol 200. Your call."
167
+ - "The chart moved where you said it would."
168
+
169
+ **System Runner:**
170
+ - "Your session stats: 7 trades, 4 wins."
171
+ - "Withdrawal processed. 90 seconds."
172
+ - "Your system is up 3 this week."
173
+
174
+ **Public Predictor:**
175
+ - "Streak: 7. Post it."
176
+ - "You were early on that Vol 75 move."
177
+ - "Your all-time record is now 47–29."
178
+
179
+ **Subject lines that don't work for anyone:**
180
+ - "Exciting updates from trading.game!"
181
+ - "Don't miss out on these amazing new features"
182
+ - "A message from our team 🙏"
183
+
184
+ **Good email opening (Edge Seeker):**
185
+ > "You called the Vol 75 level three days ago.
186
+ > It hit today. Your trade settled 1.96x.
187
+ > That's what attention looks like."
188
+
189
+ **Good email opening (System Runner):**
190
+ > "Six sessions in: 4 wins, 2 losses, net +340 USDT.
191
+ > That's above the 50% baseline by enough to matter.
192
+ > Your stats are in the app."
193
+
194
+ **Good email opening (Public Predictor):**
195
+ > "You hit a 7-game streak yesterday.
196
+ > The result screen's been designed so that screenshot is worth posting. Have a look at it."
197
+
198
+ **Bad email opening (for anyone):**
199
+ > "Hi [First Name]! We hope you're having a wonderful day! We're reaching out with some exciting news about our platform that we think you'll love..."
200
+
201
+ ---
202
+
203
+ ### Community (Discord / Telegram)
204
+
205
+ Same voice; slightly more relaxed. Not a different person. The biggest mistake community managers make is treating Discord as "informal" and drifting into hype language that doesn't fit the brand.
206
+
207
+ What works: talking to the mode the community is in. If there's a hot streak in the channel, the System Runner framing works well. After a rough patch, the Edge Seeker loss framing preserves the most self-images.
208
+
209
+ **Good:**
210
+ > "Vol 100 has been spiking since the open. If you've been watching it, now you know."
211
+
212
+ > "Clean withdrawal just confirmed for two people in the thread. USDT, 90 seconds."
213
+
214
+ > "7-game streak in the channel this morning. Two of you got screenshots worth posting."
215
+
216
+ **Bad:**
217
+ > "WAGMI fam 🚀🚀🚀 who's been crushing it today??"
218
+
219
+ > "Don't forget — trading season is HERE and gains are waiting for you bestie!! 💸💸"
220
+
221
+ The rule: write Discord messages the same way you'd write an X post, then relax the formality by about 10%. Not 50%.
222
+
223
+ ---
224
+
225
+ ### Announcements and product updates
226
+
227
+ State the thing. Then the implication for the player. Don't lead with your feelings about the announcement.
228
+
229
+ | ✅ | ❌ |
230
+ |---|---|
231
+ | "Rise & Fall now runs on V_200. Higher vol, wider payout range. Check the multiplier before you trade." | "We're excited to announce an exciting new instrument! Amazing opportunity for all traders!" |
232
+ | "Digits is live. Tick-based prediction on the last digit of a price feed. 1–10 ticks, six contract types." | "Introducing Digits, our innovative new game that revolutionises the prediction experience!" |
233
+ | "Withdrawal processing is now instant. Not 'faster.' Instant." | "We've made some improvements to our withdrawal process for a more seamless experience." |
234
+
235
+ ---
236
+
237
+ ## What we never say
238
+
239
+ Banned because they're empty, borrowed, or destructive to the player's self-image.
240
+
241
+ | Never say | Why |
242
+ |---|---|
243
+ | "Exciting" (describing our own things) | Show it; don't label it. |
244
+ | "Innovative" / "cutting-edge" | Claims, not descriptions. The product proves it. |
245
+ | "Seamless" | That's the baseline for anything that works. |
246
+ | "Journey" (as in trading journey) | Soft, vague, and corporate. |
247
+ | "Empowering" / "democratising" | Filler unless it's a mission statement. |
248
+ | "Don't miss out!" | Fake urgency. |
249
+ | "We're thrilled / excited / delighted to announce" | Start with the announcement. |
250
+ | "Lucky break" | Destroys the Edge Seeker's self-image. |
251
+ | "Your selection was incorrect" | Destroys all three modes simultaneously. |
252
+ | "Try again for another chance to win" | It's not a chance; it's a read. |
253
+ | "LFG" / "wagmi" / "gm fren" | Borrowed social credibility from a community we're not part of. |
254
+ | "You're getting the hang of this!" | Implies they didn't already have it. Kills the Public Predictor. |
255
+ | Three consecutive exclamation marks | Once is enough. Rarely. |
256
+
257
+ ---
258
+
259
+ ## Competitive positioning in voice
260
+
261
+ HyperSwap (@HyperSwapX) operates in adjacent social territory. Their tagline "Trade, Copy. Earn" packs a lot into three words. Their community language ("Swappies," point seasons, NFT allocations to top holders) creates belonging through ownership. They're transparent about tokenomics: "75% of protocol revenue to buyback and burn" states the number without hedging.
262
+
263
+ What they do well isn't transferable to us. Their belonging mechanics are ownership-based — you're a SWAP holder, an early believer, a governance participant. We don't have a token. Our belonging mechanics are mastery-based. "Your win rate: 54%. The baseline is 50%. You're ahead." is our version of "you're a Swappie." The ledger is skill, not holdings.
264
+
265
+ The other difference: HyperSwap assumes DeFi fluency. We can't. Some players have never held a token. Copy that assumes otherwise loses them at the first acronym.
266
+
267
+ | HyperSwap register | trading.game register |
268
+ |---|---|
269
+ | "SWAP Genesis is live. Early believers get rewarded 🔥" | "Rise & Fall is live on V_100. Edge is 2%. The rest is skill." |
270
+ | "Swappies, the airdrop is coming 🚀" | "Your win rate this week: 54%. Baseline is 50%. You're ahead." |
271
+ | "Earn boosted rewards for LPs 💰" | "Transferred 20 USDT to GridRush. Your capital, your call." |
272
+
273
+ ---
274
+
275
+ ## Vocabulary reference
276
+
277
+ | Use | Not |
278
+ |---|---|
279
+ | trading.game | Trading.Game / Trading Game (always lowercase) |
280
+ | USDT | Dollars, funds, money (use the specific term) |
281
+ | Trade (noun/verb) | Bet, wager, gamble |
282
+ | Contract | Position (in most contexts) |
283
+ | Rise / Fall | Up / Down (in game-specific copy) |
284
+ | Win rate | Success rate |
285
+ | Demo mode | Free play mode (in copy; "free play" is a UI label) |
286
+ | Arena | Dashboard, home screen |
287
+ | Real session | Live session, paid session |
288
+ | Settlement | Resolution, result |
289
+ | Bust | Loss (in in-game copy; elsewhere "loss" is fine) |
290
+
291
+ ### Game names — exact
292
+
293
+ | Correct | Not |
294
+ |---|---|
295
+ | Rise & Fall | Rise and Fall / Rise/Fall |
296
+ | GridRush | Grid Rush / Grid rush |
297
+ | Swipe Cards | Swipe-Cards / SwipeCards |
298
+ | Digits | The Digits game |
299
+ | Dice | The Dice game |
300
+
301
+ ### Formatting
302
+
303
+ - USDT amounts: `340 USDT` not `$340` (USDT is the platform currency)
304
+ - Percentages: `2%` not `2 percent`
305
+ - Win multipliers: `1.96×` with the multiplication symbol, not `1.96x`
306
+ - Tick counts: `5 ticks`, `1 tick` in UI; spell out in prose ("five ticks")
307
+
308
+ ---
309
+
310
+ ## Quick-reference checklist
311
+
312
+ Before publishing anything:
313
+
314
+ - [ ] Would "your selection was incorrect" be better? If so, rewrite it.
315
+ - [ ] Which mode is the player likely in when they read this? Does the copy protect that self-image?
316
+ - [ ] Any banned phrase? (exciting, innovative, seamless, journey, LFG, lucky break)
317
+ - [ ] More than one exclamation mark? Cut to zero.
318
+ - [ ] Does it land the point in the first sentence?
319
+ - [ ] Correct game name formatting?
320
+ - [ ] Is it shorter than it needs to be?
321
+ - [ ] Does it sound like trading.game, or could it belong to any product?
322
+
323
+ ---
324
+
325
+ *trading.game Brand Voice — v2.0*
@@ -36,7 +36,7 @@ NEVER use:
36
36
 
37
37
  ALWAYS use semantic tokens:
38
38
  ✅ bg-prominent, bg-card, bg-popover, bg-subtle, bg-overlay
39
- ✅ text-on-prominent, text-on-subtle, text-on-muted
39
+ ✅ text-on-prominent, text-on-subtle
40
40
  ✅ border-border-subtle, border-border-prominent, ring-ring
41
41
  ✅ bg-primary, bg-primary-hover, bg-secondary-hover
42
42
  ✅ text-semantic-win, text-semantic-loss, text-semantic-warning
@@ -151,7 +151,6 @@ import { Button, Card, Badge } from "@trading-game/design-intelligence-layer"
151
151
  | `--on-prominent` | `text-on-prominent` | Primary text (headings, body) |
152
152
  | `--on-prominent-static-inverse` | `text-on-prominent-static-inverse` | Always-white text (e.g. on primary blue buttons) |
153
153
  | `--on-subtle` | `text-on-subtle` | Secondary text (descriptions, labels) |
154
- | `--on-muted` | `text-on-muted` | Tertiary text (subtle labels, placeholders) |
155
154
 
156
155
  ### 2.5 — Borders & Inputs
157
156
 
@@ -281,7 +280,7 @@ import { Button, Card, Badge } from "@trading-game/design-intelligence-layer"
281
280
  | Color an elevated surface (popover) | `bg-popover` | `bg-card` for popovers |
282
281
  | Write primary heading text | `text-on-prominent` | Pure white, raw hex colors |
283
282
  | Write body / description text | `text-on-subtle` | `text-on-prominent` for descriptions |
284
- | Write a subtle label | `text-on-muted` | `text-on-subtle` for the subtlest text |
283
+ | Write a subtle label | `text-on-subtle` | Raw gray values |
285
284
  | Add a default border | `border-border-subtle` | Solid black borders, `border-border` |
286
285
  | Add a strong border | `border-border-prominent` | — |
287
286
  | Style an input (resting) | `border-input` | Solid colored backgrounds |
@@ -423,8 +422,8 @@ All buttons: `font-display font-bold`, sentence case (no `uppercase`, no `tracki
423
422
  | Hover | Color shift per variant (see above) |
424
423
  | Focus | 3px ring with `ring-ring/50` opacity |
425
424
  | Pressed | `active:opacity-60` |
426
- | Loading | `opacity-50`, `pointer-events-none`, `data-loading`, `aria-busy` |
427
- | Disabled | `opacity-50`, `pointer-events-none` |
425
+ | Loading | `opacity-24`, `pointer-events-none`, `data-loading`, `aria-busy` — applies to all variants (primary, secondary, tertiary) |
426
+ | Disabled | `opacity-24`, `pointer-events-none` — applies to all variants (primary, secondary, tertiary) |
428
427
 
429
428
  ---
430
429
 
@@ -546,6 +545,7 @@ import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, Dialog
546
545
  | Slider | [simple] | — |
547
546
  | Sonner (Toaster) | [simple] | — (also import `toast` from `sonner`) |
548
547
  | Spinner | [simple] | — |
548
+ | Stepper | [simple] | — |
549
549
  | Switch | [simple] | — |
550
550
  | Table | [composed] | TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption |
551
551
  | Tabs | [composed] | TabsList (`variant`: default/line, `size`: sm/md/lg), TabsTrigger (`iconPosition`: inline/top), TabsContent. Root accepts `orientation`: horizontal/vertical. |
@@ -571,6 +571,7 @@ These are styling behaviors you can't discover from TypeScript types alone:
571
571
  | Select | Item hover: `bg-primary/[0.08]`. Selected: `text-primary font-medium` + checkmark. `SelectTrigger` accepts `readOnly` prop: blocks interaction, retains full default appearance, chevron renders at `opacity-30` |
572
572
  | Progress | Track: `bg-primary/20`. Indicator: `bg-primary`. Radius: `rounded-2xs` |
573
573
  | Spinner | Inherits parent text color. **Always pass `text-primary` for standalone use** |
574
+ | Stepper | Numeric input flanked by `−` / `+` tertiary `icon-xs` buttons. Composes `InputGroup` internally. Props: `value`, `defaultValue`, `onValueChange`, `min`, `max`, `step` (default 1), `disabled`, `placeholder`. Supports controlled & uncontrolled modes, keyboard Arrow Up/Down, and floating-point steps. Default width: `w-32` |
574
575
  | Switch | Checked track: `bg-slider-range`. Checked thumb: `bg-primary` |
575
576
  | Slider | Thumb: square `rounded-[4px]`, `bg-primary`. Track range: `bg-slider-range` |
576
577
  | Dialog/Sheet | Footer buttons should use `size="md"`. Overlay: `bg-overlay` |
@@ -628,7 +629,7 @@ Landing page hero sections in multiple layout types.
628
629
  | Using `border-border` | Use `border-border-subtle` or `border-border-prominent` |
629
630
  | Using `bg-hover` | Use `bg-primary/[0.08]` or `bg-secondary-hover` |
630
631
  | Using `text-primary-foreground` | Use `text-on-prominent-static-inverse` |
631
- | Using `text-on-decorative` | Use `text-on-muted` |
632
+ | Using `text-on-decorative` | Use `text-on-subtle` |
632
633
  | Using `font-mono` expecting Plus Jakarta Sans | Use `font-display` or `font-body` |
633
634
  | Using `font-bold` for headings | Use `font-semibold` (600) for headings |
634
635
  | Using `uppercase` on buttons | Buttons use sentence case (no `uppercase`) |
@@ -645,7 +646,7 @@ Landing page hero sections in multiple layout types.
645
646
 
646
647
  1. **Primary blue text on white** (~3.0:1) — reserve for large/bold UI labels only.
647
648
  2. **Secondary text `text-on-subtle` on white** (~4.5:1) — meets WCAG AA for normal text.
648
- 3. **Tertiary text `text-on-muted` on white** (~7.0:1) — safe for all sizes.
649
+ 3. **Secondary text `text-on-subtle` on white** (~4.5:1) — meets WCAG AA for normal text.
649
650
  4. **Win green on white** (~5.0:1) — safe for normal text at AA.
650
651
  5. **Loss red on white** (~3.9:1) — use at 18px+ bold or pair with icons.
651
652
  6. Always pair semantic colors with **icons or labels** — never communicate meaning through color alone.
@@ -70,7 +70,7 @@ import { Button, Card, Badge } from "@trading-game/design-intelligence-layer"
70
70
  ✅ text-on-prominent — primary text (black #000000)
71
71
  ✅ text-on-prominent-static-inverse — always white — for text on dark/primary bg
72
72
  ✅ text-on-subtle — secondary text (mid grey)
73
- ✅ text-on-muted — low emphasis text (dark grey)
73
+
74
74
  ✅ text-primary — brand blue #2323FF
75
75
  ✅ text-semantic-win — green — profit/positive
76
76
  ✅ text-semantic-loss — red — loss/negative
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trading-game/design-intelligence-layer",
3
- "version": "0.9.0",
3
+ "version": "0.9.2",
4
4
  "description": "Trading Game Design System — shadcn/ui components with Tailwind CSS v4",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
package/src/styles.css CHANGED
@@ -51,7 +51,7 @@
51
51
  --color-alert-info-border: var(--alert-info-border);
52
52
  --color-alert-error-text: var(--alert-error-text);
53
53
  --color-alert-error-border: var(--alert-error-border);
54
- --color-on-muted: var(--on-muted);
54
+
55
55
  --color-overlay: var(--overlay);
56
56
  --color-slider-range: var(--slider-range);
57
57
  --color-semantic-info: var(--semantic-info);
@@ -242,7 +242,7 @@
242
242
  --primary-hover: oklch(0.403 0.251 267.5);
243
243
  --subtle: oklch(0.96 0 0);
244
244
  --on-subtle: oklch(0.52 0 0);
245
- --on-muted: oklch(0.38 0 0);
245
+
246
246
  --border-subtle: oklch(0.92 0 0);
247
247
  --border: var(--border-subtle);
248
248
  /* @deprecated alias — use --border-subtle or --border-prominent */