@dscodotco/theme-presets 0.1.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/LICENSE +21 -0
- package/README.md +50 -0
- package/dist/index.cjs +218 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +50 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.js +188 -0
- package/dist/index.js.map +1 -0
- package/package.json +38 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Digital Sciences
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# @dscodotco/theme-presets
|
|
2
|
+
|
|
3
|
+
Combinable storefront theme presets for the RUO Pro / Flightdeck platform — a store's look decomposed into three independent axes, composed into DTCG-style `theme.tokens` the storefront's derivation engine consumes. Zero dependencies.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install @dscodotco/theme-presets
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## The three axes
|
|
10
|
+
|
|
11
|
+
1. **Palette** — the core color roles (`primary`, `accent`, `background`, `surface`, `surfaceMuted`, `text`, `muted`, `border`, `primaryForeground`); the derivation engine computes everything else. Eight palettes: `clinical`, `midnight`, `oceanic`, `warm-sand`, `luxe-mono`, `vivid`, `forest`, `paper-ink` (the RUO Pro brand identity — paper ground, ink primary, DSCO violet accent).
|
|
12
|
+
2. **Type** — a font pairing (heading + body + mono). Five sets: `grotesk`, `editorial`, `brutalist`, `humanist`, `dsco` (the platform's own face).
|
|
13
|
+
3. **Structure** — architectural variants read from the token tree: nav style (`classic` / `glass-pill`), hero style (`off` / `gradient` / `starfield`), footer style (`minimal` / `columns` / `centered`). Five named presets: `editorial-quiet`, `editorial-columns`, `bold-gradient`, `space-hero`, `classic-shop`.
|
|
14
|
+
|
|
15
|
+
Because the axes are independent, every combination is a coherent theme: 8 palettes × 5 type sets × 5 structures = 200 distinct, ready-to-ship looks with zero bespoke CSS.
|
|
16
|
+
|
|
17
|
+
## Compose one theme
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { composeThemeTokens } from "@dscodotco/theme-presets";
|
|
21
|
+
|
|
22
|
+
const tokens = composeThemeTokens({
|
|
23
|
+
palette: "midnight",
|
|
24
|
+
type: "grotesk",
|
|
25
|
+
structure: "space-hero",
|
|
26
|
+
});
|
|
27
|
+
// -> { color: {...}, font: {...}, nav: { style }, footer: { style }, hero: { style } }
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The result is a manifest `theme.tokens` object. A store can adopt a preset and still override any individual token on top. A structure with `hero: "off"` declares no hero style, so the renderer shows no backdrop — that is the hero toggle.
|
|
31
|
+
|
|
32
|
+
## The full matrix
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { themeMatrix } from "@dscodotco/theme-presets";
|
|
36
|
+
|
|
37
|
+
for (const { id, choice, tokens } of themeMatrix()) {
|
|
38
|
+
// id is stable, e.g. "warm-sand--editorial--editorial-quiet" — pin it per store
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Curated shortlist
|
|
43
|
+
|
|
44
|
+
`FEATURED_THEMES` is the named shortlist for the store-builder UI — "RUO Crystal", "Clinical Trust", "Midnight Lab", "Warm Apothecary", "Luxe Mono", "Vivid Drop", "Deep Ocean", "Field Notes" — each a `ThemeChoice` you can hand straight to `composeThemeTokens`.
|
|
45
|
+
|
|
46
|
+
The raw axes are exported too (`PALETTES`, `TYPE_SETS`, `STRUCTURES`) along with their id types (`PaletteId`, `TypeId`, `NavStyleId`, `HeroStyleId`, `FooterStyleId`, `StructurePreset`, `ThemeChoice`), so a builder UI can enumerate options without hardcoding them.
|
|
47
|
+
|
|
48
|
+
## Status
|
|
49
|
+
|
|
50
|
+
Alpha (0.x). Palettes are contrast-checked against the storefront's WCAG AA floor (see the `oceanic` note in the source).
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
FEATURED_THEMES: () => FEATURED_THEMES,
|
|
24
|
+
PALETTES: () => PALETTES,
|
|
25
|
+
STRUCTURES: () => STRUCTURES,
|
|
26
|
+
TYPE_SETS: () => TYPE_SETS,
|
|
27
|
+
composeThemeTokens: () => composeThemeTokens,
|
|
28
|
+
themeMatrix: () => themeMatrix
|
|
29
|
+
});
|
|
30
|
+
module.exports = __toCommonJS(index_exports);
|
|
31
|
+
var color = (value) => ({ $type: "color", $value: value });
|
|
32
|
+
var font = (value) => ({ $type: "fontFamily", $value: value });
|
|
33
|
+
var raw = (value) => ({ $value: value });
|
|
34
|
+
var PALETTES = {
|
|
35
|
+
clinical: {
|
|
36
|
+
primary: color("#1e6fd9"),
|
|
37
|
+
primaryForeground: color("#ffffff"),
|
|
38
|
+
accent: color("#12b5b0"),
|
|
39
|
+
background: color("#f8fafc"),
|
|
40
|
+
surface: color("#ffffff"),
|
|
41
|
+
surfaceMuted: color("#eef2f7"),
|
|
42
|
+
text: color("#0f172a"),
|
|
43
|
+
muted: color("#64748b"),
|
|
44
|
+
border: color("#dbe3ec")
|
|
45
|
+
},
|
|
46
|
+
midnight: {
|
|
47
|
+
primary: color("#7c8bff"),
|
|
48
|
+
primaryForeground: color("#0b0f1e"),
|
|
49
|
+
accent: color("#22d3ee"),
|
|
50
|
+
background: color("#070a14"),
|
|
51
|
+
surface: color("#0e1424"),
|
|
52
|
+
surfaceMuted: color("#161f36"),
|
|
53
|
+
text: color("#eaf0ff"),
|
|
54
|
+
muted: color("#8794b5"),
|
|
55
|
+
border: color("#1e2a44")
|
|
56
|
+
},
|
|
57
|
+
oceanic: {
|
|
58
|
+
// #0891b2 → #0e7490: the lighter teal held only 3.54:1 against the
|
|
59
|
+
// near-white primaryForeground — under the WCAG AA 4.5:1 body-text floor
|
|
60
|
+
// pinned by surfaces/storefront/src/lib/theme-contrast.test.ts. One step
|
|
61
|
+
// darker on the same hue clears it at 5.15:1.
|
|
62
|
+
primary: color("#0e7490"),
|
|
63
|
+
primaryForeground: color("#f0fdff"),
|
|
64
|
+
accent: color("#3b82f6"),
|
|
65
|
+
background: color("#031b23"),
|
|
66
|
+
surface: color("#062b36"),
|
|
67
|
+
surfaceMuted: color("#0a3a49"),
|
|
68
|
+
text: color("#e6fbff"),
|
|
69
|
+
muted: color("#7fb6c4"),
|
|
70
|
+
border: color("#0e4b5e")
|
|
71
|
+
},
|
|
72
|
+
"warm-sand": {
|
|
73
|
+
primary: color("#a8340f"),
|
|
74
|
+
primaryForeground: color("#fff8f1"),
|
|
75
|
+
accent: color("#f29131"),
|
|
76
|
+
background: color("#f9f6f1"),
|
|
77
|
+
surface: color("#fbf9f4"),
|
|
78
|
+
surfaceMuted: color("#f0e9dd"),
|
|
79
|
+
text: color("#1a1614"),
|
|
80
|
+
muted: color("#7a7165"),
|
|
81
|
+
border: color("#e3d9c8")
|
|
82
|
+
},
|
|
83
|
+
"luxe-mono": {
|
|
84
|
+
primary: color("#111111"),
|
|
85
|
+
primaryForeground: color("#ffffff"),
|
|
86
|
+
accent: color("#c8a24a"),
|
|
87
|
+
background: color("#ffffff"),
|
|
88
|
+
surface: color("#fafafa"),
|
|
89
|
+
surfaceMuted: color("#f0f0f0"),
|
|
90
|
+
text: color("#0a0a0a"),
|
|
91
|
+
muted: color("#6b6b6b"),
|
|
92
|
+
border: color("#e5e5e5")
|
|
93
|
+
},
|
|
94
|
+
vivid: {
|
|
95
|
+
primary: color("#7c3aed"),
|
|
96
|
+
primaryForeground: color("#ffffff"),
|
|
97
|
+
accent: color("#ec4899"),
|
|
98
|
+
background: color("#0a0713"),
|
|
99
|
+
surface: color("#150f26"),
|
|
100
|
+
surfaceMuted: color("#221838"),
|
|
101
|
+
text: color("#f6f2ff"),
|
|
102
|
+
muted: color("#a091c0"),
|
|
103
|
+
border: color("#2e2149")
|
|
104
|
+
},
|
|
105
|
+
forest: {
|
|
106
|
+
primary: color("#15803d"),
|
|
107
|
+
primaryForeground: color("#f0fff4"),
|
|
108
|
+
accent: color("#ca8a04"),
|
|
109
|
+
background: color("#f4f8f2"),
|
|
110
|
+
surface: color("#ffffff"),
|
|
111
|
+
surfaceMuted: color("#e7f0e6"),
|
|
112
|
+
text: color("#14231a"),
|
|
113
|
+
muted: color("#5c6f60"),
|
|
114
|
+
border: color("#d2e2d0")
|
|
115
|
+
},
|
|
116
|
+
// The RUO Pro brand identity (design/RUO_Pro_Final): warm paper ground,
|
|
117
|
+
// near-black ink, DSCO violet as the single accent. Primary is the INK
|
|
118
|
+
// (buttons are dark like the reference site's), violet carries emphasis.
|
|
119
|
+
"paper-ink": {
|
|
120
|
+
primary: color("#080808"),
|
|
121
|
+
primaryForeground: color("#f5f4f0"),
|
|
122
|
+
accent: color("#6254ff"),
|
|
123
|
+
background: color("#f5f4f0"),
|
|
124
|
+
surface: color("#fbfaf7"),
|
|
125
|
+
surfaceMuted: color("#ecebe4"),
|
|
126
|
+
text: color("#080808"),
|
|
127
|
+
muted: color("#5b5b56"),
|
|
128
|
+
border: color("#dbd9d0")
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
var MONO = font("var(--font-jetbrains-mono), 'JetBrains Mono', ui-monospace, monospace");
|
|
132
|
+
var TYPE_SETS = {
|
|
133
|
+
grotesk: {
|
|
134
|
+
heading: font("var(--font-space-grotesk), 'Space Grotesk', system-ui, sans-serif"),
|
|
135
|
+
body: font("var(--font-inter), Inter, system-ui, sans-serif"),
|
|
136
|
+
mono: MONO
|
|
137
|
+
},
|
|
138
|
+
editorial: {
|
|
139
|
+
heading: font("var(--font-fraunces), 'Fraunces', Georgia, serif"),
|
|
140
|
+
body: font("var(--font-inter), Inter, system-ui, sans-serif"),
|
|
141
|
+
mono: MONO
|
|
142
|
+
},
|
|
143
|
+
brutalist: {
|
|
144
|
+
heading: font("var(--font-archivo-black), 'Arial Black', system-ui, sans-serif"),
|
|
145
|
+
body: font("var(--font-inter), Inter, system-ui, sans-serif"),
|
|
146
|
+
mono: MONO
|
|
147
|
+
},
|
|
148
|
+
humanist: {
|
|
149
|
+
heading: font("var(--font-inter), Inter, system-ui, sans-serif"),
|
|
150
|
+
body: font("var(--font-inter), Inter, system-ui, sans-serif"),
|
|
151
|
+
mono: MONO
|
|
152
|
+
},
|
|
153
|
+
// DSCO is the platform's own face (Arimo/Liberation Sans under SIL OFL,
|
|
154
|
+
// shipped by the storefront at /brand with its license file). One family
|
|
155
|
+
// for heading and body — the brand look is carried by size and tracking.
|
|
156
|
+
dsco: {
|
|
157
|
+
heading: font("DSCO, Arimo, 'Liberation Sans', Arial, sans-serif"),
|
|
158
|
+
body: font("DSCO, Arimo, 'Liberation Sans', Arial, sans-serif"),
|
|
159
|
+
mono: MONO
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
var STRUCTURES = {
|
|
163
|
+
"editorial-quiet": { nav: "classic", hero: "off", footer: "minimal" },
|
|
164
|
+
"editorial-columns": { nav: "classic", hero: "off", footer: "columns" },
|
|
165
|
+
"bold-gradient": { nav: "glass-pill", hero: "gradient", footer: "columns" },
|
|
166
|
+
"space-hero": { nav: "glass-pill", hero: "starfield", footer: "centered" },
|
|
167
|
+
"classic-shop": { nav: "classic", hero: "gradient", footer: "columns" }
|
|
168
|
+
};
|
|
169
|
+
function composeThemeTokens(choice) {
|
|
170
|
+
const structure = STRUCTURES[choice.structure];
|
|
171
|
+
if (!structure) throw new Error(`unknown structure preset: ${choice.structure}`);
|
|
172
|
+
const tokens = {
|
|
173
|
+
color: { ...PALETTES[choice.palette] },
|
|
174
|
+
font: { ...TYPE_SETS[choice.type] },
|
|
175
|
+
nav: { style: raw(structure.nav) },
|
|
176
|
+
footer: { style: raw(structure.footer) }
|
|
177
|
+
};
|
|
178
|
+
if (structure.hero !== "off") {
|
|
179
|
+
tokens.hero = { style: raw(structure.hero) };
|
|
180
|
+
}
|
|
181
|
+
return tokens;
|
|
182
|
+
}
|
|
183
|
+
function themeMatrix() {
|
|
184
|
+
const out = [];
|
|
185
|
+
for (const palette of Object.keys(PALETTES)) {
|
|
186
|
+
for (const type of Object.keys(TYPE_SETS)) {
|
|
187
|
+
for (const structure of Object.keys(STRUCTURES)) {
|
|
188
|
+
const choice = { palette, type, structure };
|
|
189
|
+
out.push({
|
|
190
|
+
id: `${palette}--${type}--${structure}`,
|
|
191
|
+
choice,
|
|
192
|
+
tokens: composeThemeTokens(choice)
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return out;
|
|
198
|
+
}
|
|
199
|
+
var FEATURED_THEMES = {
|
|
200
|
+
"RUO Crystal": { palette: "paper-ink", type: "dsco", structure: "editorial-columns" },
|
|
201
|
+
"Clinical Trust": { palette: "clinical", type: "grotesk", structure: "classic-shop" },
|
|
202
|
+
"Midnight Lab": { palette: "midnight", type: "grotesk", structure: "space-hero" },
|
|
203
|
+
"Warm Apothecary": { palette: "warm-sand", type: "editorial", structure: "editorial-quiet" },
|
|
204
|
+
"Luxe Mono": { palette: "luxe-mono", type: "editorial", structure: "editorial-quiet" },
|
|
205
|
+
"Vivid Drop": { palette: "vivid", type: "brutalist", structure: "bold-gradient" },
|
|
206
|
+
"Deep Ocean": { palette: "oceanic", type: "humanist", structure: "space-hero" },
|
|
207
|
+
"Field Notes": { palette: "forest", type: "humanist", structure: "classic-shop" }
|
|
208
|
+
};
|
|
209
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
210
|
+
0 && (module.exports = {
|
|
211
|
+
FEATURED_THEMES,
|
|
212
|
+
PALETTES,
|
|
213
|
+
STRUCTURES,
|
|
214
|
+
TYPE_SETS,
|
|
215
|
+
composeThemeTokens,
|
|
216
|
+
themeMatrix
|
|
217
|
+
});
|
|
218
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Theme presets + a combinable matrix (FD theming).\n *\n * A store's look is three independent axes composed into the manifest\n * `theme.tokens` the derivation engine (`lib/theme.ts`) already consumes:\n * 1. PALETTE — the core color roles (primary/accent/background/…)\n * 2. TYPE — a font pairing (heading + body)\n * 3. STRUCTURE — architectural variants read from the token tree\n * (nav / hero / footer style; hero = null turns the hero off)\n *\n * Because the axes are independent, `themeMatrix()` yields every combination —\n * a few palettes × a few type sets × a few structures already gives hundreds\n * of distinct, on-brand looks with zero bespoke CSS. `composeThemeTokens()`\n * builds one; a store can adopt a named preset and still override any token.\n */\n\ntype Dtcg = Record<string, unknown>;\nconst color = (value: string): Dtcg => ({ $type: \"color\", $value: value });\nconst font = (value: string): Dtcg => ({ $type: \"fontFamily\", $value: value });\nconst raw = (value: string): Dtcg => ({ $value: value });\n\n// ── Axis 1: PALETTE (core color roles; the engine derives the rest) ────────\n\nexport type PaletteId =\n | \"clinical\"\n | \"midnight\"\n | \"oceanic\"\n | \"warm-sand\"\n | \"luxe-mono\"\n | \"vivid\"\n | \"forest\"\n | \"paper-ink\";\n\nexport const PALETTES: Record<PaletteId, Dtcg> = {\n clinical: {\n primary: color(\"#1e6fd9\"),\n primaryForeground: color(\"#ffffff\"),\n accent: color(\"#12b5b0\"),\n background: color(\"#f8fafc\"),\n surface: color(\"#ffffff\"),\n surfaceMuted: color(\"#eef2f7\"),\n text: color(\"#0f172a\"),\n muted: color(\"#64748b\"),\n border: color(\"#dbe3ec\"),\n },\n midnight: {\n primary: color(\"#7c8bff\"),\n primaryForeground: color(\"#0b0f1e\"),\n accent: color(\"#22d3ee\"),\n background: color(\"#070a14\"),\n surface: color(\"#0e1424\"),\n surfaceMuted: color(\"#161f36\"),\n text: color(\"#eaf0ff\"),\n muted: color(\"#8794b5\"),\n border: color(\"#1e2a44\"),\n },\n oceanic: {\n // #0891b2 → #0e7490: the lighter teal held only 3.54:1 against the\n // near-white primaryForeground — under the WCAG AA 4.5:1 body-text floor\n // pinned by surfaces/storefront/src/lib/theme-contrast.test.ts. One step\n // darker on the same hue clears it at 5.15:1.\n primary: color(\"#0e7490\"),\n primaryForeground: color(\"#f0fdff\"),\n accent: color(\"#3b82f6\"),\n background: color(\"#031b23\"),\n surface: color(\"#062b36\"),\n surfaceMuted: color(\"#0a3a49\"),\n text: color(\"#e6fbff\"),\n muted: color(\"#7fb6c4\"),\n border: color(\"#0e4b5e\"),\n },\n \"warm-sand\": {\n primary: color(\"#a8340f\"),\n primaryForeground: color(\"#fff8f1\"),\n accent: color(\"#f29131\"),\n background: color(\"#f9f6f1\"),\n surface: color(\"#fbf9f4\"),\n surfaceMuted: color(\"#f0e9dd\"),\n text: color(\"#1a1614\"),\n muted: color(\"#7a7165\"),\n border: color(\"#e3d9c8\"),\n },\n \"luxe-mono\": {\n primary: color(\"#111111\"),\n primaryForeground: color(\"#ffffff\"),\n accent: color(\"#c8a24a\"),\n background: color(\"#ffffff\"),\n surface: color(\"#fafafa\"),\n surfaceMuted: color(\"#f0f0f0\"),\n text: color(\"#0a0a0a\"),\n muted: color(\"#6b6b6b\"),\n border: color(\"#e5e5e5\"),\n },\n vivid: {\n primary: color(\"#7c3aed\"),\n primaryForeground: color(\"#ffffff\"),\n accent: color(\"#ec4899\"),\n background: color(\"#0a0713\"),\n surface: color(\"#150f26\"),\n surfaceMuted: color(\"#221838\"),\n text: color(\"#f6f2ff\"),\n muted: color(\"#a091c0\"),\n border: color(\"#2e2149\"),\n },\n forest: {\n primary: color(\"#15803d\"),\n primaryForeground: color(\"#f0fff4\"),\n accent: color(\"#ca8a04\"),\n background: color(\"#f4f8f2\"),\n surface: color(\"#ffffff\"),\n surfaceMuted: color(\"#e7f0e6\"),\n text: color(\"#14231a\"),\n muted: color(\"#5c6f60\"),\n border: color(\"#d2e2d0\"),\n },\n // The RUO Pro brand identity (design/RUO_Pro_Final): warm paper ground,\n // near-black ink, DSCO violet as the single accent. Primary is the INK\n // (buttons are dark like the reference site's), violet carries emphasis.\n \"paper-ink\": {\n primary: color(\"#080808\"),\n primaryForeground: color(\"#f5f4f0\"),\n accent: color(\"#6254ff\"),\n background: color(\"#f5f4f0\"),\n surface: color(\"#fbfaf7\"),\n surfaceMuted: color(\"#ecebe4\"),\n text: color(\"#080808\"),\n muted: color(\"#5b5b56\"),\n border: color(\"#dbd9d0\"),\n },\n};\n\n// ── Axis 2: TYPE (font pairings) ───────────────────────────────────────────\n\nexport type TypeId = \"grotesk\" | \"editorial\" | \"brutalist\" | \"humanist\" | \"dsco\";\n\nconst MONO = font(\"var(--font-jetbrains-mono), 'JetBrains Mono', ui-monospace, monospace\");\n\nexport const TYPE_SETS: Record<TypeId, Dtcg> = {\n grotesk: {\n heading: font(\"var(--font-space-grotesk), 'Space Grotesk', system-ui, sans-serif\"),\n body: font(\"var(--font-inter), Inter, system-ui, sans-serif\"),\n mono: MONO,\n },\n editorial: {\n heading: font(\"var(--font-fraunces), 'Fraunces', Georgia, serif\"),\n body: font(\"var(--font-inter), Inter, system-ui, sans-serif\"),\n mono: MONO,\n },\n brutalist: {\n heading: font(\"var(--font-archivo-black), 'Arial Black', system-ui, sans-serif\"),\n body: font(\"var(--font-inter), Inter, system-ui, sans-serif\"),\n mono: MONO,\n },\n humanist: {\n heading: font(\"var(--font-inter), Inter, system-ui, sans-serif\"),\n body: font(\"var(--font-inter), Inter, system-ui, sans-serif\"),\n mono: MONO,\n },\n // DSCO is the platform's own face (Arimo/Liberation Sans under SIL OFL,\n // shipped by the storefront at /brand with its license file). One family\n // for heading and body — the brand look is carried by size and tracking.\n dsco: {\n heading: font(\"DSCO, Arimo, 'Liberation Sans', Arial, sans-serif\"),\n body: font(\"DSCO, Arimo, 'Liberation Sans', Arial, sans-serif\"),\n mono: MONO,\n },\n};\n\n// ── Axis 3: STRUCTURE (architectural variants, read from the token tree) ────\n\nexport type NavStyleId = \"classic\" | \"glass-pill\";\nexport type HeroStyleId = \"off\" | \"gradient\" | \"starfield\";\nexport type FooterStyleId = \"minimal\" | \"columns\" | \"centered\";\n\nexport interface StructurePreset {\n nav: NavStyleId;\n hero: HeroStyleId;\n footer: FooterStyleId;\n}\n\nexport const STRUCTURES: Record<string, StructurePreset> = {\n \"editorial-quiet\": { nav: \"classic\", hero: \"off\", footer: \"minimal\" },\n \"editorial-columns\": { nav: \"classic\", hero: \"off\", footer: \"columns\" },\n \"bold-gradient\": { nav: \"glass-pill\", hero: \"gradient\", footer: \"columns\" },\n \"space-hero\": { nav: \"glass-pill\", hero: \"starfield\", footer: \"centered\" },\n \"classic-shop\": { nav: \"classic\", hero: \"gradient\", footer: \"columns\" },\n};\n\n// ── Composition ─────────────────────────────────────────────────────────────\n\nexport interface ThemeChoice {\n palette: PaletteId;\n type: TypeId;\n structure: keyof typeof STRUCTURES;\n}\n\n/** Build a manifest `theme.tokens` object from a palette/type/structure choice. */\nexport function composeThemeTokens(choice: ThemeChoice): Dtcg {\n const structure = STRUCTURES[choice.structure];\n if (!structure) throw new Error(`unknown structure preset: ${choice.structure}`);\n const tokens: Dtcg = {\n color: { ...PALETTES[choice.palette] },\n font: { ...TYPE_SETS[choice.type] },\n nav: { style: raw(structure.nav) },\n footer: { style: raw(structure.footer) },\n };\n // hero \"off\" means: declare no hero style, so the renderer shows no backdrop\n // (the hero section, if present, degrades to a plain band — the toggle).\n if (structure.hero !== \"off\") {\n (tokens as { hero?: Dtcg }).hero = { style: raw(structure.hero) };\n }\n return tokens;\n}\n\n/**\n * The full combinable matrix — every palette × type × structure. With the\n * current axes that's 8 × 5 × 5 = 200 distinct, ready-to-ship themes; add one\n * palette and it's 225. Each entry has a stable id you can pin per store.\n */\nexport function themeMatrix(): Array<{ id: string; choice: ThemeChoice; tokens: Dtcg }> {\n const out: Array<{ id: string; choice: ThemeChoice; tokens: Dtcg }> = [];\n for (const palette of Object.keys(PALETTES) as PaletteId[]) {\n for (const type of Object.keys(TYPE_SETS) as TypeId[]) {\n for (const structure of Object.keys(STRUCTURES)) {\n const choice: ThemeChoice = { palette, type, structure };\n out.push({\n id: `${palette}--${type}--${structure}`,\n choice,\n tokens: composeThemeTokens(choice),\n });\n }\n }\n }\n return out;\n}\n\n/** A curated, named shortlist for the store-builder UI (the \"featured\" themes). */\nexport const FEATURED_THEMES: Record<string, ThemeChoice> = {\n \"RUO Crystal\": { palette: \"paper-ink\", type: \"dsco\", structure: \"editorial-columns\" },\n \"Clinical Trust\": { palette: \"clinical\", type: \"grotesk\", structure: \"classic-shop\" },\n \"Midnight Lab\": { palette: \"midnight\", type: \"grotesk\", structure: \"space-hero\" },\n \"Warm Apothecary\": { palette: \"warm-sand\", type: \"editorial\", structure: \"editorial-quiet\" },\n \"Luxe Mono\": { palette: \"luxe-mono\", type: \"editorial\", structure: \"editorial-quiet\" },\n \"Vivid Drop\": { palette: \"vivid\", type: \"brutalist\", structure: \"bold-gradient\" },\n \"Deep Ocean\": { palette: \"oceanic\", type: \"humanist\", structure: \"space-hero\" },\n \"Field Notes\": { palette: \"forest\", type: \"humanist\", structure: \"classic-shop\" },\n};\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme presets + a combinable matrix (FD theming).
|
|
3
|
+
*
|
|
4
|
+
* A store's look is three independent axes composed into the manifest
|
|
5
|
+
* `theme.tokens` the derivation engine (`lib/theme.ts`) already consumes:
|
|
6
|
+
* 1. PALETTE — the core color roles (primary/accent/background/…)
|
|
7
|
+
* 2. TYPE — a font pairing (heading + body)
|
|
8
|
+
* 3. STRUCTURE — architectural variants read from the token tree
|
|
9
|
+
* (nav / hero / footer style; hero = null turns the hero off)
|
|
10
|
+
*
|
|
11
|
+
* Because the axes are independent, `themeMatrix()` yields every combination —
|
|
12
|
+
* a few palettes × a few type sets × a few structures already gives hundreds
|
|
13
|
+
* of distinct, on-brand looks with zero bespoke CSS. `composeThemeTokens()`
|
|
14
|
+
* builds one; a store can adopt a named preset and still override any token.
|
|
15
|
+
*/
|
|
16
|
+
type Dtcg = Record<string, unknown>;
|
|
17
|
+
type PaletteId = "clinical" | "midnight" | "oceanic" | "warm-sand" | "luxe-mono" | "vivid" | "forest" | "paper-ink";
|
|
18
|
+
declare const PALETTES: Record<PaletteId, Dtcg>;
|
|
19
|
+
type TypeId = "grotesk" | "editorial" | "brutalist" | "humanist" | "dsco";
|
|
20
|
+
declare const TYPE_SETS: Record<TypeId, Dtcg>;
|
|
21
|
+
type NavStyleId = "classic" | "glass-pill";
|
|
22
|
+
type HeroStyleId = "off" | "gradient" | "starfield";
|
|
23
|
+
type FooterStyleId = "minimal" | "columns" | "centered";
|
|
24
|
+
interface StructurePreset {
|
|
25
|
+
nav: NavStyleId;
|
|
26
|
+
hero: HeroStyleId;
|
|
27
|
+
footer: FooterStyleId;
|
|
28
|
+
}
|
|
29
|
+
declare const STRUCTURES: Record<string, StructurePreset>;
|
|
30
|
+
interface ThemeChoice {
|
|
31
|
+
palette: PaletteId;
|
|
32
|
+
type: TypeId;
|
|
33
|
+
structure: keyof typeof STRUCTURES;
|
|
34
|
+
}
|
|
35
|
+
/** Build a manifest `theme.tokens` object from a palette/type/structure choice. */
|
|
36
|
+
declare function composeThemeTokens(choice: ThemeChoice): Dtcg;
|
|
37
|
+
/**
|
|
38
|
+
* The full combinable matrix — every palette × type × structure. With the
|
|
39
|
+
* current axes that's 8 × 5 × 5 = 200 distinct, ready-to-ship themes; add one
|
|
40
|
+
* palette and it's 225. Each entry has a stable id you can pin per store.
|
|
41
|
+
*/
|
|
42
|
+
declare function themeMatrix(): Array<{
|
|
43
|
+
id: string;
|
|
44
|
+
choice: ThemeChoice;
|
|
45
|
+
tokens: Dtcg;
|
|
46
|
+
}>;
|
|
47
|
+
/** A curated, named shortlist for the store-builder UI (the "featured" themes). */
|
|
48
|
+
declare const FEATURED_THEMES: Record<string, ThemeChoice>;
|
|
49
|
+
|
|
50
|
+
export { FEATURED_THEMES, type FooterStyleId, type HeroStyleId, type NavStyleId, PALETTES, type PaletteId, STRUCTURES, type StructurePreset, TYPE_SETS, type ThemeChoice, type TypeId, composeThemeTokens, themeMatrix };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme presets + a combinable matrix (FD theming).
|
|
3
|
+
*
|
|
4
|
+
* A store's look is three independent axes composed into the manifest
|
|
5
|
+
* `theme.tokens` the derivation engine (`lib/theme.ts`) already consumes:
|
|
6
|
+
* 1. PALETTE — the core color roles (primary/accent/background/…)
|
|
7
|
+
* 2. TYPE — a font pairing (heading + body)
|
|
8
|
+
* 3. STRUCTURE — architectural variants read from the token tree
|
|
9
|
+
* (nav / hero / footer style; hero = null turns the hero off)
|
|
10
|
+
*
|
|
11
|
+
* Because the axes are independent, `themeMatrix()` yields every combination —
|
|
12
|
+
* a few palettes × a few type sets × a few structures already gives hundreds
|
|
13
|
+
* of distinct, on-brand looks with zero bespoke CSS. `composeThemeTokens()`
|
|
14
|
+
* builds one; a store can adopt a named preset and still override any token.
|
|
15
|
+
*/
|
|
16
|
+
type Dtcg = Record<string, unknown>;
|
|
17
|
+
type PaletteId = "clinical" | "midnight" | "oceanic" | "warm-sand" | "luxe-mono" | "vivid" | "forest" | "paper-ink";
|
|
18
|
+
declare const PALETTES: Record<PaletteId, Dtcg>;
|
|
19
|
+
type TypeId = "grotesk" | "editorial" | "brutalist" | "humanist" | "dsco";
|
|
20
|
+
declare const TYPE_SETS: Record<TypeId, Dtcg>;
|
|
21
|
+
type NavStyleId = "classic" | "glass-pill";
|
|
22
|
+
type HeroStyleId = "off" | "gradient" | "starfield";
|
|
23
|
+
type FooterStyleId = "minimal" | "columns" | "centered";
|
|
24
|
+
interface StructurePreset {
|
|
25
|
+
nav: NavStyleId;
|
|
26
|
+
hero: HeroStyleId;
|
|
27
|
+
footer: FooterStyleId;
|
|
28
|
+
}
|
|
29
|
+
declare const STRUCTURES: Record<string, StructurePreset>;
|
|
30
|
+
interface ThemeChoice {
|
|
31
|
+
palette: PaletteId;
|
|
32
|
+
type: TypeId;
|
|
33
|
+
structure: keyof typeof STRUCTURES;
|
|
34
|
+
}
|
|
35
|
+
/** Build a manifest `theme.tokens` object from a palette/type/structure choice. */
|
|
36
|
+
declare function composeThemeTokens(choice: ThemeChoice): Dtcg;
|
|
37
|
+
/**
|
|
38
|
+
* The full combinable matrix — every palette × type × structure. With the
|
|
39
|
+
* current axes that's 8 × 5 × 5 = 200 distinct, ready-to-ship themes; add one
|
|
40
|
+
* palette and it's 225. Each entry has a stable id you can pin per store.
|
|
41
|
+
*/
|
|
42
|
+
declare function themeMatrix(): Array<{
|
|
43
|
+
id: string;
|
|
44
|
+
choice: ThemeChoice;
|
|
45
|
+
tokens: Dtcg;
|
|
46
|
+
}>;
|
|
47
|
+
/** A curated, named shortlist for the store-builder UI (the "featured" themes). */
|
|
48
|
+
declare const FEATURED_THEMES: Record<string, ThemeChoice>;
|
|
49
|
+
|
|
50
|
+
export { FEATURED_THEMES, type FooterStyleId, type HeroStyleId, type NavStyleId, PALETTES, type PaletteId, STRUCTURES, type StructurePreset, TYPE_SETS, type ThemeChoice, type TypeId, composeThemeTokens, themeMatrix };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
var color = (value) => ({ $type: "color", $value: value });
|
|
3
|
+
var font = (value) => ({ $type: "fontFamily", $value: value });
|
|
4
|
+
var raw = (value) => ({ $value: value });
|
|
5
|
+
var PALETTES = {
|
|
6
|
+
clinical: {
|
|
7
|
+
primary: color("#1e6fd9"),
|
|
8
|
+
primaryForeground: color("#ffffff"),
|
|
9
|
+
accent: color("#12b5b0"),
|
|
10
|
+
background: color("#f8fafc"),
|
|
11
|
+
surface: color("#ffffff"),
|
|
12
|
+
surfaceMuted: color("#eef2f7"),
|
|
13
|
+
text: color("#0f172a"),
|
|
14
|
+
muted: color("#64748b"),
|
|
15
|
+
border: color("#dbe3ec")
|
|
16
|
+
},
|
|
17
|
+
midnight: {
|
|
18
|
+
primary: color("#7c8bff"),
|
|
19
|
+
primaryForeground: color("#0b0f1e"),
|
|
20
|
+
accent: color("#22d3ee"),
|
|
21
|
+
background: color("#070a14"),
|
|
22
|
+
surface: color("#0e1424"),
|
|
23
|
+
surfaceMuted: color("#161f36"),
|
|
24
|
+
text: color("#eaf0ff"),
|
|
25
|
+
muted: color("#8794b5"),
|
|
26
|
+
border: color("#1e2a44")
|
|
27
|
+
},
|
|
28
|
+
oceanic: {
|
|
29
|
+
// #0891b2 → #0e7490: the lighter teal held only 3.54:1 against the
|
|
30
|
+
// near-white primaryForeground — under the WCAG AA 4.5:1 body-text floor
|
|
31
|
+
// pinned by surfaces/storefront/src/lib/theme-contrast.test.ts. One step
|
|
32
|
+
// darker on the same hue clears it at 5.15:1.
|
|
33
|
+
primary: color("#0e7490"),
|
|
34
|
+
primaryForeground: color("#f0fdff"),
|
|
35
|
+
accent: color("#3b82f6"),
|
|
36
|
+
background: color("#031b23"),
|
|
37
|
+
surface: color("#062b36"),
|
|
38
|
+
surfaceMuted: color("#0a3a49"),
|
|
39
|
+
text: color("#e6fbff"),
|
|
40
|
+
muted: color("#7fb6c4"),
|
|
41
|
+
border: color("#0e4b5e")
|
|
42
|
+
},
|
|
43
|
+
"warm-sand": {
|
|
44
|
+
primary: color("#a8340f"),
|
|
45
|
+
primaryForeground: color("#fff8f1"),
|
|
46
|
+
accent: color("#f29131"),
|
|
47
|
+
background: color("#f9f6f1"),
|
|
48
|
+
surface: color("#fbf9f4"),
|
|
49
|
+
surfaceMuted: color("#f0e9dd"),
|
|
50
|
+
text: color("#1a1614"),
|
|
51
|
+
muted: color("#7a7165"),
|
|
52
|
+
border: color("#e3d9c8")
|
|
53
|
+
},
|
|
54
|
+
"luxe-mono": {
|
|
55
|
+
primary: color("#111111"),
|
|
56
|
+
primaryForeground: color("#ffffff"),
|
|
57
|
+
accent: color("#c8a24a"),
|
|
58
|
+
background: color("#ffffff"),
|
|
59
|
+
surface: color("#fafafa"),
|
|
60
|
+
surfaceMuted: color("#f0f0f0"),
|
|
61
|
+
text: color("#0a0a0a"),
|
|
62
|
+
muted: color("#6b6b6b"),
|
|
63
|
+
border: color("#e5e5e5")
|
|
64
|
+
},
|
|
65
|
+
vivid: {
|
|
66
|
+
primary: color("#7c3aed"),
|
|
67
|
+
primaryForeground: color("#ffffff"),
|
|
68
|
+
accent: color("#ec4899"),
|
|
69
|
+
background: color("#0a0713"),
|
|
70
|
+
surface: color("#150f26"),
|
|
71
|
+
surfaceMuted: color("#221838"),
|
|
72
|
+
text: color("#f6f2ff"),
|
|
73
|
+
muted: color("#a091c0"),
|
|
74
|
+
border: color("#2e2149")
|
|
75
|
+
},
|
|
76
|
+
forest: {
|
|
77
|
+
primary: color("#15803d"),
|
|
78
|
+
primaryForeground: color("#f0fff4"),
|
|
79
|
+
accent: color("#ca8a04"),
|
|
80
|
+
background: color("#f4f8f2"),
|
|
81
|
+
surface: color("#ffffff"),
|
|
82
|
+
surfaceMuted: color("#e7f0e6"),
|
|
83
|
+
text: color("#14231a"),
|
|
84
|
+
muted: color("#5c6f60"),
|
|
85
|
+
border: color("#d2e2d0")
|
|
86
|
+
},
|
|
87
|
+
// The RUO Pro brand identity (design/RUO_Pro_Final): warm paper ground,
|
|
88
|
+
// near-black ink, DSCO violet as the single accent. Primary is the INK
|
|
89
|
+
// (buttons are dark like the reference site's), violet carries emphasis.
|
|
90
|
+
"paper-ink": {
|
|
91
|
+
primary: color("#080808"),
|
|
92
|
+
primaryForeground: color("#f5f4f0"),
|
|
93
|
+
accent: color("#6254ff"),
|
|
94
|
+
background: color("#f5f4f0"),
|
|
95
|
+
surface: color("#fbfaf7"),
|
|
96
|
+
surfaceMuted: color("#ecebe4"),
|
|
97
|
+
text: color("#080808"),
|
|
98
|
+
muted: color("#5b5b56"),
|
|
99
|
+
border: color("#dbd9d0")
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
var MONO = font("var(--font-jetbrains-mono), 'JetBrains Mono', ui-monospace, monospace");
|
|
103
|
+
var TYPE_SETS = {
|
|
104
|
+
grotesk: {
|
|
105
|
+
heading: font("var(--font-space-grotesk), 'Space Grotesk', system-ui, sans-serif"),
|
|
106
|
+
body: font("var(--font-inter), Inter, system-ui, sans-serif"),
|
|
107
|
+
mono: MONO
|
|
108
|
+
},
|
|
109
|
+
editorial: {
|
|
110
|
+
heading: font("var(--font-fraunces), 'Fraunces', Georgia, serif"),
|
|
111
|
+
body: font("var(--font-inter), Inter, system-ui, sans-serif"),
|
|
112
|
+
mono: MONO
|
|
113
|
+
},
|
|
114
|
+
brutalist: {
|
|
115
|
+
heading: font("var(--font-archivo-black), 'Arial Black', system-ui, sans-serif"),
|
|
116
|
+
body: font("var(--font-inter), Inter, system-ui, sans-serif"),
|
|
117
|
+
mono: MONO
|
|
118
|
+
},
|
|
119
|
+
humanist: {
|
|
120
|
+
heading: font("var(--font-inter), Inter, system-ui, sans-serif"),
|
|
121
|
+
body: font("var(--font-inter), Inter, system-ui, sans-serif"),
|
|
122
|
+
mono: MONO
|
|
123
|
+
},
|
|
124
|
+
// DSCO is the platform's own face (Arimo/Liberation Sans under SIL OFL,
|
|
125
|
+
// shipped by the storefront at /brand with its license file). One family
|
|
126
|
+
// for heading and body — the brand look is carried by size and tracking.
|
|
127
|
+
dsco: {
|
|
128
|
+
heading: font("DSCO, Arimo, 'Liberation Sans', Arial, sans-serif"),
|
|
129
|
+
body: font("DSCO, Arimo, 'Liberation Sans', Arial, sans-serif"),
|
|
130
|
+
mono: MONO
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
var STRUCTURES = {
|
|
134
|
+
"editorial-quiet": { nav: "classic", hero: "off", footer: "minimal" },
|
|
135
|
+
"editorial-columns": { nav: "classic", hero: "off", footer: "columns" },
|
|
136
|
+
"bold-gradient": { nav: "glass-pill", hero: "gradient", footer: "columns" },
|
|
137
|
+
"space-hero": { nav: "glass-pill", hero: "starfield", footer: "centered" },
|
|
138
|
+
"classic-shop": { nav: "classic", hero: "gradient", footer: "columns" }
|
|
139
|
+
};
|
|
140
|
+
function composeThemeTokens(choice) {
|
|
141
|
+
const structure = STRUCTURES[choice.structure];
|
|
142
|
+
if (!structure) throw new Error(`unknown structure preset: ${choice.structure}`);
|
|
143
|
+
const tokens = {
|
|
144
|
+
color: { ...PALETTES[choice.palette] },
|
|
145
|
+
font: { ...TYPE_SETS[choice.type] },
|
|
146
|
+
nav: { style: raw(structure.nav) },
|
|
147
|
+
footer: { style: raw(structure.footer) }
|
|
148
|
+
};
|
|
149
|
+
if (structure.hero !== "off") {
|
|
150
|
+
tokens.hero = { style: raw(structure.hero) };
|
|
151
|
+
}
|
|
152
|
+
return tokens;
|
|
153
|
+
}
|
|
154
|
+
function themeMatrix() {
|
|
155
|
+
const out = [];
|
|
156
|
+
for (const palette of Object.keys(PALETTES)) {
|
|
157
|
+
for (const type of Object.keys(TYPE_SETS)) {
|
|
158
|
+
for (const structure of Object.keys(STRUCTURES)) {
|
|
159
|
+
const choice = { palette, type, structure };
|
|
160
|
+
out.push({
|
|
161
|
+
id: `${palette}--${type}--${structure}`,
|
|
162
|
+
choice,
|
|
163
|
+
tokens: composeThemeTokens(choice)
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return out;
|
|
169
|
+
}
|
|
170
|
+
var FEATURED_THEMES = {
|
|
171
|
+
"RUO Crystal": { palette: "paper-ink", type: "dsco", structure: "editorial-columns" },
|
|
172
|
+
"Clinical Trust": { palette: "clinical", type: "grotesk", structure: "classic-shop" },
|
|
173
|
+
"Midnight Lab": { palette: "midnight", type: "grotesk", structure: "space-hero" },
|
|
174
|
+
"Warm Apothecary": { palette: "warm-sand", type: "editorial", structure: "editorial-quiet" },
|
|
175
|
+
"Luxe Mono": { palette: "luxe-mono", type: "editorial", structure: "editorial-quiet" },
|
|
176
|
+
"Vivid Drop": { palette: "vivid", type: "brutalist", structure: "bold-gradient" },
|
|
177
|
+
"Deep Ocean": { palette: "oceanic", type: "humanist", structure: "space-hero" },
|
|
178
|
+
"Field Notes": { palette: "forest", type: "humanist", structure: "classic-shop" }
|
|
179
|
+
};
|
|
180
|
+
export {
|
|
181
|
+
FEATURED_THEMES,
|
|
182
|
+
PALETTES,
|
|
183
|
+
STRUCTURES,
|
|
184
|
+
TYPE_SETS,
|
|
185
|
+
composeThemeTokens,
|
|
186
|
+
themeMatrix
|
|
187
|
+
};
|
|
188
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Theme presets + a combinable matrix (FD theming).\n *\n * A store's look is three independent axes composed into the manifest\n * `theme.tokens` the derivation engine (`lib/theme.ts`) already consumes:\n * 1. PALETTE — the core color roles (primary/accent/background/…)\n * 2. TYPE — a font pairing (heading + body)\n * 3. STRUCTURE — architectural variants read from the token tree\n * (nav / hero / footer style; hero = null turns the hero off)\n *\n * Because the axes are independent, `themeMatrix()` yields every combination —\n * a few palettes × a few type sets × a few structures already gives hundreds\n * of distinct, on-brand looks with zero bespoke CSS. `composeThemeTokens()`\n * builds one; a store can adopt a named preset and still override any token.\n */\n\ntype Dtcg = Record<string, unknown>;\nconst color = (value: string): Dtcg => ({ $type: \"color\", $value: value });\nconst font = (value: string): Dtcg => ({ $type: \"fontFamily\", $value: value });\nconst raw = (value: string): Dtcg => ({ $value: value });\n\n// ── Axis 1: PALETTE (core color roles; the engine derives the rest) ────────\n\nexport type PaletteId =\n | \"clinical\"\n | \"midnight\"\n | \"oceanic\"\n | \"warm-sand\"\n | \"luxe-mono\"\n | \"vivid\"\n | \"forest\"\n | \"paper-ink\";\n\nexport const PALETTES: Record<PaletteId, Dtcg> = {\n clinical: {\n primary: color(\"#1e6fd9\"),\n primaryForeground: color(\"#ffffff\"),\n accent: color(\"#12b5b0\"),\n background: color(\"#f8fafc\"),\n surface: color(\"#ffffff\"),\n surfaceMuted: color(\"#eef2f7\"),\n text: color(\"#0f172a\"),\n muted: color(\"#64748b\"),\n border: color(\"#dbe3ec\"),\n },\n midnight: {\n primary: color(\"#7c8bff\"),\n primaryForeground: color(\"#0b0f1e\"),\n accent: color(\"#22d3ee\"),\n background: color(\"#070a14\"),\n surface: color(\"#0e1424\"),\n surfaceMuted: color(\"#161f36\"),\n text: color(\"#eaf0ff\"),\n muted: color(\"#8794b5\"),\n border: color(\"#1e2a44\"),\n },\n oceanic: {\n // #0891b2 → #0e7490: the lighter teal held only 3.54:1 against the\n // near-white primaryForeground — under the WCAG AA 4.5:1 body-text floor\n // pinned by surfaces/storefront/src/lib/theme-contrast.test.ts. One step\n // darker on the same hue clears it at 5.15:1.\n primary: color(\"#0e7490\"),\n primaryForeground: color(\"#f0fdff\"),\n accent: color(\"#3b82f6\"),\n background: color(\"#031b23\"),\n surface: color(\"#062b36\"),\n surfaceMuted: color(\"#0a3a49\"),\n text: color(\"#e6fbff\"),\n muted: color(\"#7fb6c4\"),\n border: color(\"#0e4b5e\"),\n },\n \"warm-sand\": {\n primary: color(\"#a8340f\"),\n primaryForeground: color(\"#fff8f1\"),\n accent: color(\"#f29131\"),\n background: color(\"#f9f6f1\"),\n surface: color(\"#fbf9f4\"),\n surfaceMuted: color(\"#f0e9dd\"),\n text: color(\"#1a1614\"),\n muted: color(\"#7a7165\"),\n border: color(\"#e3d9c8\"),\n },\n \"luxe-mono\": {\n primary: color(\"#111111\"),\n primaryForeground: color(\"#ffffff\"),\n accent: color(\"#c8a24a\"),\n background: color(\"#ffffff\"),\n surface: color(\"#fafafa\"),\n surfaceMuted: color(\"#f0f0f0\"),\n text: color(\"#0a0a0a\"),\n muted: color(\"#6b6b6b\"),\n border: color(\"#e5e5e5\"),\n },\n vivid: {\n primary: color(\"#7c3aed\"),\n primaryForeground: color(\"#ffffff\"),\n accent: color(\"#ec4899\"),\n background: color(\"#0a0713\"),\n surface: color(\"#150f26\"),\n surfaceMuted: color(\"#221838\"),\n text: color(\"#f6f2ff\"),\n muted: color(\"#a091c0\"),\n border: color(\"#2e2149\"),\n },\n forest: {\n primary: color(\"#15803d\"),\n primaryForeground: color(\"#f0fff4\"),\n accent: color(\"#ca8a04\"),\n background: color(\"#f4f8f2\"),\n surface: color(\"#ffffff\"),\n surfaceMuted: color(\"#e7f0e6\"),\n text: color(\"#14231a\"),\n muted: color(\"#5c6f60\"),\n border: color(\"#d2e2d0\"),\n },\n // The RUO Pro brand identity (design/RUO_Pro_Final): warm paper ground,\n // near-black ink, DSCO violet as the single accent. Primary is the INK\n // (buttons are dark like the reference site's), violet carries emphasis.\n \"paper-ink\": {\n primary: color(\"#080808\"),\n primaryForeground: color(\"#f5f4f0\"),\n accent: color(\"#6254ff\"),\n background: color(\"#f5f4f0\"),\n surface: color(\"#fbfaf7\"),\n surfaceMuted: color(\"#ecebe4\"),\n text: color(\"#080808\"),\n muted: color(\"#5b5b56\"),\n border: color(\"#dbd9d0\"),\n },\n};\n\n// ── Axis 2: TYPE (font pairings) ───────────────────────────────────────────\n\nexport type TypeId = \"grotesk\" | \"editorial\" | \"brutalist\" | \"humanist\" | \"dsco\";\n\nconst MONO = font(\"var(--font-jetbrains-mono), 'JetBrains Mono', ui-monospace, monospace\");\n\nexport const TYPE_SETS: Record<TypeId, Dtcg> = {\n grotesk: {\n heading: font(\"var(--font-space-grotesk), 'Space Grotesk', system-ui, sans-serif\"),\n body: font(\"var(--font-inter), Inter, system-ui, sans-serif\"),\n mono: MONO,\n },\n editorial: {\n heading: font(\"var(--font-fraunces), 'Fraunces', Georgia, serif\"),\n body: font(\"var(--font-inter), Inter, system-ui, sans-serif\"),\n mono: MONO,\n },\n brutalist: {\n heading: font(\"var(--font-archivo-black), 'Arial Black', system-ui, sans-serif\"),\n body: font(\"var(--font-inter), Inter, system-ui, sans-serif\"),\n mono: MONO,\n },\n humanist: {\n heading: font(\"var(--font-inter), Inter, system-ui, sans-serif\"),\n body: font(\"var(--font-inter), Inter, system-ui, sans-serif\"),\n mono: MONO,\n },\n // DSCO is the platform's own face (Arimo/Liberation Sans under SIL OFL,\n // shipped by the storefront at /brand with its license file). One family\n // for heading and body — the brand look is carried by size and tracking.\n dsco: {\n heading: font(\"DSCO, Arimo, 'Liberation Sans', Arial, sans-serif\"),\n body: font(\"DSCO, Arimo, 'Liberation Sans', Arial, sans-serif\"),\n mono: MONO,\n },\n};\n\n// ── Axis 3: STRUCTURE (architectural variants, read from the token tree) ────\n\nexport type NavStyleId = \"classic\" | \"glass-pill\";\nexport type HeroStyleId = \"off\" | \"gradient\" | \"starfield\";\nexport type FooterStyleId = \"minimal\" | \"columns\" | \"centered\";\n\nexport interface StructurePreset {\n nav: NavStyleId;\n hero: HeroStyleId;\n footer: FooterStyleId;\n}\n\nexport const STRUCTURES: Record<string, StructurePreset> = {\n \"editorial-quiet\": { nav: \"classic\", hero: \"off\", footer: \"minimal\" },\n \"editorial-columns\": { nav: \"classic\", hero: \"off\", footer: \"columns\" },\n \"bold-gradient\": { nav: \"glass-pill\", hero: \"gradient\", footer: \"columns\" },\n \"space-hero\": { nav: \"glass-pill\", hero: \"starfield\", footer: \"centered\" },\n \"classic-shop\": { nav: \"classic\", hero: \"gradient\", footer: \"columns\" },\n};\n\n// ── Composition ─────────────────────────────────────────────────────────────\n\nexport interface ThemeChoice {\n palette: PaletteId;\n type: TypeId;\n structure: keyof typeof STRUCTURES;\n}\n\n/** Build a manifest `theme.tokens` object from a palette/type/structure choice. */\nexport function composeThemeTokens(choice: ThemeChoice): Dtcg {\n const structure = STRUCTURES[choice.structure];\n if (!structure) throw new Error(`unknown structure preset: ${choice.structure}`);\n const tokens: Dtcg = {\n color: { ...PALETTES[choice.palette] },\n font: { ...TYPE_SETS[choice.type] },\n nav: { style: raw(structure.nav) },\n footer: { style: raw(structure.footer) },\n };\n // hero \"off\" means: declare no hero style, so the renderer shows no backdrop\n // (the hero section, if present, degrades to a plain band — the toggle).\n if (structure.hero !== \"off\") {\n (tokens as { hero?: Dtcg }).hero = { style: raw(structure.hero) };\n }\n return tokens;\n}\n\n/**\n * The full combinable matrix — every palette × type × structure. With the\n * current axes that's 8 × 5 × 5 = 200 distinct, ready-to-ship themes; add one\n * palette and it's 225. Each entry has a stable id you can pin per store.\n */\nexport function themeMatrix(): Array<{ id: string; choice: ThemeChoice; tokens: Dtcg }> {\n const out: Array<{ id: string; choice: ThemeChoice; tokens: Dtcg }> = [];\n for (const palette of Object.keys(PALETTES) as PaletteId[]) {\n for (const type of Object.keys(TYPE_SETS) as TypeId[]) {\n for (const structure of Object.keys(STRUCTURES)) {\n const choice: ThemeChoice = { palette, type, structure };\n out.push({\n id: `${palette}--${type}--${structure}`,\n choice,\n tokens: composeThemeTokens(choice),\n });\n }\n }\n }\n return out;\n}\n\n/** A curated, named shortlist for the store-builder UI (the \"featured\" themes). */\nexport const FEATURED_THEMES: Record<string, ThemeChoice> = {\n \"RUO Crystal\": { palette: \"paper-ink\", type: \"dsco\", structure: \"editorial-columns\" },\n \"Clinical Trust\": { palette: \"clinical\", type: \"grotesk\", structure: \"classic-shop\" },\n \"Midnight Lab\": { palette: \"midnight\", type: \"grotesk\", structure: \"space-hero\" },\n \"Warm Apothecary\": { palette: \"warm-sand\", type: \"editorial\", structure: \"editorial-quiet\" },\n \"Luxe Mono\": { palette: \"luxe-mono\", type: \"editorial\", structure: \"editorial-quiet\" },\n \"Vivid Drop\": { palette: \"vivid\", type: \"brutalist\", structure: \"bold-gradient\" },\n \"Deep Ocean\": { palette: \"oceanic\", type: \"humanist\", structure: \"space-hero\" },\n \"Field Notes\": { palette: \"forest\", type: \"humanist\", structure: \"classic-shop\" },\n};\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dscodotco/theme-presets",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Combinable storefront theme presets — palette × type × structure composed into DTCG tokens, with a matrix generator. Zero dependencies.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"development": "./src/index.ts",
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"require": "./dist/index.cjs"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"sideEffects": false,
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"tsup": "^8.5.0",
|
|
21
|
+
"typescript": "^5.7.0"
|
|
22
|
+
},
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/ruopro/flightdeck.git",
|
|
26
|
+
"directory": "packages/theme-presets"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsup",
|
|
36
|
+
"typecheck": "tsc --noEmit"
|
|
37
|
+
}
|
|
38
|
+
}
|