@dustin-riley/design 0.3.0 → 0.5.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/DESIGN.md CHANGED
@@ -8,9 +8,10 @@ This doc is the source of truth; the bundled `dustinriley-design` skill mirrors
8
8
 
9
9
  ## Tl;dr — non-negotiables
10
10
 
11
- - **One primary** (burnt orange `#B8541C`), **two accents** (ochre, teal). Don't invent colors.
11
+ - **One primary** (burnt orange `#B8541C`), **two accents** (ochre, teal), **plum** as a tertiary accent — also the basis of the AI treatment (§ AI content). Don't invent colors.
12
12
  - **Three radii only**: `8px` (inputs/chips), `16px` (cards/modals), `999px` (buttons/toggles). Nothing else.
13
13
  - **Three shadows only**: `sm`, `md`, `lg` — all warm-tinted (`rgba(74, 52, 28, …)`), never gray or black.
14
+ - **One border weight**: `--ds-border-width` (`1px`), never heavier — emphasis is shadow / elevation, not a thicker border.
14
15
  - **Sentence case everywhere.** No Title Case. No ALL CAPS for emphasis. Even nav: "experiments", "writing", "about".
15
16
  - **First person.** Address the reader as "you". No marketing puffery.
16
17
  - **No emoji.** Use Lucide icons or unicode arrows (`→ ↗ ↓ ←`).
@@ -67,6 +68,9 @@ Warm-neutral canvas with one primary and two accents. Color is reserved for inte
67
68
  | `--ds-link-hover` | `#85390F` | Link hover |
68
69
  | `--ds-accent-ochre` | `#C9922B` | Accent + warning |
69
70
  | `--ds-accent-teal` | `#2E7D7A` | Accent |
71
+ | `--ds-accent-plum` | `#8B5E83` | Tertiary accent (decorative use ok) |
72
+ | `--ds-surface-ai` | `#F1E9EF` | AI-content surface (`.ds-ai`) |
73
+ | `--ds-on-surface-ai` | `#6A4763` | AI mark text/glyph (`.ds-ai-mark`; AA on AI surface, bg, surface) |
70
74
  | `--ds-success` | `#5C7A3E` | Warm olive |
71
75
  | `--ds-error` | `#A8392E` | Warm brick red |
72
76
 
@@ -85,6 +89,38 @@ Warm-neutral canvas with one primary and two accents. Color is reserved for inte
85
89
 
86
90
  ---
87
91
 
92
+ ## AI content
93
+
94
+ A first-class, on-brand way to mark model-generated content. It is built on
95
+ plum but **plum is not reserved** — a decorative plum accent elsewhere is
96
+ fine. AI is signalled by the **`.ds-ai` surface + `.ds-ai-mark` mark
97
+ together**, never by colour alone.
98
+
99
+ | Token / class | Role |
100
+ |---|---|
101
+ | `--ds-surface-ai` | Faint plum surface for an AI block |
102
+ | `--ds-on-surface-ai` | Mark text/glyph colour (WCAG AA on AI surface, bg, surface) |
103
+ | `.ds-ai` | Surface-only modifier — compose with `.ds-panel` for chrome |
104
+ | `.ds-ai-mark` | The byline mark; composes independently (block or inline) |
105
+
106
+ **The mark.** Lucide `cpu` (canonical; `bot` is the only sanctioned
107
+ alternative — swap the whole system, not one use) + the plainspoken byline
108
+ `the model says · <model>`. Naming the model is encouraged — transparency is
109
+ the character. Markup: `<span class="ds-ai-mark"><Cpu/> the model says ·
110
+ sonnet</span>` (the package ships the class; the consumer renders the Lucide
111
+ icon, same contract as the rest of iconography). Write the byline in
112
+ sentence case in source — `.ds-ai-mark` renders it uppercase, the mono-meta
113
+ carve-out (see § Type), not an ALL-CAPS exception to the voice rule.
114
+
115
+ **Sub-states inside a constant AI block.** Keep the `.ds-ai` surface and mark
116
+ constant; differentiate sub-states (e.g. a verdict) by tinting the state's
117
+ Lucide icon with an existing semantic token (`--ds-success`,
118
+ `--ds-accent-ochre`/warning, `--ds-error`, `--ds-primary`, `--ds-text-muted`)
119
+ — icons are non-text (3:1), so no per-state surface or border. Never a
120
+ heavier border (see the border non-negotiable).
121
+
122
+ ---
123
+
88
124
  ## Type
89
125
 
90
126
  Outfit (display) × DM Sans (body) — geometric × rounded — JetBrains Mono for code and meta only. No italics in UI chrome.
@@ -125,6 +161,18 @@ Corners are continuous / squircle-adjacent — that's why `16px` and `999px` fee
125
161
 
126
162
  ---
127
163
 
164
+ ## Border
165
+
166
+ One weight. **No others allowed.**
167
+
168
+ | Token | Value | Use |
169
+ |---|---|---|
170
+ | `--ds-border-width` | `1px` | Every border — panels, inputs, dividers, hairlines |
171
+
172
+ Borders are always this single hairline; the system has no heavier border. When something needs more separation or emphasis, use **shadow / elevation** (see Shadow), not a thicker border. Reference `--ds-border-width` for the width and `--ds-border` for the color — never hard-code `1px`.
173
+
174
+ ---
175
+
128
176
  ## Motion
129
177
 
130
178
  Spring easing over linear. **Everything resolves under 300ms.**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dustin-riley/design",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Dustin Riley design system — warm mid-century modern tokens and primitives.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -14,6 +14,7 @@ Apply this whenever you add or change UI in a project importing `@dustin-riley/d
