@unmap/themes 0.1.2 → 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/LICENSE +21 -0
- package/README.md +10 -8
- package/dist/index.d.ts +188 -36
- package/dist/index.js +868 -559
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Maps & Apps Inc.
|
|
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
CHANGED
|
@@ -20,21 +20,21 @@ import { encodeTheme, decodeTheme, validateTheme, ThemeError } from '@unmap/them
|
|
|
20
20
|
const code = await encodeTheme({
|
|
21
21
|
v: 1,
|
|
22
22
|
name: 'copper',
|
|
23
|
-
base: '
|
|
23
|
+
base: 'outdoor', // base | muted | outdoor | decimal | blueprint
|
|
24
24
|
light: { basemap: { water: '#9CCFD2' }, route: { color: '#B85C00', width: 4 } },
|
|
25
25
|
dark: { basemap: { water: '#12303A' }, route: { color: '#FFA24D', width: 4 } },
|
|
26
26
|
})
|
|
27
|
-
// '
|
|
27
|
+
// 'u00' for a bare style, or 'ut1.eJy…' once you leave the curated set.
|
|
28
28
|
|
|
29
29
|
const doc = await decodeTheme(code) // validated ThemeDoc, or throws ThemeError
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
## What is in a theme
|
|
33
33
|
|
|
34
|
-
- `base` picks the
|
|
35
|
-
sparse overrides on that
|
|
34
|
+
- `base` picks the style: `base`, `muted`, `outdoor`, `decimal` or `blueprint`. Each of `light` and `dark` carries
|
|
35
|
+
sparse overrides on that style, so a theme with no overrides renders exactly like its
|
|
36
36
|
`flavor=` twin.
|
|
37
|
-
- `basemap` overrides are colours on the
|
|
37
|
+
- `basemap` overrides are colours on the style's recipe (land, water, vegetation, roads, labels,
|
|
38
38
|
points of interest, landcover). `marker` styles the geocoding pin (`color`, `scale` 0.5 to 2).
|
|
39
39
|
`route` styles the routing line (`color`, `width` 1 to 12, `opacity`, and a casing).
|
|
40
40
|
- Colours are `#RRGGBB` or `#RRGGBBAA`. Unknown fields, URLs, and expressions are rejected: a
|
|
@@ -43,11 +43,13 @@ const doc = await decodeTheme(code) // validated ThemeDoc, or th
|
|
|
43
43
|
## Exports
|
|
44
44
|
|
|
45
45
|
- `encodeTheme(doc)` and `decodeTheme(code)`: async, validate on both sides, throw `ThemeError`
|
|
46
|
-
with a `detail` array naming each problem.
|
|
46
|
+
with a `detail` array naming each problem. Simple themes encode as a short `u…` preset
|
|
47
|
+
(three characters and up); advanced overrides stay `ut1.` + deflate. Codes are at most 4096
|
|
48
|
+
characters. Existing `ut1.` codes keep decoding.
|
|
47
49
|
- `validateTheme(input)`: the synchronous validator, returns a typed `ThemeDoc`.
|
|
48
|
-
- `resolveTheme(doc, mode)`: what the gateway calls. Returns the
|
|
50
|
+
- `resolveTheme(doc, mode)`: what the gateway calls. Returns the style's flavor name, the
|
|
49
51
|
composed colour flavor, and the resolved `marker` and `route` styles with defaults filled in.
|
|
50
|
-
- `
|
|
52
|
+
- `STYLE_THEMES`: the shipped styles as zero-override documents.
|
|
51
53
|
- `generateTheme(base, seeds)` and `contrastWarnings(doc)`: the pieces the builder uses to
|
|
52
54
|
derive a coherent light and dark pair from a few seed colours, and to flag label contrast
|
|
53
55
|
below 4.5:1 and 3:1.
|
package/dist/index.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ declare const ember: {
|
|
|
22
22
|
readonly 600: "#e07b2e";
|
|
23
23
|
readonly 700: "#b45309";
|
|
24
24
|
};
|
|
25
|
-
/** Cool neutrals, hue 212. The spine of every Process Ink flavour
|
|
25
|
+
/** Cool neutrals, hue 212. The spine of every Process Ink flavour except `base`. */
|
|
26
26
|
declare const ink: {
|
|
27
27
|
readonly 25: "#F1F8FA";
|
|
28
28
|
readonly 50: "#EAF2F3";
|
|
@@ -39,6 +39,29 @@ declare const ink: {
|
|
|
39
39
|
readonly 950: "#0E191C";
|
|
40
40
|
readonly 1000: "#030E10";
|
|
41
41
|
};
|
|
42
|
+
/**
|
|
43
|
+
* Warm off-white neutrals, hue 50, chroma 0.008. The `base` pair only.
|
|
44
|
+
*
|
|
45
|
+
* Same lightness ladder as `ink`, re-hued to the land of the Mapbox Streets reference `base`
|
|
46
|
+
* follows (`hsl(20, 20%, 95%)`): a faint warm tint rather than the cream it had, so parks,
|
|
47
|
+
* water and the motorway orange read as colour against it instead of competing with it.
|
|
48
|
+
*/
|
|
49
|
+
declare const paper: {
|
|
50
|
+
readonly 25: "#FBF5F2";
|
|
51
|
+
readonly 50: "#F5EFEC";
|
|
52
|
+
readonly 100: "#ECE6E3";
|
|
53
|
+
readonly 200: "#E1DBD8";
|
|
54
|
+
readonly 300: "#D4CECB";
|
|
55
|
+
readonly 400: "#C3BDBA";
|
|
56
|
+
readonly 500: "#A9A3A0";
|
|
57
|
+
readonly 600: "#8A8582";
|
|
58
|
+
readonly 700: "#696361";
|
|
59
|
+
readonly 800: "#4A4543";
|
|
60
|
+
readonly 850: "#373330";
|
|
61
|
+
readonly 900: "#272220";
|
|
62
|
+
readonly 950: "#1A1614";
|
|
63
|
+
readonly 1000: "#0E0B09";
|
|
64
|
+
};
|
|
42
65
|
/** Water, hue 200. Cooler and more chromatic than the land it meets. */
|
|
43
66
|
declare const wave: {
|
|
44
67
|
readonly 100: "#C7F1F3";
|
|
@@ -53,6 +76,26 @@ declare const wave: {
|
|
|
53
76
|
readonly 950: "#001C1E";
|
|
54
77
|
readonly 980: "#001012";
|
|
55
78
|
};
|
|
79
|
+
/**
|
|
80
|
+
* Sky water, hue 230. The `base` pair only.
|
|
81
|
+
*
|
|
82
|
+
* Same lightness ladder as `wave`, re-hued and brightened to the Streets reference's water
|
|
83
|
+
* (`hsl(200, 100%, 80%)`). `sky.200` is that colour; the rest of the ladder is the dark-mode
|
|
84
|
+
* inversion and the ocean-label step.
|
|
85
|
+
*/
|
|
86
|
+
declare const sky: {
|
|
87
|
+
readonly 100: "#CCEEFF";
|
|
88
|
+
readonly 200: "#A7E2FF";
|
|
89
|
+
readonly 300: "#8ACFF0";
|
|
90
|
+
readonly 400: "#73B7D7";
|
|
91
|
+
readonly 500: "#5A9CBC";
|
|
92
|
+
readonly 600: "#387D9C";
|
|
93
|
+
readonly 700: "#155F7C";
|
|
94
|
+
readonly 800: "#004057";
|
|
95
|
+
readonly 900: "#002837";
|
|
96
|
+
readonly 950: "#001B27";
|
|
97
|
+
readonly 980: "#000F17";
|
|
98
|
+
};
|
|
56
99
|
/** Vegetation, hue 152: park, wood, scrub. */
|
|
57
100
|
declare const verdant: {
|
|
58
101
|
readonly 100: "#D3F1DA";
|
|
@@ -74,19 +117,8 @@ declare const sandstone: {
|
|
|
74
117
|
readonly 500: "#A19070";
|
|
75
118
|
};
|
|
76
119
|
/**
|
|
77
|
-
* Pure neutrals, zero chroma.
|
|
78
|
-
*
|
|
79
|
-
* `ink` carries a hue-212 cool cast, which is right for every other flavour and wrong for this
|
|
80
|
-
* one: `muted` exists to vanish under a customer's data, and a basemap with *any* hue biases the
|
|
81
|
-
* colours laid on top of it. So muted gets its own ramp where R=G=B exactly.
|
|
82
|
-
*
|
|
83
|
-
* Calibrated against Mapbox Light and Protomaps' `WHITE`, whose land/water/building relationships
|
|
84
|
-
* this flavour follows: land a light grey, roads *brighter* than the land rather than darker,
|
|
85
|
-
* buildings a single step down, and water the only tone with any real weight.
|
|
86
|
-
*
|
|
87
|
-
* Their label colours are deliberately NOT copied. Protomaps `WHITE` puts `state_label` #b3b3b3
|
|
88
|
-
* on #ffffff, roughly 2:1, which fails the 4.5:1 floor `cartography.test.ts` enforces. The
|
|
89
|
-
* structure is worth borrowing; the label contrast is not.
|
|
120
|
+
* Pure neutrals, zero chroma. Everything on `muted` except its water (see `mist`), plus the
|
|
121
|
+
* road casings on `base`. Kept R=G=B so `muted` is greyscale in fact rather than in name.
|
|
90
122
|
*/
|
|
91
123
|
declare const graphite: {
|
|
92
124
|
readonly 25: "#FAFAFA";
|
|
@@ -102,6 +134,71 @@ declare const graphite: {
|
|
|
102
134
|
readonly 900: "#232323";
|
|
103
135
|
readonly 1000: "#0B0B0B";
|
|
104
136
|
};
|
|
137
|
+
/**
|
|
138
|
+
* Muted water: the `wave` lightness ladder at zero chroma. `muted` is greyscale end to end,
|
|
139
|
+
* water included, so this ramp exists for one reason — it is the ramp the *water* seed
|
|
140
|
+
* recolours when a theme is applied to `muted`, which the land ramp (`graphite`) is not.
|
|
141
|
+
* `mist.200` is the light-mode fill; `mist.980` the dark-mode inversion so water stays darker
|
|
142
|
+
* than land.
|
|
143
|
+
*/
|
|
144
|
+
declare const mist: {
|
|
145
|
+
readonly 100: "#E7E7E7";
|
|
146
|
+
readonly 200: "#D7D7D7";
|
|
147
|
+
readonly 300: "#C4C4C4";
|
|
148
|
+
readonly 400: "#ACACAC";
|
|
149
|
+
readonly 500: "#929292";
|
|
150
|
+
readonly 600: "#757575";
|
|
151
|
+
readonly 700: "#575757";
|
|
152
|
+
readonly 800: "#3A3A3A";
|
|
153
|
+
readonly 900: "#242424";
|
|
154
|
+
readonly 950: "#171717";
|
|
155
|
+
readonly 980: "#0D0D0D";
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Jade, hue 163. The `decimal` pair: one green family on near-black (dark) or near-white
|
|
159
|
+
* (light), nothing else. Same lightness ladder as `ink`, so every label step the other styles
|
|
160
|
+
* rely on clears the floors here too. Chroma rises with lightness up to the mid steps
|
|
161
|
+
* (`0.16·L`) and eases off toward white (`0.42·(1−L)`), which is the profile of the
|
|
162
|
+
* reference's own four greens (`#142a21` → `#50a882`).
|
|
163
|
+
*/
|
|
164
|
+
declare const jade: {
|
|
165
|
+
readonly 25: "#F1F9F4";
|
|
166
|
+
readonly 50: "#E6F4ED";
|
|
167
|
+
readonly 100: "#D7EEE2";
|
|
168
|
+
readonly 200: "#C3E6D4";
|
|
169
|
+
readonly 300: "#ACDDC4";
|
|
170
|
+
readonly 400: "#8BCFAF";
|
|
171
|
+
readonly 500: "#56BB90";
|
|
172
|
+
readonly 600: "#459975";
|
|
173
|
+
readonly 700: "#327357";
|
|
174
|
+
readonly 800: "#21513D";
|
|
175
|
+
readonly 850: "#173C2C";
|
|
176
|
+
readonly 900: "#0E2A1E";
|
|
177
|
+
readonly 950: "#071C13";
|
|
178
|
+
readonly 1000: "#030F09";
|
|
179
|
+
};
|
|
180
|
+
/**
|
|
181
|
+
* Cobalt, hue 267. The `blueprint` pair: royal blue field with navy roads and pale blue water
|
|
182
|
+
* in dark, blue lines on blue-white paper in light. Same lightness ladder as `ink`. Chroma
|
|
183
|
+
* peaks at the field step (`700`, `0.23` — the reference's `#1c44dc`) and falls away on both
|
|
184
|
+
* sides, so the pale steps stay paper-like and the navy steps stay ink-like.
|
|
185
|
+
*/
|
|
186
|
+
declare const cobalt: {
|
|
187
|
+
readonly 25: "#F4F7FB";
|
|
188
|
+
readonly 50: "#ECF0F9";
|
|
189
|
+
readonly 100: "#E1E8F7";
|
|
190
|
+
readonly 200: "#D2DCF5";
|
|
191
|
+
readonly 300: "#C0CFF3";
|
|
192
|
+
readonly 400: "#A8BDF1";
|
|
193
|
+
readonly 500: "#84A2EE";
|
|
194
|
+
readonly 600: "#587EEA";
|
|
195
|
+
readonly 700: "#2C4EE5";
|
|
196
|
+
readonly 800: "#243D93";
|
|
197
|
+
readonly 850: "#1D2F65";
|
|
198
|
+
readonly 900: "#162241";
|
|
199
|
+
readonly 950: "#0F1629";
|
|
200
|
+
readonly 1000: "#080B15";
|
|
201
|
+
};
|
|
105
202
|
|
|
106
203
|
/**
|
|
107
204
|
* The unmap cartography authoring surface, moved here from apps/gateway/src/flavors.ts so the
|
|
@@ -113,11 +210,17 @@ declare const graphite: {
|
|
|
113
210
|
* cannot drift out of step with the surface roads they mirror.
|
|
114
211
|
*/
|
|
115
212
|
/**
|
|
116
|
-
* Appended, never inserted
|
|
117
|
-
* so inserting a
|
|
213
|
+
* The shipped styles. Appended, never inserted: this array's order drives the style picker in
|
|
214
|
+
* the unmap.dev builder, so inserting a style mid-array silently reorders a control people have
|
|
215
|
+
* already learned.
|
|
216
|
+
*
|
|
217
|
+
* `relief` and `street` were retired; they are not listed here. Short preset codes still
|
|
218
|
+
* decode those slots via `normalizeThemeBase` / the slot table in `preset.ts`.
|
|
118
219
|
*/
|
|
119
|
-
declare const THEME_BASES: readonly ["base", "muted", "
|
|
220
|
+
declare const THEME_BASES: readonly ["base", "muted", "outdoor", "decimal", "blueprint"];
|
|
120
221
|
type ThemeBase = (typeof THEME_BASES)[number];
|
|
222
|
+
/** Map a theme `base` — living or retired — onto a shipped style. `null` if unknown. */
|
|
223
|
+
declare function normalizeThemeBase(base: string): ThemeBase | null;
|
|
121
224
|
declare const MODES: readonly ["light", "dark"];
|
|
122
225
|
type ThemeMode = (typeof MODES)[number];
|
|
123
226
|
interface RoadRamp {
|
|
@@ -198,21 +301,26 @@ interface Recipe {
|
|
|
198
301
|
declare function makeFlavor(r: Recipe): Flavor;
|
|
199
302
|
|
|
200
303
|
/**
|
|
201
|
-
* The
|
|
304
|
+
* The ramp families (plus ember) a recipe draws from. `buildRecipes` is parameterized on
|
|
202
305
|
* this so the theme generator can re-emit the same recipes from *generated* ramps — same
|
|
203
306
|
* lightness ladders, a customer's hues — while the stock `RECIPES` stay byte-identical to the
|
|
204
307
|
* hand-tuned originals (they are `buildRecipes(STOCK_RAMPS)`).
|
|
205
308
|
*/
|
|
206
309
|
interface RampSet {
|
|
207
310
|
ink: typeof ink;
|
|
311
|
+
paper: typeof paper;
|
|
208
312
|
wave: typeof wave;
|
|
313
|
+
sky: typeof sky;
|
|
209
314
|
verdant: typeof verdant;
|
|
210
315
|
sandstone: typeof sandstone;
|
|
211
316
|
graphite: typeof graphite;
|
|
317
|
+
mist: typeof mist;
|
|
318
|
+
jade: typeof jade;
|
|
319
|
+
cobalt: typeof cobalt;
|
|
212
320
|
ember: typeof ember;
|
|
213
321
|
}
|
|
214
322
|
declare const STOCK_RAMPS: RampSet;
|
|
215
|
-
/** Build the
|
|
323
|
+
/** Build the shipped recipes from a ramp set. Stock ramps in → the shipped cartography out. */
|
|
216
324
|
declare function buildRecipes(r: RampSet): Record<ThemeBase, Record<ThemeMode, Recipe>>;
|
|
217
325
|
declare const RECIPES: Record<ThemeBase, Record<ThemeMode, Recipe>>;
|
|
218
326
|
|
|
@@ -224,8 +332,8 @@ declare const RECIPES: Record<ThemeBase, Record<ThemeMode, Recipe>>;
|
|
|
224
332
|
* arrive on public query strings and are composed into style JSON the gateway signs its own
|
|
225
333
|
* asset URLs into. `validateTheme` is the only door in.
|
|
226
334
|
*
|
|
227
|
-
* `base` names the
|
|
228
|
-
*
|
|
335
|
+
* `base` names the style (one of the shipped styles); each half carries only sparse overrides
|
|
336
|
+
* on that style, so presets are near-empty documents and codes stay short.
|
|
229
337
|
*/
|
|
230
338
|
type DeepPartial<T> = {
|
|
231
339
|
[K in keyof T]?: NonNullable<T[K]> extends object ? DeepPartial<NonNullable<T[K]>> : T[K];
|
|
@@ -309,11 +417,48 @@ declare function validateTheme(input: unknown): ThemeDoc;
|
|
|
309
417
|
*/
|
|
310
418
|
declare const THEME_CODE_PREFIX = "ut1.";
|
|
311
419
|
declare const MAX_CODE_LENGTH = 4096;
|
|
312
|
-
/** Validate and encode a theme document
|
|
420
|
+
/** Validate and encode a theme document. Curated/simple themes become a short `u…` preset; anything else is `ut1.` + deflate. Throws `ThemeError`. */
|
|
313
421
|
declare function encodeTheme(doc: ThemeDoc): Promise<string>;
|
|
314
|
-
/** Decode and validate a compact `ut1.`
|
|
422
|
+
/** Decode and validate a compact theme code (`u…` preset or `ut1.` document). Every failure lands as `ThemeError`. */
|
|
315
423
|
declare function decodeTheme(code: string): Promise<ThemeDoc>;
|
|
316
424
|
|
|
425
|
+
/**
|
|
426
|
+
* Short preset codes, the same idea as shadcn's `b0` / `a2r6bw`: a versioned base62 packing of
|
|
427
|
+
* enumerated choices that starts at three characters and grows only when the theme leaves the
|
|
428
|
+
* curated set.
|
|
429
|
+
*
|
|
430
|
+
* u00, u01, u04 living styles from the original lineup (base, muted, outdoor)
|
|
431
|
+
* u02, u03 retired styles (relief → outdoor, street → base)
|
|
432
|
+
* u05, u06 styles added later (decimal, blueprint); u07 is the one spare slot
|
|
433
|
+
* u08… named theme preset on one of the original style slots
|
|
434
|
+
* u5K… named theme preset on one of the later slots
|
|
435
|
+
* longer custom seed colours (4× RGB) on any style
|
|
436
|
+
*
|
|
437
|
+
* Advanced overrides — anything `generateTheme` would not emit — still use the `ut1.` deflate
|
|
438
|
+
* document. `ut1.` is checked first on decode so an existing customer code never collides.
|
|
439
|
+
*
|
|
440
|
+
* Slot numbers are permanent once a code is published, which is why the layout below is a set
|
|
441
|
+
* of appended regions rather than one formula: every code ever printed keeps decoding.
|
|
442
|
+
*/
|
|
443
|
+
declare const PRESET_CODE_PREFIX = "u";
|
|
444
|
+
declare const PRESET_CODE_RE: RegExp;
|
|
445
|
+
declare function isThemePresetCode(code: string): boolean;
|
|
446
|
+
/** Registry key for a preset name: `process ink` → `processInk`. */
|
|
447
|
+
declare function presetId(name: string): string;
|
|
448
|
+
/**
|
|
449
|
+
* Pack a theme into a short preset code, or `null` when the document is not one of the
|
|
450
|
+
* representable shapes (caller falls back to `ut1.`).
|
|
451
|
+
*/
|
|
452
|
+
declare function encodePreset(doc: ThemeDoc): string | null;
|
|
453
|
+
/** Expand a short preset code to a validated ThemeDoc. Throws `ThemeError`. */
|
|
454
|
+
declare function decodePreset(code: string): ThemeDoc;
|
|
455
|
+
/**
|
|
456
|
+
* Registry key for a curated preset (`base`, `processInk`, `boreal`, …), or `undefined` when
|
|
457
|
+
* the theme is a custom code that is not one of the named `MAP_THEMES` entries (named presets
|
|
458
|
+
* are published on the `base` style only).
|
|
459
|
+
*/
|
|
460
|
+
declare function registryThemeKey(doc: ThemeDoc): string | undefined;
|
|
461
|
+
|
|
317
462
|
/**
|
|
318
463
|
* Platform drawing defaults for the two client-side overlays a theme styles. These are exactly
|
|
319
464
|
* the convention the unmap.dev hero has always drawn: a magenta pin, and a route as a solid
|
|
@@ -322,7 +467,7 @@ declare function decodeTheme(code: string): Promise<ThemeDoc>;
|
|
|
322
467
|
declare const DEFAULT_MARKER: Required<MarkerTheme>;
|
|
323
468
|
declare const DEFAULT_ROUTE: Required<RouteTheme>;
|
|
324
469
|
interface ResolvedTheme {
|
|
325
|
-
/** `<base>-<mode>`, the
|
|
470
|
+
/** `<base>-<mode>`, the flavour name — what selects sprites and terrain behaviour. */
|
|
326
471
|
flavorName: `${ThemeBase}-${ThemeMode}`;
|
|
327
472
|
flavor: Flavor;
|
|
328
473
|
marker: Required<MarkerTheme>;
|
|
@@ -336,7 +481,7 @@ interface ResolvedTheme {
|
|
|
336
481
|
declare function mergeRecipe(base: Recipe, overrides?: BasemapOverrides): Recipe;
|
|
337
482
|
/**
|
|
338
483
|
* Resolve one half of a theme into everything a renderer needs: the expanded Flavor, the
|
|
339
|
-
*
|
|
484
|
+
* flavour name, and marker/route styles with defaults filled in.
|
|
340
485
|
*/
|
|
341
486
|
declare function resolveTheme(doc: ThemeDoc, mode: ThemeMode): ResolvedTheme;
|
|
342
487
|
|
|
@@ -360,8 +505,12 @@ declare function contrastWarnings(doc: ThemeDoc): ContrastWarning[];
|
|
|
360
505
|
/**
|
|
361
506
|
* The shipped styles as starting-point themes: zero overrides, so each is guaranteed identical
|
|
362
507
|
* to its `flavor=` twin (asserted in the gateway theme tests). The builder opens on these.
|
|
508
|
+
*
|
|
509
|
+
* Named after the style itself — `base`, `muted`, `outdoor`, `decimal`, `blueprint` — the same word the homepage, the
|
|
510
|
+
* SDK's `style` option and the gateway URL use. The theme presets (`process ink`, `boreal`, …)
|
|
511
|
+
* are a separate set layered on a style; a style never borrows one's name.
|
|
363
512
|
*/
|
|
364
|
-
declare const
|
|
513
|
+
declare const STYLE_THEMES: Record<ThemeBase, ThemeDoc>;
|
|
365
514
|
|
|
366
515
|
/**
|
|
367
516
|
* Minimal sRGB ↔ OKLCH conversion (Björn Ottosson's OKLab constants), plus a chroma-reducing
|
|
@@ -395,25 +544,28 @@ declare const DEFAULT_SEEDS: Required<ThemeSeeds>;
|
|
|
395
544
|
* Generate a full theme from seed colours. Deterministic; the result always clears the label
|
|
396
545
|
* floors in both modes (enforced, and asserted by the hue-sweep test).
|
|
397
546
|
*
|
|
398
|
-
* Family mapping: `land` recolours the
|
|
399
|
-
* chroma
|
|
400
|
-
*
|
|
401
|
-
*
|
|
402
|
-
*
|
|
547
|
+
* Family mapping: `land` recolours the land spines — `ink`, `base`'s `paper`, `muted`'s
|
|
548
|
+
* `graphite` at a whisper of chroma (that style exists to vanish under data), and the
|
|
549
|
+
* single-hue families of `decimal` (`jade`) and `blueprint` (`cobalt`) at full chroma, so a
|
|
550
|
+
* seed can carry them to any hue. `water` recolours the wave, sky, and mist ramps (`mist` is
|
|
551
|
+
* greyscale in stock `muted` and takes the water seed's hue outright), `nature` the verdant
|
|
552
|
+
* ramp. Warm landcover (sandstone), POI accents and white road fills stay stock: they
|
|
553
|
+
* are tuned relationships, not identity. `accent` styles the marker and route overlays only —
|
|
554
|
+
* it never enters the basemap, same rule as the brand magenta.
|
|
403
555
|
*/
|
|
404
556
|
declare function generateTheme(base: ThemeBase, seeds: ThemeSeeds): ThemeDoc;
|
|
405
557
|
|
|
406
558
|
/**
|
|
407
|
-
*
|
|
559
|
+
* The named theme presets of the builder's simple mode — the hand-picked starting points, named
|
|
408
560
|
* for Canadian landscapes. Each is just a seed trio + accent; `generateTheme` does the rest,
|
|
409
561
|
* and its contrast guarantee holds for these like any other seeds (asserted in tests).
|
|
410
562
|
*/
|
|
411
|
-
interface
|
|
412
|
-
/** Display name, lowercase like the
|
|
563
|
+
interface ThemePreset {
|
|
564
|
+
/** Display name, lowercase like the style names. Not translated — these are names. */
|
|
413
565
|
name: string;
|
|
414
566
|
seeds: Required<ThemeSeeds>;
|
|
415
567
|
}
|
|
416
|
-
declare const
|
|
568
|
+
declare const THEME_PRESETS: ThemePreset[];
|
|
417
569
|
/**
|
|
418
570
|
* A random but *harmonic* seed trio — the shuffle button. Hues are related (water lands
|
|
419
571
|
* cool-of-complementary, nature analogous-of-triadic, the accent opposes the land) and chroma
|
|
@@ -424,4 +576,4 @@ declare const SEED_PALETTES: SeedPalette[];
|
|
|
424
576
|
*/
|
|
425
577
|
declare function shuffleSeeds(rng?: () => number): Required<ThemeSeeds>;
|
|
426
578
|
|
|
427
|
-
export { type BasemapOverrides, type ContrastWarning, DEFAULT_MARKER, DEFAULT_ROUTE, DEFAULT_SEEDS, type DeepPartial, LABEL_PAIRS, type LabelRamp, MAX_CODE_LENGTH, MODES, type MarkerTheme, type Oklch,
|
|
579
|
+
export { type BasemapOverrides, type ContrastWarning, DEFAULT_MARKER, DEFAULT_ROUTE, DEFAULT_SEEDS, type DeepPartial, LABEL_PAIRS, type LabelRamp, MAX_CODE_LENGTH, MODES, type MarkerTheme, type Oklch, PRESET_CODE_PREFIX, PRESET_CODE_RE, RECIPES, type RampSet, type Recipe, type ResolvedTheme, type RoadRamp, type RouteTheme, STOCK_RAMPS, STYLE_THEMES, THEME_BASES, THEME_CODE_PREFIX, THEME_PRESETS, type ThemeBase, type ThemeDoc, ThemeError, type ThemeHalf, type ThemeMode, type ThemePreset, type ThemeSeeds, buildRecipes, cobalt, contrast, contrastWarnings, decodePreset, decodeTheme, ember, encodePreset, encodeTheme, generateTheme, graphite, hexToOklch, ink, isThemePresetCode, jade, makeFlavor, mergeRecipe, mist, normalizeThemeBase, oklchToHex, paper, presetId, registryThemeKey, resolveTheme, sandstone, shuffleSeeds, sky, validateTheme, verdant, wave };
|