@cupped/tokens 0.1.0 → 0.2.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/README.md +5 -5
- package/dist/css/components.css +22 -8
- package/dist/css/tokens.css +2 -0
- package/dist/json/tokens.dtcg.json +22 -0
- package/dist/json/tokens.flat.json +2 -0
- package/dist/native/index.cjs +2 -0
- package/dist/native/index.d.ts +2 -0
- package/dist/native/index.js +2 -0
- package/dist/tailwind/theme.css +2 -0
- package/docs/expo.md +3 -11
- package/docs/phoenix.md +4 -3
- package/docs/releasing.md +39 -47
- package/package.json +1 -1
- package/tokens/semantic/motion.tokens.json +18 -0
package/README.md
CHANGED
|
@@ -5,9 +5,9 @@ community-first coffee-logging platform. The canonical source is
|
|
|
5
5
|
platform-neutral [DTCG](https://www.designtokens.org/TR/drafts/format/)-style
|
|
6
6
|
JSON under [`tokens/`](./tokens); every consumable artifact in
|
|
7
7
|
[`dist/`](./dist) is **generated** from it and committed. The package is
|
|
8
|
-
published
|
|
9
|
-
committed it also works as a plain git dependency
|
|
10
|
-
install-time build
|
|
8
|
+
published **public on npm** (`npm install @cupped/tokens` — no auth), and
|
|
9
|
+
because `dist/` is committed it also works as a plain git dependency with no
|
|
10
|
+
install-time build, for consumers that prefer pinning a commit.
|
|
11
11
|
|
|
12
12
|
> Never hard-code a hex or pixel value that exists as a token.
|
|
13
13
|
|
|
@@ -28,7 +28,7 @@ fonts are self-hosted per platform (documented).
|
|
|
28
28
|
## Consuming
|
|
29
29
|
|
|
30
30
|
- **Phoenix LiveView (Tailwind v4):** [docs/phoenix.md](./docs/phoenix.md) —
|
|
31
|
-
pinned CSS from the GitHub Release, npm
|
|
31
|
+
pinned CSS from the GitHub Release, npm dependency, or zero-npm vendor mode;
|
|
32
32
|
fonts, lint recipe.
|
|
33
33
|
- **Expo / React Native (SDK 53+):** [docs/expo.md](./docs/expo.md) — the
|
|
34
34
|
`theme.ts` pattern, expo-font, ESLint recipe.
|
|
@@ -71,7 +71,7 @@ npm run check # build, fail on dist/ drift, then test — what CI runs
|
|
|
71
71
|
## Releasing & versioning
|
|
72
72
|
|
|
73
73
|
Releases are automated with [Changesets](https://github.com/changesets/changesets)
|
|
74
|
-
and published to
|
|
74
|
+
and published to public npm; each release also attaches version-pinned CSS
|
|
75
75
|
to its GitHub Release. Add a changeset with `npx changeset` in any PR that
|
|
76
76
|
changes tokens.
|
|
77
77
|
|
package/dist/css/components.css
CHANGED
|
@@ -94,6 +94,7 @@
|
|
|
94
94
|
/* ——— Inputs ——— */
|
|
95
95
|
.input {
|
|
96
96
|
width: 100%;
|
|
97
|
+
min-height: var(--hit-target-min); /* ≥44pt tap target — matches .btn */
|
|
97
98
|
padding: 12px 14px;
|
|
98
99
|
border: 1px solid var(--canvas-border);
|
|
99
100
|
border-radius: var(--radius-md);
|
|
@@ -103,21 +104,28 @@
|
|
|
103
104
|
color: var(--ink);
|
|
104
105
|
transition: border-color .15s, box-shadow .15s;
|
|
105
106
|
}
|
|
106
|
-
|
|
107
|
+
/* Placeholder is essential text — ink-secondary clears AA; ink-muted does not. */
|
|
108
|
+
.input::placeholder { color: var(--ink-secondary); }
|
|
109
|
+
.input:hover:not(:focus):not([disabled]) { border-color: var(--ink-muted); }
|
|
107
110
|
.input:focus {
|
|
108
111
|
outline: none;
|
|
109
|
-
border-color: var(--primary);
|
|
110
|
-
box-shadow: 0 0
|
|
112
|
+
border-color: var(--primary-strong); /* #C05539, ≥3:1 vs field — carries the contrast */
|
|
113
|
+
box-shadow: 0 0 6px 2px var(--focus-glow); /* soft glow, decorative; buttons keep the two-tone ring */
|
|
111
114
|
}
|
|
112
|
-
.input.error
|
|
115
|
+
.input.error,
|
|
116
|
+
.input.error:focus {
|
|
113
117
|
border-color: var(--error);
|
|
114
|
-
box-shadow: 0 0
|
|
118
|
+
box-shadow: 0 0 6px 2px var(--error-glow); /* soft glow, error color — shown focused or not */
|
|
115
119
|
}
|
|
116
120
|
.input[disabled] { background: var(--canvas); color: var(--ink-muted); cursor: not-allowed; }
|
|
117
121
|
.input-row { display: flex; flex-direction: column; gap: 6px; }
|
|
118
|
-
.input-label { font-size:
|
|
119
|
-
|
|
122
|
+
.input-label { font-size: var(--text-caption); font-weight: 500; color: var(--ink-secondary); }
|
|
123
|
+
/* Hint: neutral helper by default; .error turns it red + pairs an icon (never color alone, WCAG 1.4.1). */
|
|
124
|
+
.input-hint { display: flex; align-items: center; gap: 6px; font-size: var(--text-caption); color: var(--ink-secondary); }
|
|
125
|
+
.input-hint .icon { width: 14px; height: 14px; flex-shrink: 0; }
|
|
120
126
|
.input-hint.error { color: var(--error-ink); }
|
|
127
|
+
/* Validating — async check (e.g. "checking bean name"); pair with .spinner.spinner-ink */
|
|
128
|
+
.input-hint.validating { color: var(--ink-secondary); }
|
|
121
129
|
|
|
122
130
|
/* ——— Cards ——— */
|
|
123
131
|
.card {
|
|
@@ -177,7 +185,13 @@
|
|
|
177
185
|
}
|
|
178
186
|
@keyframes cupped-spin { to { transform: rotate(360deg); } }
|
|
179
187
|
|
|
188
|
+
/* Dark spinner for light surfaces (input validating, secondary/ghost buttons) */
|
|
189
|
+
.spinner-ink {
|
|
190
|
+
border-color: color-mix(in srgb, var(--ink) 18%, transparent);
|
|
191
|
+
border-top-color: var(--ink-secondary);
|
|
192
|
+
}
|
|
193
|
+
|
|
180
194
|
@media (prefers-reduced-motion: reduce) {
|
|
181
|
-
.btn { transition: none; }
|
|
195
|
+
.btn, .input { transition: none; }
|
|
182
196
|
.spinner { animation: none; }
|
|
183
197
|
}
|
package/dist/css/tokens.css
CHANGED
|
@@ -119,6 +119,8 @@
|
|
|
119
119
|
--shimmer-duration: 1.5s;
|
|
120
120
|
--motion-reduced: 120ms;
|
|
121
121
|
--focus-ring: 0 0 0 2px var(--card), 0 0 0 4px var(--primary-strong);
|
|
122
|
+
--focus-glow: color-mix(in srgb, var(--primary-strong) 22%, transparent);
|
|
123
|
+
--error-glow: color-mix(in srgb, var(--error) 22%, transparent);
|
|
122
124
|
--hit-target-min: 44px;
|
|
123
125
|
|
|
124
126
|
/* ── Materials ── */
|
|
@@ -1304,6 +1304,28 @@
|
|
|
1304
1304
|
"outerWidthPx": 2
|
|
1305
1305
|
}
|
|
1306
1306
|
}
|
|
1307
|
+
},
|
|
1308
|
+
"glow": {
|
|
1309
|
+
"$type": "color",
|
|
1310
|
+
"$value": "rgba(192, 85, 57, 0.22)",
|
|
1311
|
+
"$description": "Decorative input focus halo — primary-strong @ 22%. The primary-strong border carries the ≥3:1 contrast; this glow is decorative. Buttons keep the two-tone focus ring.",
|
|
1312
|
+
"$extensions": {
|
|
1313
|
+
"app.cupped": {
|
|
1314
|
+
"cssName": "focus-glow",
|
|
1315
|
+
"cssValue": "color-mix(in srgb, var(--primary-strong) 22%, transparent)"
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
},
|
|
1319
|
+
"errorGlow": {
|
|
1320
|
+
"$type": "color",
|
|
1321
|
+
"$value": "rgba(239, 68, 68, 0.22)",
|
|
1322
|
+
"$description": "Decorative input error halo — error @ 22%. Pairs with the error border; shown whether or not the field is focused.",
|
|
1323
|
+
"$extensions": {
|
|
1324
|
+
"app.cupped": {
|
|
1325
|
+
"cssName": "error-glow",
|
|
1326
|
+
"cssValue": "color-mix(in srgb, var(--error) 22%, transparent)"
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1307
1329
|
}
|
|
1308
1330
|
},
|
|
1309
1331
|
"hit-target": {
|
|
@@ -77,6 +77,8 @@
|
|
|
77
77
|
"shimmer-duration": "1.5s",
|
|
78
78
|
"motion-reduced": "120ms",
|
|
79
79
|
"focus-ring": "0 0 0 2px #FFFFFF, 0 0 0 4px #C05539",
|
|
80
|
+
"focus-glow": "rgba(192, 85, 57, 0.22)",
|
|
81
|
+
"error-glow": "rgba(239, 68, 68, 0.22)",
|
|
80
82
|
"hit-target-min": "44px",
|
|
81
83
|
"radius-sm": "8px",
|
|
82
84
|
"radius-md": "12px",
|
package/dist/native/index.cjs
CHANGED
|
@@ -271,6 +271,8 @@ const tokens = {
|
|
|
271
271
|
"innerColor": "#FFFFFF",
|
|
272
272
|
"color": "#C05539"
|
|
273
273
|
},
|
|
274
|
+
"focusGlow": "rgba(192, 85, 57, 0.22)",
|
|
275
|
+
"errorGlow": "rgba(239, 68, 68, 0.22)",
|
|
274
276
|
"material": {
|
|
275
277
|
"chromeBg": "rgba(255, 255, 255, 0.95)",
|
|
276
278
|
"scrim": "rgba(15, 23, 42, 0.45)",
|
package/dist/native/index.d.ts
CHANGED
|
@@ -271,6 +271,8 @@ export declare const tokens: {
|
|
|
271
271
|
readonly "innerColor": "#FFFFFF";
|
|
272
272
|
readonly "color": "#C05539";
|
|
273
273
|
};
|
|
274
|
+
readonly "focusGlow": "rgba(192, 85, 57, 0.22)";
|
|
275
|
+
readonly "errorGlow": "rgba(239, 68, 68, 0.22)";
|
|
274
276
|
readonly "material": {
|
|
275
277
|
readonly "chromeBg": "rgba(255, 255, 255, 0.95)";
|
|
276
278
|
readonly "scrim": "rgba(15, 23, 42, 0.45)";
|
package/dist/native/index.js
CHANGED
|
@@ -270,6 +270,8 @@ export const tokens = {
|
|
|
270
270
|
"innerColor": "#FFFFFF",
|
|
271
271
|
"color": "#C05539"
|
|
272
272
|
},
|
|
273
|
+
"focusGlow": "rgba(192, 85, 57, 0.22)",
|
|
274
|
+
"errorGlow": "rgba(239, 68, 68, 0.22)",
|
|
273
275
|
"material": {
|
|
274
276
|
"chromeBg": "rgba(255, 255, 255, 0.95)",
|
|
275
277
|
"scrim": "rgba(15, 23, 42, 0.45)",
|
package/dist/tailwind/theme.css
CHANGED
|
@@ -143,6 +143,8 @@
|
|
|
143
143
|
--shimmer-duration: 1.5s;
|
|
144
144
|
--motion-reduced: 120ms;
|
|
145
145
|
--focus-ring: 0 0 0 2px #FFFFFF, 0 0 0 4px #C05539;
|
|
146
|
+
--focus-glow: rgba(192, 85, 57, 0.22);
|
|
147
|
+
--error-glow: rgba(239, 68, 68, 0.22);
|
|
146
148
|
--hit-target-min: 44px;
|
|
147
149
|
--material-chrome-bg: rgba(255, 255, 255, 0.95);
|
|
148
150
|
--material-chrome-blur: saturate(1.4) blur(20px);
|
package/docs/expo.md
CHANGED
|
@@ -7,15 +7,7 @@ default). The top-level `main`/`types` fallback covers SDK 52. The
|
|
|
7
7
|
|
|
8
8
|
## Install
|
|
9
9
|
|
|
10
|
-
**
|
|
11
|
-
the app's `.npmrc`:
|
|
12
|
-
|
|
13
|
-
```ini
|
|
14
|
-
# .npmrc
|
|
15
|
-
@cupped:registry=https://npm.pkg.github.com
|
|
16
|
-
# TODO: this registry needs a read token. Add the auth line for your setup, e.g.
|
|
17
|
-
# //npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
|
|
18
|
-
```
|
|
10
|
+
Published **public on npm** — no registry config, no token, no `.npmrc`:
|
|
19
11
|
|
|
20
12
|
```bash
|
|
21
13
|
npm install @cupped/tokens
|
|
@@ -23,8 +15,8 @@ npm install @cupped/tokens
|
|
|
23
15
|
|
|
24
16
|
Pin the version in `package.json` as usual (`"@cupped/tokens": "^0.1.0"`).
|
|
25
17
|
|
|
26
|
-
**Fallback — git dependency
|
|
27
|
-
|
|
18
|
+
**Fallback — git dependency.** Because `dist/` is committed, the package also
|
|
19
|
+
installs straight from git (e.g. to pin an unpublished commit):
|
|
28
20
|
|
|
29
21
|
```bash
|
|
30
22
|
npm install github:ybird-labs/cupped-design-system#v0.1.0
|
package/docs/phoenix.md
CHANGED
|
@@ -38,14 +38,15 @@ gh release download "v${CUPPED_TOKENS_VERSION}" \
|
|
|
38
38
|
(`gh release download` needs an authenticated `gh` / token with read access to
|
|
39
39
|
the package repo. The filenames are stable: `cupped-tokens-<version>.<target>.css`.)
|
|
40
40
|
|
|
41
|
-
## Mode 1 — npm
|
|
41
|
+
## Mode 1 — npm dependency
|
|
42
42
|
|
|
43
|
-
Create `assets/package.json` (or add to it)
|
|
43
|
+
Create `assets/package.json` (or add to it) — `@cupped/tokens` is public on npm,
|
|
44
|
+
so no registry auth is needed:
|
|
44
45
|
|
|
45
46
|
```jsonc
|
|
46
47
|
{
|
|
47
48
|
"dependencies": {
|
|
48
|
-
"@cupped/tokens": "
|
|
49
|
+
"@cupped/tokens": "^0.1.0"
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
```
|
package/docs/releasing.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Releasing @cupped/tokens
|
|
2
2
|
|
|
3
|
-
The package is published
|
|
4
|
-
`https://
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
and attaches versioned CSS to the GitHub Release.
|
|
3
|
+
The package is published **public on npm** as
|
|
4
|
+
[`@cupped/tokens`](https://www.npmjs.com/package/@cupped/tokens) — consumers
|
|
5
|
+
install it with no auth. Releases are driven by
|
|
6
|
+
[Changesets](https://github.com/changesets/changesets); the
|
|
7
|
+
[`release.yml`](../.github/workflows/release.yml) workflow does the publish
|
|
8
|
+
(with provenance) and attaches versioned CSS to the GitHub Release.
|
|
9
9
|
|
|
10
10
|
For *what* bump to choose, see [versioning.md](./versioning.md).
|
|
11
11
|
|
|
@@ -35,7 +35,7 @@ changesets/action sees pending changesets
|
|
|
35
35
|
release.yml runs again → no pending changesets, version not yet published
|
|
36
36
|
│
|
|
37
37
|
▼ changesets/action runs `npm run release` (changeset publish)
|
|
38
|
-
changeset publish → publishes to
|
|
38
|
+
changeset publish → publishes to npm (public) + creates the git tag vX.Y.Z
|
|
39
39
|
the changesets/action wrapper then creates the matching GitHub Release
|
|
40
40
|
│
|
|
41
41
|
▼ upload step attaches the three CSS files to Release vX.Y.Z:
|
|
@@ -47,47 +47,39 @@ changeset publish → publishes to GitHub Packages + creates the git tag vX.Y.Z
|
|
|
47
47
|
You never bump `package.json` or write `CHANGELOG.md` by hand — merging the
|
|
48
48
|
Version Packages PR does it.
|
|
49
49
|
|
|
50
|
-
##
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
2.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
Consuming repos in the same org need **read** access to the package:
|
|
80
|
-
|
|
81
|
-
- In the package settings on GitHub → *Package settings* → *Manage Actions
|
|
82
|
-
access* / *Manage access*, grant the consumer repos (e.g. the Phoenix and
|
|
83
|
-
Expo apps) read access.
|
|
84
|
-
- Consumers then authenticate with a token that has `read:packages`. (Consumer
|
|
85
|
-
`.npmrc` setup is documented per-app — see [expo.md](./expo.md). **TODO:**
|
|
86
|
-
finalize and document the consumer read-token model.)
|
|
50
|
+
## CI setup for automated releases (one-time)
|
|
51
|
+
|
|
52
|
+
Automated releases publish to **public npm** via the Release workflow. Two
|
|
53
|
+
one-time setups in repo settings:
|
|
54
|
+
|
|
55
|
+
1. **`NPM_TOKEN` secret** — create an npm **Automation** token (npmjs.com →
|
|
56
|
+
Access Tokens → Generate New Token → *Automation*; it bypasses 2FA) on an
|
|
57
|
+
account that owns the `@cupped` npm org, and add it as the repo secret
|
|
58
|
+
**`NPM_TOKEN`** (Settings → Secrets and variables → Actions). The workflow
|
|
59
|
+
passes it as `NODE_AUTH_TOKEN`.
|
|
60
|
+
2. **Allow Actions to open PRs** — Settings → Actions → General → Workflow
|
|
61
|
+
permissions → check *"Allow GitHub Actions to create and approve pull
|
|
62
|
+
requests"* (needed for the Changesets "Version Packages" PR).
|
|
63
|
+
|
|
64
|
+
The workflow also requests `id-token: write`, so npm attaches build
|
|
65
|
+
**provenance** to each public release.
|
|
66
|
+
|
|
67
|
+
## First publish (already done for 0.1.0)
|
|
68
|
+
|
|
69
|
+
`0.1.0` was published manually once to bootstrap the package:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npm login # browser auth to npmjs (owner of the @cupped org)
|
|
73
|
+
npm ci && npm run check
|
|
74
|
+
npm publish # public; prepublishOnly rebuilds dist/ first
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Every subsequent release is automated — no manual publish.
|
|
87
78
|
|
|
88
79
|
## Verifying a published release
|
|
89
80
|
|
|
90
|
-
- The
|
|
91
|
-
|
|
92
|
-
|
|
81
|
+
- The version is on npm: <https://www.npmjs.com/package/@cupped/tokens>
|
|
82
|
+
(or `npm view @cupped/tokens version`). Consumers install with no auth.
|
|
83
|
+
- The GitHub Release `vX.Y.Z` exists with the `cupped-tokens-X.Y.Z.*.css`
|
|
84
|
+
assets (+ `.sha256`) attached.
|
|
93
85
|
- `CHANGELOG.md` has an entry for the version.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cupped/tokens",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Cupped design tokens — canonical DTCG source with generated CSS custom properties, Tailwind v4 @theme, React Native theme object, and raw JSON.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -40,6 +40,24 @@
|
|
|
40
40
|
],
|
|
41
41
|
"$description": "Opaque dual focus ring (refreshed export) — ≥3:1 non-text contrast on any surface. Outline is never removed without a replacement.",
|
|
42
42
|
"$extensions": { "app.cupped": { "innerWidthPx": 2, "outerWidthPx": 2 } }
|
|
43
|
+
},
|
|
44
|
+
"glow": {
|
|
45
|
+
"$type": "color",
|
|
46
|
+
"$value": "rgba(192, 85, 57, 0.22)",
|
|
47
|
+
"$description": "Decorative input focus halo — primary-strong @ 22%. The primary-strong border carries the ≥3:1 contrast; this glow is decorative. Buttons keep the two-tone focus ring.",
|
|
48
|
+
"$extensions": { "app.cupped": {
|
|
49
|
+
"cssName": "focus-glow",
|
|
50
|
+
"cssValue": "color-mix(in srgb, var(--primary-strong) 22%, transparent)"
|
|
51
|
+
} }
|
|
52
|
+
},
|
|
53
|
+
"errorGlow": {
|
|
54
|
+
"$type": "color",
|
|
55
|
+
"$value": "rgba(239, 68, 68, 0.22)",
|
|
56
|
+
"$description": "Decorative input error halo — error @ 22%. Pairs with the error border; shown whether or not the field is focused.",
|
|
57
|
+
"$extensions": { "app.cupped": {
|
|
58
|
+
"cssName": "error-glow",
|
|
59
|
+
"cssValue": "color-mix(in srgb, var(--error) 22%, transparent)"
|
|
60
|
+
} }
|
|
43
61
|
}
|
|
44
62
|
},
|
|
45
63
|
"hit-target": {
|