@plutocms/core 0.38.0 → 0.38.1

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/CHANGELOG.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # Changelog
2
2
 
3
3
 
4
+ ## [0.38.1](https://github.com/plutocms/pluto/compare/v0.38.0...v0.38.1) (2026-10-30)
5
+
6
+
7
+ ### Bug Fixes
8
+
9
+ * the core package leaves out its dev scripts ([#284](https://github.com/plutocms/pluto/issues/284)) ([c62763f](https://github.com/plutocms/pluto/commit/c62763f42cd0976514b2de515ea3e52971eef65a))
10
+
4
11
  ## [0.38.0](https://github.com/plutocms/pluto/compare/v0.37.0...v0.38.0) (2026-10-30)
5
12
 
6
13
 
@@ -32,7 +32,7 @@
32
32
  * Chart colors are a validated categorical palette: lightness band, chroma
33
33
  * floor, colorblind separation, and 3:1 contrast pass on white (light) and
34
34
  * on the dark card surface (dark). This file is generated; keep the values in
35
- * sync with scripts/generate-admin-theme.cjs: run it from the repo root, never
35
+ * sync with scripts/generate-admin-theme.cjs: run it from packages/core, never
36
36
  * edit this file by hand.
37
37
  */
38
38
  :root[data-pluto-admin],
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@plutocms/core",
3
3
  "type": "module",
4
- "version": "0.38.0",
4
+ "version": "0.38.1",
5
5
  "description": "The base layer every Pluto app extends: the admin, the content model, and the GitHub CMS",
6
6
  "author": "Victor Ribeiro",
7
7
  "license": "MIT",
@@ -1,263 +0,0 @@
1
- // Generates app/assets/css/admin-theme.css from the Pluto UI tokens
2
- // (app/assets/css/pluto-tokens.css) and the installed Tailwind palette (the
3
- // status colors). Run from the repo root: node scripts/generate-admin-theme.cjs
4
- // See the admin-theme skill for the palette choices and how they were
5
- // validated.
6
- const fs = require('node:fs')
7
- const path = require('node:path')
8
-
9
- const theme = fs.readFileSync(
10
- path.join(
11
- path.dirname(
12
- require.resolve('tailwindcss/package.json', { paths: [process.cwd()] })
13
- ),
14
- 'theme.css'
15
- ),
16
- 'utf8'
17
- )
18
- const tokens = fs.readFileSync('app/assets/css/pluto-tokens.css', 'utf8')
19
-
20
- // sRGB hex to an OKLCH literal, so every value in the theme has one form.
21
- const toLinear = (c) =>
22
- c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4
23
- function hexToOklch(hex) {
24
- const n = Number.parseInt(hex.slice(1), 16)
25
- const [r, g, b] = [(n >> 16) & 255, (n >> 8) & 255, n & 255].map((value) =>
26
- toLinear(value / 255)
27
- )
28
- const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b)
29
- const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b)
30
- const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b)
31
- const L = 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s
32
- const A = 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s
33
- const B = 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s
34
- const C = Math.hypot(A, B)
35
- const H = ((Math.atan2(B, A) * 180) / Math.PI + 360) % 360
36
- return `oklch(${(L * 100).toFixed(1)}% ${C.toFixed(3)} ${H.toFixed(2)})`
37
- }
38
-
39
- // A Pluto token (tholin, haze, heart, kuiper) or a Tailwind color, as an OKLCH literal.
40
- function v(name) {
41
- const own = tokens.match(
42
- new RegExp(String.raw`--color-${name}: (#[0-9A-Fa-f]{6})`)
43
- )
44
- if (own) {
45
- return hexToOklch(own[1])
46
- }
47
- return theme.match(
48
- new RegExp(String.raw`--color-${name}: (oklch\([^)]*\))`)
49
- )[1]
50
- }
51
-
52
- // Tholin is a red-orange (hue 37). Tailwind red (hue 27) looks like it next
53
- // to a primary button, so errors use rose (hue 17). Info is haze, the blue of
54
- // the Pluto palette.
55
- const roles = {
56
- primary: 'tholin',
57
- secondary: 'haze',
58
- success: 'green',
59
- info: 'haze',
60
- warning: 'amber',
61
- error: 'rose',
62
- neutral: 'kuiper',
63
- }
64
- const shades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950]
65
- const scales = Object.entries(roles)
66
- .map(
67
- ([role, hue]) =>
68
- ` /* ${role}: ${hue} */\n${shades.map((s) => ` --ui-color-${role}-${s}: ${v(`${hue}-${s}`)};`).join('\n')}`
69
- )
70
- .join('\n\n')
71
-
72
- // The semantic step of each role. Light: tholin 600 and haze 700 for 4.5:1 on
73
- // white (the docs site uses the same steps), the status colors at 500. Dark:
74
- // 400 for every role.
75
- const lightSteps = {
76
- primary: 600,
77
- secondary: 700,
78
- success: 500,
79
- info: 500,
80
- warning: 500,
81
- error: 500,
82
- }
83
- const semantic = (steps) =>
84
- Object.entries(steps)
85
- .map(([role, step]) => ` --ui-${role}: var(--ui-color-${role}-${step});`)
86
- .join('\n')
87
- const darkSteps = Object.fromEntries(
88
- Object.keys(lightSteps).map((role) => [role, 400])
89
- )
90
-
91
- const n = (s) => `var(--ui-color-neutral-${s})`
92
- const neutralLight = {
93
- 'text-dimmed': n(400),
94
- 'text-muted': n(500),
95
- 'text-toned': n(600),
96
- text: n(700),
97
- 'text-highlighted': n(900),
98
- 'text-inverted': '#fff',
99
- bg: '#fff',
100
- 'bg-muted': n(50),
101
- 'bg-elevated': n(100),
102
- 'bg-accented': n(200),
103
- 'bg-inverted': n(900),
104
- border: n(200),
105
- 'border-muted': n(200),
106
- 'border-accented': n(300),
107
- 'border-inverted': n(900),
108
- }
109
- // Dark surfaces on the kuiper hue (273). Cards sit one step above the
110
- // kuiper-900 canvas. The sidebar sits between the kuiper-950 navbar and the
111
- // canvas. The chart palette passes the dataviz checks on the card surface.
112
- const CARD_DARK = 'oklch(28% 0.042 273)'
113
- const SIDEBAR_DARK = 'oklch(20.5% 0.040 273)'
114
- const neutralDark = {
115
- 'text-dimmed': n(500),
116
- 'text-muted': n(400),
117
- 'text-toned': n(300),
118
- text: n(200),
119
- 'text-highlighted': '#fff',
120
- 'text-inverted': n(900),
121
- bg: CARD_DARK,
122
- 'bg-muted': n(800),
123
- 'bg-elevated': n(800),
124
- 'bg-accented': n(700),
125
- 'bg-inverted': '#fff',
126
- border: n(800),
127
- 'border-muted': n(700),
128
- 'border-accented': n(700),
129
- 'border-inverted': '#fff',
130
- }
131
- const declare = (o) =>
132
- Object.entries(o)
133
- .map(([k, val]) => ` --ui-${k}: ${val};`)
134
- .join('\n')
135
-
136
- // The chart series, in a fixed order: tholin, haze, lime, violet, teal, amber.
137
- // Validated with the dataviz palette checks (lightness band, chroma floor,
138
- // colorblind and normal-vision separation of neighbors, 3:1 contrast) on white
139
- // for light, and on the dark card surface for dark. Dark uses tholin 500, not
140
- // the primary 400, which is too light for the dark band. Re-run the checks
141
- // before you change a slot.
142
- const chartLight = [
143
- 'tholin-600',
144
- 'haze-600',
145
- 'lime-700',
146
- 'violet-500',
147
- 'teal-600',
148
- 'amber-600',
149
- ]
150
- const chartDark = [
151
- 'tholin-500',
152
- 'haze-500',
153
- 'lime-600',
154
- 'violet-500',
155
- 'teal-600',
156
- 'amber-600',
157
- ]
158
- // Slot 1 reads the primary scale (tholin 600 in light, 500 in dark), so a
159
- // brand primary (appConfig.pluto.brand) recolors it too.
160
- function chart(list, primaryStep) {
161
- return [
162
- ` --ui-chart-1: var(--ui-color-primary-${primaryStep}); /* ${list[0]} */`,
163
- ...list
164
- .slice(1)
165
- .map((c, i) => ` --ui-chart-${i + 2}: ${v(c)}; /* ${c} */`),
166
- ].join('\n')
167
- }
168
-
169
- const css = `/*
170
- * The Pluto admin theme.
171
- *
172
- * Two selectors carry it:
173
- * - \`:root[data-pluto-admin]\`: usePlutoAdminTheme() sets this attribute on
174
- * <html> while an admin layout is mounted, so the theme also covers
175
- * overlays (modals, slideovers, menus, toasts, the command palette) that
176
- * render at the end of <body>.
177
- * - \`[data-pluto-admin-scope]\`: for admin chrome that also shows on the
178
- * public site, such as the admin navbar for a logged-in admin.
179
- *
180
- * \`[data-pluto-admin-dark]\` takes the dark tokens in both color modes. The
181
- * admin navbar is near black in light mode too, so its text and buttons need
182
- * the dark values.
183
- *
184
- * The colors are the Pluto UI tokens (pluto-tokens.css): primary tholin,
185
- * secondary and info haze, neutral kuiper. The status colors come from
186
- * Tailwind: green, amber, rose. The fonts are Public Sans for text and
187
- * Fredoka for page titles.
188
- *
189
- * Every value is a literal. The consumer app styles its public site through
190
- * its own app.config colors and @theme. Both reach the admin unless the admin
191
- * pins its own values: app.config colors set Nuxt UI's --ui-color-* scales on
192
- * :root, and @theme can redefine a Tailwind color such as --color-red-400.
193
- * These selectors are more specific than Nuxt UI's :root and .dark rules.
194
- *
195
- * The semantic tokens (--ui-primary, --ui-bg, --ui-text, ...) are declared
196
- * again here, not only the color scales. A custom property inherits as a
197
- * resolved value, so on a scoped element the :root tokens would still hold
198
- * the app's colors.
199
- *
200
- * Chart colors are a validated categorical palette: lightness band, chroma
201
- * floor, colorblind separation, and 3:1 contrast pass on white (light) and
202
- * on the dark card surface (dark). This file is generated; keep the values in
203
- * sync with scripts/generate-admin-theme.cjs: run it from the repo root, never
204
- * edit this file by hand.
205
- */
206
- :root[data-pluto-admin],
207
- [data-pluto-admin-scope] {
208
- ${scales}
209
-
210
- ${semantic(lightSteps)}
211
-
212
- ${declare(neutralLight)}
213
-
214
- ${chart(chartLight, 600)}
215
-
216
- /* Surfaces. The navbar is near black in both modes. */
217
- --pluto-admin-canvas: #fff;
218
- --pluto-admin-sidebar: ${v('kuiper-50')};
219
- --pluto-admin-navbar: ${v('kuiper-950')};
220
-
221
- /* The Pluto fonts, as literals like the colors (see pluto-tokens.css). */
222
- --font-sans: "Public Sans", ui-sans-serif, system-ui, sans-serif;
223
- --pluto-admin-font-display: "Fredoka", "Public Sans", ui-sans-serif, system-ui, sans-serif;
224
- }
225
-
226
- :root[data-pluto-admin].dark,
227
- .dark [data-pluto-admin-scope],
228
- [data-pluto-admin-dark] {
229
- ${semantic(darkSteps)}
230
-
231
- ${declare(neutralDark)}
232
-
233
- ${chart(chartDark, 500)}
234
-
235
- /*
236
- * Four steps, darkest at the top: a near-black navbar, a darker sidebar,
237
- * a dim dark canvas (not pitch black), and cards (--ui-bg) one step above
238
- * the canvas.
239
- */
240
- --pluto-admin-navbar: ${v('kuiper-950')};
241
- --pluto-admin-sidebar: ${SIDEBAR_DARK};
242
- --pluto-admin-canvas: ${v('kuiper-900')};
243
- }
244
-
245
- :root[data-pluto-admin] body {
246
- background-color: var(--pluto-admin-canvas);
247
- }
248
-
249
- :root[data-pluto-admin] body,
250
- [data-pluto-admin-scope] {
251
- font-family: var(--font-sans);
252
- color: var(--ui-text);
253
- }
254
-
255
- /* Page titles (h1 only) use the rounded face of the wordmark, as on the docs site. */
256
- :root[data-pluto-admin] h1,
257
- [data-pluto-admin-scope] h1 {
258
- font-family: var(--pluto-admin-font-display);
259
- letter-spacing: -0.01em;
260
- }
261
- `
262
- fs.writeFileSync('app/assets/css/admin-theme.css', css)
263
- console.log('written', css.split('\n').length, 'lines')
package/tailwind.lint.css DELETED
@@ -1,10 +0,0 @@
1
- /*
2
- * The Tailwind design system for ESLint (better-tailwindcss) and the editor
3
- * (Tailwind IntelliSense). It is not part of the build: a Pluto layer has no
4
- * Tailwind entry, the app owns it (see the single-tailwind-build skill). This
5
- * file gives the lint the same theme as an app: Tailwind, Nuxt UI, and the
6
- * Pluto layer CSS (the Pluto UI tokens and the admin theme).
7
- */
8
- @import 'tailwindcss';
9
- @import '@nuxt/ui';
10
- @import './app/assets/css/pluto-layer.css';