14
14
  - Color is never the only state signal. Motion resolves under 300ms.
15
15
  - For text-as-link in burnt orange use `--ds-link`, never `--ds-primary` (WCAG AA).
16
16
  - Never hard-code a hex/px value — reference a `--ds-*` token.
17
+ - AI-generated content uses `.ds-ai` (surface) + `.ds-ai-mark` (Lucide `cpu` + "the model says · <model>") together — never plum colour alone. Plum stays a usable tertiary accent. Write the byline sentence-case in source; `.ds-ai-mark` renders it uppercase (mono-meta carve-out, not an ALL-CAPS exception).
17
18
 
18
19
  ## How to consume
19
20
  - Always: `@import "@dustin-riley/design/tokens.css"; @import "@dustin-riley/design/core.css";`
@@ -29,7 +30,7 @@ Apply this whenever you add or change UI in a project importing `@dustin-riley/d
29
30
  Buttons `.ds-btn` + `.ds-btn-primary|secondary|ghost`; layout `.ds-container`,
30
31
  `.ds-section`; type `.ds-display`, `.ds-lede`, `.ds-caption`, `.ds-mono-note`,
31
32
  `.grid-label`, `.h1`–`.h6`; chrome bits `.ds-page-header`, `.ds-back-link`;
32
- surfaces `.ds-panel`, `.kbd`.
33
+ surfaces `.ds-panel`, `.kbd`; AI `.ds-ai`, `.ds-ai-mark`.
33
34
 
34
35
  Site-specific furniture (nav, footer, hero, grids) is NOT in the package by
35
36
  design — build it per project from these primitives and tokens.
package/src/core.css CHANGED
@@ -130,7 +130,7 @@ h6,
130
130
  .ds-btn-secondary {
131
131
  background: var(--ds-surface);
132
132
  color: var(--ds-text);
133
- border: 1px solid var(--ds-border);
133
+ border: var(--ds-border-width) solid var(--ds-border);
134
134
  }
135
135
 
136
136
  .ds-btn-secondary:hover {
@@ -220,13 +220,42 @@ h6,
220
220
  box-shadow: var(--ds-shadow-md);
221
221
  }
222
222
 
223
+ /* ----- AI content -----
224
+ .ds-ai is a surface-only modifier (compose with .ds-panel for chrome).
225
+ It pins color:var(--ds-text) (not just background) so the light plum
226
+ surface keeps a safe foreground even nested in an inverted region —
227
+ same surface/foreground contract as .ds-btn-secondary.
228
+ .ds-ai-mark is the mono "the model says" byline; composes independently
229
+ (inside .ds-ai or inline in ordinary content). It intentionally restates
230
+ the .grid-label mono-meta recipe (mono + caption + 500 + uppercase +
231
+ 0.06em) as a distinct role with the plum AI foreground — same precedent
232
+ as .ds-caption vs .grid-label; do NOT factor it into a shared base.
233
+ Both use the plum AI tokens. AI is signalled by surface + mark TOGETHER,
234
+ never plum alone. */
235
+ .ds-ai {
236
+ background: var(--ds-surface-ai);
237
+ color: var(--ds-text);
238
+ }
239
+
240
+ .ds-ai-mark {
241
+ display: inline-flex;
242
+ align-items: center;
243
+ gap: var(--ds-space-1);
244
+ font-family: var(--ds-font-mono);
245
+ font-size: var(--ds-fs-caption);
246
+ font-weight: 500;
247
+ text-transform: uppercase;
248
+ letter-spacing: 0.06em;
249
+ color: var(--ds-on-surface-ai);
250
+ }
251
+
223
252
  /* ----- kbd chip ----- */
224
253
  .kbd {
225
254
  font-family: var(--ds-font-mono);
226
255
  font-size: 11px;
227
256
  padding: 2px 6px;
228
257
  background: var(--ds-surface);
229
- border: 1px solid var(--ds-border);
258
+ border: var(--ds-border-width) solid var(--ds-border);
230
259
  border-radius: var(--ds-radius-sm);
231
260
  color: var(--ds-text);
232
261
  }
@@ -297,7 +326,7 @@ h6,
297
326
  background: var(--ds-surface-sunken);
298
327
  padding: 2px 6px;
299
328
  border-radius: var(--ds-radius-sm);
300
- border: 1px solid var(--ds-border);
329
+ border: var(--ds-border-width) solid var(--ds-border);
301
330
  }
302
331
 
303
332
  ::selection { background: rgba(184, 84, 28, 0.2); }
package/src/tokens.css CHANGED
@@ -88,6 +88,17 @@
88
88
  --ds-radius-md: 16px;
89
89
  --ds-radius-pill: 999px;
90
90
 
91
+ /* Border width (1 only — never heavier; emphasis is shadow, not thickness) */
92
+ --ds-border-width: 1px;
93
+
94
+ /* AI content (plum-derived; the AI surface + mark together signal AI —
95
+ plum itself stays a usable tertiary accent). --ds-on-surface-ai is the
96
+ paired foreground for --ds-surface-ai (cf. --ds-on-primary) and clears
97
+ WCAG AA: ~6.55:1 on --ds-surface-ai, ~7.24:1 on --ds-bg, ~6.64:1 on
98
+ --ds-surface (measured), mirroring the --ds-link precedent. */
99
+ --ds-surface-ai: #f1e9ef;
100
+ --ds-on-surface-ai: #6a4763;
101
+
91
102
  /* Shadow (warm-tinted) */
92
103
  --ds-shadow-sm: 0 1px 2px rgba(74, 52, 28, 0.06),
93
104
  0 1px 1px rgba(74, 52, 28, 0.04);