@kensio/colophon 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/README.md +48 -0
  2. package/dist/background/gradient.d.ts +12 -0
  3. package/dist/background/gradient.d.ts.map +1 -0
  4. package/dist/background/gradient.js +21 -0
  5. package/dist/background/gradient.js.map +1 -0
  6. package/dist/background/image.d.ts +14 -0
  7. package/dist/background/image.d.ts.map +1 -0
  8. package/dist/background/image.js +36 -0
  9. package/dist/background/image.js.map +1 -0
  10. package/dist/background/index.d.ts +13 -0
  11. package/dist/background/index.d.ts.map +1 -0
  12. package/dist/background/index.js +27 -0
  13. package/dist/background/index.js.map +1 -0
  14. package/dist/background/mesh.d.ts +12 -0
  15. package/dist/background/mesh.d.ts.map +1 -0
  16. package/dist/background/mesh.js +43 -0
  17. package/dist/background/mesh.js.map +1 -0
  18. package/dist/config/index.d.ts +1 -1
  19. package/dist/config/index.d.ts.map +1 -1
  20. package/dist/config/index.js +9 -2
  21. package/dist/config/index.js.map +1 -1
  22. package/dist/config/size.d.ts +6 -0
  23. package/dist/config/size.d.ts.map +1 -1
  24. package/dist/config/size.js +20 -8
  25. package/dist/config/size.js.map +1 -1
  26. package/dist/index.d.ts +3 -2
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +2 -1
  29. package/dist/index.js.map +1 -1
  30. package/dist/render/svg.d.ts.map +1 -1
  31. package/dist/render/svg.js +9 -2
  32. package/dist/render/svg.js.map +1 -1
  33. package/dist/stamp/config-digest.d.ts.map +1 -1
  34. package/dist/stamp/config-digest.js +1 -0
  35. package/dist/stamp/config-digest.js.map +1 -1
  36. package/dist/templates/banner/badge-props.d.ts +16 -0
  37. package/dist/templates/banner/badge-props.d.ts.map +1 -0
  38. package/dist/templates/banner/badge-props.js +58 -0
  39. package/dist/templates/banner/badge-props.js.map +1 -0
  40. package/dist/templates/banner/index.d.ts.map +1 -1
  41. package/dist/templates/banner/index.js +6 -4
  42. package/dist/templates/banner/index.js.map +1 -1
  43. package/dist/texture/grain.d.ts +17 -0
  44. package/dist/texture/grain.d.ts.map +1 -0
  45. package/dist/texture/grain.js +29 -0
  46. package/dist/texture/grain.js.map +1 -0
  47. package/dist/texture/index.d.ts +11 -0
  48. package/dist/texture/index.d.ts.map +1 -0
  49. package/dist/texture/index.js +20 -0
  50. package/dist/texture/index.js.map +1 -0
  51. package/dist/texture/pattern.d.ts +17 -0
  52. package/dist/texture/pattern.d.ts.map +1 -0
  53. package/dist/texture/pattern.js +45 -0
  54. package/dist/texture/pattern.js.map +1 -0
  55. package/dist/texture/resolve.d.ts +16 -0
  56. package/dist/texture/resolve.d.ts.map +1 -0
  57. package/dist/texture/resolve.js +20 -0
  58. package/dist/texture/resolve.js.map +1 -0
  59. package/dist/theme/index.d.ts +27 -0
  60. package/dist/theme/index.d.ts.map +1 -0
  61. package/dist/theme/index.js +41 -0
  62. package/dist/theme/index.js.map +1 -0
  63. package/dist/theme/presets.d.ts +38 -0
  64. package/dist/theme/presets.d.ts.map +1 -0
  65. package/dist/theme/presets.js +150 -0
  66. package/dist/theme/presets.js.map +1 -0
  67. package/dist/types.d.ts +123 -4
  68. package/dist/types.d.ts.map +1 -1
  69. package/dist/validate/background.d.ts +12 -0
  70. package/dist/validate/background.d.ts.map +1 -0
  71. package/dist/validate/background.js +53 -0
  72. package/dist/validate/background.js.map +1 -0
  73. package/dist/validate/collect.d.ts +9 -0
  74. package/dist/validate/collect.d.ts.map +1 -0
  75. package/dist/validate/collect.js +34 -0
  76. package/dist/validate/collect.js.map +1 -0
  77. package/dist/validate/index.d.ts.map +1 -1
  78. package/dist/validate/index.js +2 -20
  79. package/dist/validate/index.js.map +1 -1
  80. package/dist/validate/keys.d.ts +16 -0
  81. package/dist/validate/keys.d.ts.map +1 -1
  82. package/dist/validate/keys.js +52 -0
  83. package/dist/validate/keys.js.map +1 -1
  84. package/dist/validate/overrides.d.ts.map +1 -1
  85. package/dist/validate/overrides.js +5 -1
  86. package/dist/validate/overrides.js.map +1 -1
  87. package/dist/validate/texture.d.ts +11 -0
  88. package/dist/validate/texture.d.ts.map +1 -0
  89. package/dist/validate/texture.js +34 -0
  90. package/dist/validate/texture.js.map +1 -0
  91. package/dist/validate/values.d.ts +10 -10
  92. package/dist/validate/values.d.ts.map +1 -1
  93. package/dist/validate/values.js +21 -45
  94. package/dist/validate/values.js.map +1 -1
  95. package/package.json +1 -1
@@ -0,0 +1,58 @@
1
+ import { optionalString } from "../../props.js";
2
+ /**
3
+ * Read a badge out of the object a post declared, field by field, the way
4
+ * every other prop is read. What frontmatter yields is a plain value rather
5
+ * than the interface the compiler was shown, so a badge is built here from
6
+ * what is actually there instead of being passed along as one.
7
+ *
8
+ * Returns `undefined` for an object carrying no text, since the text is the
9
+ * badge and there is nothing to draw without it.
10
+ */
11
+ function badgeFromProps(declared) {
12
+ const text = optionalString("text" in declared ? declared.text : undefined);
13
+ if (text === undefined || text === "") {
14
+ return undefined;
15
+ }
16
+ const color = optionalString("color" in declared ? declared.color : undefined);
17
+ const background = optionalString("background" in declared ? declared.background : undefined);
18
+ return {
19
+ text,
20
+ ...(color !== undefined && { color }),
21
+ ...(background !== undefined && { background }),
22
+ };
23
+ }
24
+ /**
25
+ * The badge to draw: the one the post declares, or the configured one where it
26
+ * declares nothing.
27
+ *
28
+ * A badge in config is the same badge on every image a site renders, and a
29
+ * post the badge does not describe has no other way to be rid of it. `false`
30
+ * is that way out, and an object is the same door in the other direction, so a
31
+ * post can carry a badge of its own without the config knowing about it.
32
+ *
33
+ * Anything else is a mistake in the frontmatter. It is reported and the
34
+ * configured badge is drawn, which leaves the post with the image it would
35
+ * have had if it had said nothing at all.
36
+ */
37
+ export function badgeFor(props, config) {
38
+ // Widened because this arrives from a post's frontmatter: the declared type
39
+ // is what a project means to write, not what the file holds.
40
+ const declared = props.badge;
41
+ if (declared === undefined) {
42
+ return config.badge;
43
+ }
44
+ if (declared === false) {
45
+ return undefined;
46
+ }
47
+ const badge = typeof declared === "object" && declared !== null
48
+ ? badgeFromProps(declared)
49
+ : undefined;
50
+ if (badge === undefined) {
51
+ config.onWarning("props.badge is neither a badge nor false, so the configured badge was" +
52
+ " drawn. Give it an object with the `text` to draw, or `false` for no" +
53
+ " badge on this image.");
54
+ return config.badge;
55
+ }
56
+ return badge;
57
+ }
58
+ //# sourceMappingURL=badge-props.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge-props.js","sourceRoot":"","sources":["../../../src/templates/banner/badge-props.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGhD;;;;;;;;GAQG;AACH,SAAS,cAAc,CAAC,QAAgB;IACtC,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAE5E,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;QACtC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,KAAK,GAAG,cAAc,CAC1B,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CACjD,CAAC;IACF,MAAM,UAAU,GAAG,cAAc,CAC/B,YAAY,IAAI,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAC3D,CAAC;IAEF,OAAO;QACL,IAAI;QACJ,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,CAAC;QACrC,GAAG,CAAC,UAAU,KAAK,SAAS,IAAI,EAAE,UAAU,EAAE,CAAC;KAChD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,QAAQ,CACtB,KAAqB,EACrB,MAAsB;IAEtB,4EAA4E;IAC5E,6DAA6D;IAC7D,MAAM,QAAQ,GAAY,KAAK,CAAC,KAAK,CAAC;IAEtC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;QACvB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,KAAK,GACT,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI;QAC/C,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC;QAC1B,CAAC,CAAC,SAAS,CAAC;IAEhB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,CAAC,SAAS,CACd,uEAAuE;YACrE,sEAAsE;YACtE,uBAAuB,CAC1B,CAAC;QAEF,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/banner/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAmB,MAAM,gBAAgB,CAAC;AAOhE;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,EAAE,QAmF5B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/banner/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAmB,MAAM,gBAAgB,CAAC;AAQhE;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,EAAE,QA8E5B,CAAC"}
@@ -3,6 +3,7 @@ import { optionalString } from "../../props.js";
3
3
  import { attribution } from "../attribution.js";
4
4
  import { footerBaseline, hasFooter } from "../footer.js";
5
5
  import { logoElement, logoRect } from "../logo.js";
6
+ import { badgeFor } from "./badge-props.js";
6
7
  import { renderBadge } from "./badge.js";
7
8
  import { bannerLines } from "./lines.js";
8
9
  /**
@@ -23,11 +24,12 @@ export const bannerTemplate = {
23
24
  const footerFs = Math.round(height * 0.034);
24
25
  const badgeHeight = Math.round(height * 0.072);
25
26
  const mark = logoRect(logo, dimensions, pad, "start");
27
+ const badge = badgeFor(props, config);
26
28
  const subtitle = optionalString(props.subtitle);
27
29
  const hasSubtitle = subtitle !== undefined && subtitle !== "";
28
30
  // The text sits between whatever the marks along the top and the footer
29
31
  // along the bottom leave behind.
30
- const topMark = Math.max(config.badge === undefined ? 0 : badgeHeight, mark?.height ?? 0);
32
+ const topMark = Math.max(badge === undefined ? 0 : badgeHeight, mark?.height ?? 0);
31
33
  const area = inset({ x: 0, y: 0, width, height }, {
32
34
  top: pad + (topMark === 0 ? 0 : topMark + Math.round(height * 0.03)),
33
35
  right: pad,
@@ -51,9 +53,9 @@ export const bannerTemplate = {
51
53
  fill: config.colors.foreground,
52
54
  lineHeight: 1.28,
53
55
  });
54
- const badge = config.badge === undefined
56
+ const badgeMark = badge === undefined
55
57
  ? ""
56
- : renderBadge(config.badge, fontFamily, config.colors.brand, pad, badgeHeight);
58
+ : renderBadge(badge, fontFamily, config.colors.brand, pad, badgeHeight);
57
59
  const footer = attribution(config, {
58
60
  x: pad,
59
61
  y: footerBaseline(height, pad, footerFs),
@@ -62,7 +64,7 @@ export const bannerTemplate = {
62
64
  left: pad,
63
65
  width: width - pad * 2,
64
66
  }, avatar, measure);
65
- return badge + logoElement(logo, mark) + body + footer;
67
+ return badgeMark + logoElement(logo, mark) + body + footer;
66
68
  },
67
69
  };
68
70
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/banner/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/banner/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { Dimensions, Texture } from "../types.js";
2
+ /**
3
+ * Film grain, from one turbulence filter.
4
+ *
5
+ * `scale` is roughly the size of a speck in pixels, which is what someone
6
+ * tuning this actually wants to think about; the filter wants the reciprocal
7
+ * of that, so the two are inverses of each other. Three octaves is enough to
8
+ * stop the noise looking regular and cheap enough not to notice.
9
+ *
10
+ * The noise is desaturated to grey, since coloured specks over a brand colour
11
+ * read as a rendering fault rather than as grain. Grey does lighten what is
12
+ * under it a little, which is why the default opacity is as low as it is.
13
+ */
14
+ export declare function grainSvg(texture: Extract<Texture, {
15
+ readonly type: "grain";
16
+ }>, dimensions: Dimensions, id: string): string;
17
+ //# sourceMappingURL=grain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grain.d.ts","sourceRoot":"","sources":["../../src/texture/grain.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAKvD;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,EACrD,UAAU,EAAE,UAAU,EACtB,EAAE,EAAE,MAAM,GACT,MAAM,CAgBR"}
@@ -0,0 +1,29 @@
1
+ const defaultOpacity = 0.1;
2
+ const defaultScale = 1.4;
3
+ /**
4
+ * Film grain, from one turbulence filter.
5
+ *
6
+ * `scale` is roughly the size of a speck in pixels, which is what someone
7
+ * tuning this actually wants to think about; the filter wants the reciprocal
8
+ * of that, so the two are inverses of each other. Three octaves is enough to
9
+ * stop the noise looking regular and cheap enough not to notice.
10
+ *
11
+ * The noise is desaturated to grey, since coloured specks over a brand colour
12
+ * read as a rendering fault rather than as grain. Grey does lighten what is
13
+ * under it a little, which is why the default opacity is as low as it is.
14
+ */
15
+ export function grainSvg(texture, dimensions, id) {
16
+ const { width, height } = dimensions;
17
+ const frequency = 1 / (texture.scale ?? defaultScale);
18
+ return (`<defs>` +
19
+ `<filter id="${id}" x="0" y="0" width="100%" height="100%">` +
20
+ `<feTurbulence type="fractalNoise" baseFrequency="${frequency.toFixed(3)}"` +
21
+ ` numOctaves="3" stitchTiles="stitch"/>` +
22
+ `<feColorMatrix type="saturate" values="0"/>` +
23
+ `</filter>` +
24
+ `</defs>` +
25
+ `<rect width="${String(width)}" height="${String(height)}"` +
26
+ ` filter="url(#${id})"` +
27
+ ` opacity="${String(texture.opacity ?? defaultOpacity)}"/>`);
28
+ }
29
+ //# sourceMappingURL=grain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grain.js","sourceRoot":"","sources":["../../src/texture/grain.ts"],"names":[],"mappings":"AAEA,MAAM,cAAc,GAAG,GAAG,CAAC;AAC3B,MAAM,YAAY,GAAG,GAAG,CAAC;AAEzB;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,QAAQ,CACtB,OAAqD,EACrD,UAAsB,EACtB,EAAU;IAEV,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC;IACrC,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC,CAAC;IAEtD,OAAO,CACL,QAAQ;QACR,eAAe,EAAE,2CAA2C;QAC5D,oDAAoD,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;QAC3E,wCAAwC;QACxC,6CAA6C;QAC7C,WAAW;QACX,SAAS;QACT,gBAAgB,MAAM,CAAC,KAAK,CAAC,aAAa,MAAM,CAAC,MAAM,CAAC,GAAG;QAC3D,iBAAiB,EAAE,IAAI;QACvB,aAAa,MAAM,CAAC,OAAO,CAAC,OAAO,IAAI,cAAc,CAAC,KAAK,CAC5D,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Dimensions, Texture } from "../types.js";
2
+ export { resolveTexture } from "./resolve.js";
3
+ /**
4
+ * Render the treatment laid over a background as SVG, naming whatever it needs
5
+ * in `<defs>` after the given `id`.
6
+ *
7
+ * It is drawn between the background and whatever a template draws, so a
8
+ * texture never comes between a headline and the reader.
9
+ */
10
+ export declare function textureSvg(texture: Texture, dimensions: Dimensions, id: string): string;
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/texture/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAIvD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,UAAU,EACtB,EAAE,EAAE,MAAM,GACT,MAAM,CAUR"}
@@ -0,0 +1,20 @@
1
+ import { grainSvg } from "./grain.js";
2
+ import { dotsSvg, rulesSvg } from "./pattern.js";
3
+ export { resolveTexture } from "./resolve.js";
4
+ /**
5
+ * Render the treatment laid over a background as SVG, naming whatever it needs
6
+ * in `<defs>` after the given `id`.
7
+ *
8
+ * It is drawn between the background and whatever a template draws, so a
9
+ * texture never comes between a headline and the reader.
10
+ */
11
+ export function textureSvg(texture, dimensions, id) {
12
+ if (texture.type === "grain") {
13
+ return grainSvg(texture, dimensions, id);
14
+ }
15
+ if (texture.type === "dots") {
16
+ return dotsSvg(texture, dimensions, id);
17
+ }
18
+ return rulesSvg(texture, dimensions, id);
19
+ }
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/texture/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CACxB,OAAgB,EAChB,UAAsB,EACtB,EAAU;IAEV,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC7B,OAAO,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { Dimensions, Texture } from "../types.js";
2
+ /** A grid of dots, one to a tile. */
3
+ export declare function dotsSvg(texture: Extract<Texture, {
4
+ readonly type: "dots";
5
+ }>, dimensions: Dimensions, id: string): string;
6
+ /**
7
+ * Ruled lines, one to a tile, rotated as a set.
8
+ *
9
+ * The line runs down the middle of its tile rather than along the edge, so
10
+ * that the whole of its width is inside the tile: a stroke centred on the edge
11
+ * would have half of itself outside the tile, where the pattern does not
12
+ * repeat it, and the lines would come out half as thick as asked for.
13
+ */
14
+ export declare function rulesSvg(texture: Extract<Texture, {
15
+ readonly type: "rules";
16
+ }>, dimensions: Dimensions, id: string): string;
17
+ //# sourceMappingURL=pattern.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern.d.ts","sourceRoot":"","sources":["../../src/texture/pattern.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAiCvD,qCAAqC;AACrC,wBAAgB,OAAO,CACrB,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EACpD,UAAU,EAAE,UAAU,EACtB,EAAE,EAAE,MAAM,GACT,MAAM,CAgBR;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,EACrD,UAAU,EAAE,UAAU,EACtB,EAAE,EAAE,MAAM,GACT,MAAM,CAiBR"}
@@ -0,0 +1,45 @@
1
+ /** Used where the palette did not supply one, so a texture always draws. */
2
+ const fallbackColor = "#ffffff";
3
+ const dotDefaults = { opacity: 0.08, size: 5, gap: 44 };
4
+ const ruleDefaults = { opacity: 0.06, width: 2, gap: 28, angle: 45 };
5
+ /**
6
+ * A tiled pattern over the whole image: the `<pattern>` under the given `id`,
7
+ * and the rect that fills with it.
8
+ */
9
+ function tile(id, gap, contents, transform, dimensions, opacity) {
10
+ const { width, height } = dimensions;
11
+ const size = String(gap);
12
+ return (`<defs>` +
13
+ `<pattern id="${id}" width="${size}" height="${size}"` +
14
+ ` patternUnits="userSpaceOnUse"${transform}>${contents}</pattern>` +
15
+ `</defs>` +
16
+ `<rect width="${String(width)}" height="${String(height)}"` +
17
+ ` fill="url(#${id})" opacity="${String(opacity)}"/>`);
18
+ }
19
+ /** A grid of dots, one to a tile. */
20
+ export function dotsSvg(texture, dimensions, id) {
21
+ const gap = texture.gap ?? dotDefaults.gap;
22
+ const centre = String(gap / 2);
23
+ const dot = `<circle cx="${centre}" cy="${centre}"` +
24
+ ` r="${String((texture.size ?? dotDefaults.size) / 2)}"` +
25
+ ` fill="${texture.color ?? fallbackColor}"/>`;
26
+ return tile(id, gap, dot, "", dimensions, texture.opacity ?? dotDefaults.opacity);
27
+ }
28
+ /**
29
+ * Ruled lines, one to a tile, rotated as a set.
30
+ *
31
+ * The line runs down the middle of its tile rather than along the edge, so
32
+ * that the whole of its width is inside the tile: a stroke centred on the edge
33
+ * would have half of itself outside the tile, where the pattern does not
34
+ * repeat it, and the lines would come out half as thick as asked for.
35
+ */
36
+ export function rulesSvg(texture, dimensions, id) {
37
+ const gap = texture.gap ?? ruleDefaults.gap;
38
+ const x = String(gap / 2);
39
+ const line = `<line x1="${x}" y1="0" x2="${x}" y2="${String(gap)}"` +
40
+ ` stroke="${texture.color ?? fallbackColor}"` +
41
+ ` stroke-width="${String(texture.width ?? ruleDefaults.width)}"/>`;
42
+ const angle = texture.angle ?? ruleDefaults.angle;
43
+ return tile(id, gap, line, ` patternTransform="rotate(${String(angle)})"`, dimensions, texture.opacity ?? ruleDefaults.opacity);
44
+ }
45
+ //# sourceMappingURL=pattern.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern.js","sourceRoot":"","sources":["../../src/texture/pattern.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,MAAM,aAAa,GAAG,SAAS,CAAC;AAEhC,MAAM,WAAW,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;AACxD,MAAM,YAAY,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAErE;;;GAGG;AACH,SAAS,IAAI,CACX,EAAU,EACV,GAAW,EACX,QAAgB,EAChB,SAAiB,EACjB,UAAsB,EACtB,OAAe;IAEf,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC;IACrC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAEzB,OAAO,CACL,QAAQ;QACR,gBAAgB,EAAE,YAAY,IAAI,aAAa,IAAI,GAAG;QACtD,iCAAiC,SAAS,IAAI,QAAQ,YAAY;QAClE,SAAS;QACT,gBAAgB,MAAM,CAAC,KAAK,CAAC,aAAa,MAAM,CAAC,MAAM,CAAC,GAAG;QAC3D,eAAe,EAAE,eAAe,MAAM,CAAC,OAAO,CAAC,KAAK,CACrD,CAAC;AACJ,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,OAAO,CACrB,OAAoD,EACpD,UAAsB,EACtB,EAAU;IAEV,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC;IAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAC/B,MAAM,GAAG,GACP,eAAe,MAAM,SAAS,MAAM,GAAG;QACvC,OAAO,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG;QACxD,UAAU,OAAO,CAAC,KAAK,IAAI,aAAa,KAAK,CAAC;IAEhD,OAAO,IAAI,CACT,EAAE,EACF,GAAG,EACH,GAAG,EACH,EAAE,EACF,UAAU,EACV,OAAO,CAAC,OAAO,IAAI,WAAW,CAAC,OAAO,CACvC,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CACtB,OAAqD,EACrD,UAAsB,EACtB,EAAU;IAEV,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC;IAC5C,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAC1B,MAAM,IAAI,GACR,aAAa,CAAC,gBAAgB,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC,GAAG;QACtD,YAAY,OAAO,CAAC,KAAK,IAAI,aAAa,GAAG;QAC7C,kBAAkB,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC;IACrE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC;IAElD,OAAO,IAAI,CACT,EAAE,EACF,GAAG,EACH,IAAI,EACJ,6BAA6B,MAAM,CAAC,KAAK,CAAC,IAAI,EAC9C,UAAU,EACV,OAAO,CAAC,OAAO,IAAI,YAAY,CAAC,OAAO,CACxC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { BrandColors, Texture } from "../types.js";
2
+ /**
3
+ * Fill in the colour a texture left open, from the palette it will be drawn
4
+ * over.
5
+ *
6
+ * A dot grid or a set of rules has to be the foreground colour by default,
7
+ * because that is the one colour known to contrast with the background: a
8
+ * fixed white would disappear on a light theme, which is a texture that
9
+ * silently does nothing. Grain has no colour to fill in, being noise.
10
+ *
11
+ * It happens here rather than while drawing so that the resolved config says
12
+ * what will actually be drawn, which is also what the rebuild stamp hashes: a
13
+ * palette change then re-renders the texture that follows it.
14
+ */
15
+ export declare function resolveTexture(texture: Texture | undefined, colors: Required<BrandColors>): Texture | undefined;
16
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/texture/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAExD;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,OAAO,GAAG,SAAS,EAC5B,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,GAC5B,OAAO,GAAG,SAAS,CAMrB"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Fill in the colour a texture left open, from the palette it will be drawn
3
+ * over.
4
+ *
5
+ * A dot grid or a set of rules has to be the foreground colour by default,
6
+ * because that is the one colour known to contrast with the background: a
7
+ * fixed white would disappear on a light theme, which is a texture that
8
+ * silently does nothing. Grain has no colour to fill in, being noise.
9
+ *
10
+ * It happens here rather than while drawing so that the resolved config says
11
+ * what will actually be drawn, which is also what the rebuild stamp hashes: a
12
+ * palette change then re-renders the texture that follows it.
13
+ */
14
+ export function resolveTexture(texture, colors) {
15
+ if (texture === undefined || texture.type === "grain") {
16
+ return texture;
17
+ }
18
+ return { color: colors.foreground, ...texture };
19
+ }
20
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/texture/resolve.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAC5B,OAA4B,EAC5B,MAA6B;IAE7B,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACtD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG,OAAO,EAAE,CAAC;AAClD,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { BrandColors, ColophonConfig, ThemeName } from "../types.js";
2
+ export { themeNames } from "./presets.js";
3
+ /**
4
+ * The palette a theme brings, or `undefined` where there is no theme.
5
+ *
6
+ * It is what a partial override merges over, so that a size asking for one
7
+ * darker shade keeps the rest of the look rather than dropping back to the
8
+ * neutral default palette.
9
+ */
10
+ export declare function themePalette(theme: ThemeName | undefined): Required<BrandColors> | undefined;
11
+ /**
12
+ * Fill in the fields a theme supplies and the config did not name.
13
+ *
14
+ * A theme is applied by merging rather than by resolving, so that everything
15
+ * downstream sees an ordinary config and nothing else in the package has to
16
+ * know that themes exist. Whatever the config sets wins, field by field: this
17
+ * is `colors`, `background` and `texture` as defaults, not as a look that
18
+ * cannot be argued with.
19
+ *
20
+ * The consequence worth knowing is that a config naming its own `colors`
21
+ * alongside a theme keeps the theme's background as it was written, so the
22
+ * accent colour changes and the picture behind it does not. That follows from
23
+ * the merge, and it is the honest reading of a theme: the background is part
24
+ * of the look rather than something derived from the palette.
25
+ */
26
+ export declare function applyTheme(config: ColophonConfig): ColophonConfig;
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/theme/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG1E,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,SAAS,GAAG,SAAS,GAC3B,QAAQ,CAAC,WAAW,CAAC,GAAG,SAAS,CAEnC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAcjE"}
@@ -0,0 +1,41 @@
1
+ import { THEMES } from "./presets.js";
2
+ export { themeNames } from "./presets.js";
3
+ /**
4
+ * The palette a theme brings, or `undefined` where there is no theme.
5
+ *
6
+ * It is what a partial override merges over, so that a size asking for one
7
+ * darker shade keeps the rest of the look rather than dropping back to the
8
+ * neutral default palette.
9
+ */
10
+ export function themePalette(theme) {
11
+ return theme === undefined ? undefined : THEMES[theme].colors;
12
+ }
13
+ /**
14
+ * Fill in the fields a theme supplies and the config did not name.
15
+ *
16
+ * A theme is applied by merging rather than by resolving, so that everything
17
+ * downstream sees an ordinary config and nothing else in the package has to
18
+ * know that themes exist. Whatever the config sets wins, field by field: this
19
+ * is `colors`, `background` and `texture` as defaults, not as a look that
20
+ * cannot be argued with.
21
+ *
22
+ * The consequence worth knowing is that a config naming its own `colors`
23
+ * alongside a theme keeps the theme's background as it was written, so the
24
+ * accent colour changes and the picture behind it does not. That follows from
25
+ * the merge, and it is the honest reading of a theme: the background is part
26
+ * of the look rather than something derived from the palette.
27
+ */
28
+ export function applyTheme(config) {
29
+ const theme = config.theme === undefined ? undefined : THEMES[config.theme];
30
+ if (theme === undefined) {
31
+ return config;
32
+ }
33
+ return {
34
+ ...config,
35
+ ...(config.colors === undefined && { colors: theme.colors }),
36
+ ...(config.background === undefined && { background: theme.background }),
37
+ ...(config.texture === undefined &&
38
+ theme.texture !== undefined && { texture: theme.texture }),
39
+ };
40
+ }
41
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/theme/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,KAA4B;IAE5B,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;AAChE,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,UAAU,CAAC,MAAsB;IAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAE5E,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO;QACL,GAAG,MAAM;QACT,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;QAC5D,GAAG,CAAC,MAAM,CAAC,UAAU,KAAK,SAAS,IAAI,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC;QACxE,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS;YAC9B,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;KAC7D,CAAC;AACJ,CAAC"}
@@ -0,0 +1,38 @@
1
+ import type { Background, BrandColors, Texture, ThemeName } from "../types.js";
2
+ /**
3
+ * What a named theme sets. Every field is an ordinary config option, because
4
+ * that is all a theme is: a set of defaults for fields a project could have
5
+ * written out itself, and would rather not.
6
+ */
7
+ export interface Theme {
8
+ readonly colors: Required<BrandColors>;
9
+ readonly background: Background;
10
+ readonly texture?: Texture;
11
+ }
12
+ /**
13
+ * The curated set.
14
+ *
15
+ * Each one is a whole look rather than a palette, which is why the background
16
+ * is written out here instead of being derived from the colours: `midnight`
17
+ * without its mesh and `slate` without its dot grid are the same flat image in
18
+ * two shades of navy. Deriving would also mean a theme could only ever be the
19
+ * one gradient the defaults already give.
20
+ *
21
+ * Six of them are dark, since white text on a deep background is what a share
22
+ * image is usually asked to be, and two are light, because a site whose own
23
+ * pages are light has nothing to reach for otherwise.
24
+ *
25
+ * None of them turns grain on, though it is the treatment they would most
26
+ * obviously want. Per-pixel noise does not compress, and it takes a
27
+ * 1200x1200 PNG from around 600KB to a little over 2MB: a cost worth paying
28
+ * on purpose, and not one to hand someone who picked a theme by its name and
29
+ * is committing the images next to their posts.
30
+ */
31
+ export declare const THEMES: Readonly<Record<ThemeName, Theme>>;
32
+ /**
33
+ * The theme names, for validation and for anything listing them. Asserted
34
+ * rather than written out again, because `Object.keys` loses the key type and
35
+ * a second copy of the list is one that can drift from the set above.
36
+ */
37
+ export declare const themeNames: readonly ThemeName[];
38
+ //# sourceMappingURL=presets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/theme/presets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE/E;;;;GAIG;AACH,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IACvC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAkIrD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAA0B,SAAS,SAAS,EAAE,CAAC"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * The curated set.
3
+ *
4
+ * Each one is a whole look rather than a palette, which is why the background
5
+ * is written out here instead of being derived from the colours: `midnight`
6
+ * without its mesh and `slate` without its dot grid are the same flat image in
7
+ * two shades of navy. Deriving would also mean a theme could only ever be the
8
+ * one gradient the defaults already give.
9
+ *
10
+ * Six of them are dark, since white text on a deep background is what a share
11
+ * image is usually asked to be, and two are light, because a site whose own
12
+ * pages are light has nothing to reach for otherwise.
13
+ *
14
+ * None of them turns grain on, though it is the treatment they would most
15
+ * obviously want. Per-pixel noise does not compress, and it takes a
16
+ * 1200x1200 PNG from around 600KB to a little over 2MB: a cost worth paying
17
+ * on purpose, and not one to hand someone who picked a theme by its name and
18
+ * is committing the images next to their posts.
19
+ */
20
+ export const THEMES = {
21
+ midnight: {
22
+ colors: {
23
+ brand: "#6366f1",
24
+ brandDark: "#0b1020",
25
+ brandWarm: "#a855f7",
26
+ foreground: "#e6e9f5",
27
+ },
28
+ background: {
29
+ type: "mesh",
30
+ color: "#0b1020",
31
+ blobs: [
32
+ { color: "#4338ca", x: 0.12, y: 0.05, radius: 0.55, opacity: 0.85 },
33
+ { color: "#7c3aed", x: 0.9, y: 0.85, radius: 0.5, opacity: 0.7 },
34
+ { color: "#1d4ed8", x: 0.6, y: 1, radius: 0.4, opacity: 0.45 },
35
+ ],
36
+ },
37
+ texture: { type: "dots", opacity: 0.05 },
38
+ },
39
+ aurora: {
40
+ colors: {
41
+ brand: "#14b8a6",
42
+ brandDark: "#04211f",
43
+ brandWarm: "#8b5cf6",
44
+ foreground: "#ecfdf5",
45
+ },
46
+ background: {
47
+ type: "mesh",
48
+ color: "#04211f",
49
+ blobs: [
50
+ { color: "#14b8a6", x: 0.15, y: 0.85, radius: 0.7, opacity: 0.85 },
51
+ { color: "#22d3ee", x: 0.75, y: 0.15, radius: 0.6, opacity: 0.7 },
52
+ { color: "#8b5cf6", x: 1, y: 0.9, radius: 0.5, opacity: 0.55 },
53
+ ],
54
+ },
55
+ },
56
+ ember: {
57
+ colors: {
58
+ brand: "#f97316",
59
+ brandDark: "#1a0b06",
60
+ brandWarm: "#ef4444",
61
+ foreground: "#fff7ed",
62
+ },
63
+ background: {
64
+ type: "gradient",
65
+ stops: [
66
+ { offset: "0%", color: "#1a0b06" },
67
+ { offset: "55%", color: "#7c2d12" },
68
+ { offset: "100%", color: "#ea580c" },
69
+ ],
70
+ },
71
+ },
72
+ forest: {
73
+ colors: {
74
+ brand: "#22c55e",
75
+ brandDark: "#04140c",
76
+ brandWarm: "#a3e635",
77
+ foreground: "#ecfdf5",
78
+ },
79
+ background: {
80
+ type: "gradient",
81
+ stops: [
82
+ { offset: "0%", color: "#04140c" },
83
+ { offset: "55%", color: "#14532d" },
84
+ { offset: "100%", color: "#166534" },
85
+ ],
86
+ },
87
+ texture: { type: "rules", opacity: 0.05 },
88
+ },
89
+ bloom: {
90
+ colors: {
91
+ brand: "#ec4899",
92
+ brandDark: "#2e1065",
93
+ brandWarm: "#f59e0b",
94
+ foreground: "#fdf4ff",
95
+ },
96
+ background: {
97
+ type: "mesh",
98
+ color: "#2e1065",
99
+ blobs: [
100
+ { color: "#db2777", x: 0.2, y: 0.2, radius: 0.8, opacity: 0.85 },
101
+ { color: "#f472b6", x: 0.9, y: 0.35, radius: 0.5, opacity: 0.5 },
102
+ { color: "#7c3aed", x: 0.5, y: 1, radius: 0.75, opacity: 0.8 },
103
+ ],
104
+ },
105
+ },
106
+ slate: {
107
+ colors: {
108
+ brand: "#38bdf8",
109
+ brandDark: "#0f172a",
110
+ brandWarm: "#64748b",
111
+ foreground: "#f1f5f9",
112
+ },
113
+ background: { type: "solid", color: "#0f172a" },
114
+ texture: { type: "dots", opacity: 0.07 },
115
+ },
116
+ paper: {
117
+ colors: {
118
+ brand: "#b45309",
119
+ brandDark: "#78350f",
120
+ brandWarm: "#d97706",
121
+ foreground: "#1c1917",
122
+ },
123
+ background: { type: "solid", color: "#faf7f0" },
124
+ texture: { type: "rules", opacity: 0.05 },
125
+ },
126
+ sandstone: {
127
+ colors: {
128
+ brand: "#c2410c",
129
+ brandDark: "#9a3412",
130
+ brandWarm: "#f59e0b",
131
+ foreground: "#292524",
132
+ },
133
+ background: {
134
+ type: "gradient",
135
+ stops: [
136
+ { offset: "0%", color: "#fdf6ec" },
137
+ { offset: "55%", color: "#f7e6cf" },
138
+ { offset: "100%", color: "#f2d5b3" },
139
+ ],
140
+ },
141
+ texture: { type: "dots", opacity: 0.06 },
142
+ },
143
+ };
144
+ /**
145
+ * The theme names, for validation and for anything listing them. Asserted
146
+ * rather than written out again, because `Object.keys` loses the key type and
147
+ * a second copy of the list is one that can drift from the set above.
148
+ */
149
+ export const themeNames = Object.keys(THEMES);
150
+ //# sourceMappingURL=presets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.js","sourceRoot":"","sources":["../../src/theme/presets.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,MAAM,GAAuC;IACxD,QAAQ,EAAE;QACR,MAAM,EAAE;YACN,KAAK,EAAE,SAAS;YAChB,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,SAAS;YACpB,UAAU,EAAE,SAAS;SACtB;QACD,UAAU,EAAE;YACV,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE;gBACL,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE;gBACnE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE;gBAChE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE;aAC/D;SACF;QACD,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;KACzC;IAED,MAAM,EAAE;QACN,MAAM,EAAE;YACN,KAAK,EAAE,SAAS;YAChB,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,SAAS;YACpB,UAAU,EAAE,SAAS;SACtB;QACD,UAAU,EAAE;YACV,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE;gBACL,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE;gBAClE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE;gBACjE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE;aAC/D;SACF;KACF;IAED,KAAK,EAAE;QACL,MAAM,EAAE;YACN,KAAK,EAAE,SAAS;YAChB,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,SAAS;YACpB,UAAU,EAAE,SAAS;SACtB;QACD,UAAU,EAAE;YACV,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE;gBACL,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE;gBAClC,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE;gBACnC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE;aACrC;SACF;KACF;IAED,MAAM,EAAE;QACN,MAAM,EAAE;YACN,KAAK,EAAE,SAAS;YAChB,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,SAAS;YACpB,UAAU,EAAE,SAAS;SACtB;QACD,UAAU,EAAE;YACV,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE;gBACL,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE;gBAClC,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE;gBACnC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE;aACrC;SACF;QACD,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;KAC1C;IAED,KAAK,EAAE;QACL,MAAM,EAAE;YACN,KAAK,EAAE,SAAS;YAChB,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,SAAS;YACpB,UAAU,EAAE,SAAS;SACtB;QACD,UAAU,EAAE;YACV,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE;gBACL,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE;gBAChE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE;gBAChE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE;aAC/D;SACF;KACF;IAED,KAAK,EAAE;QACL,MAAM,EAAE;YACN,KAAK,EAAE,SAAS;YAChB,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,SAAS;YACpB,UAAU,EAAE,SAAS;SACtB;QACD,UAAU,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE;QAC/C,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;KACzC;IAED,KAAK,EAAE;QACL,MAAM,EAAE;YACN,KAAK,EAAE,SAAS;YAChB,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,SAAS;YACpB,UAAU,EAAE,SAAS;SACtB;QACD,UAAU,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE;QAC/C,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;KAC1C;IAED,SAAS,EAAE;QACT,MAAM,EAAE;YACN,KAAK,EAAE,SAAS;YAChB,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,SAAS;YACpB,UAAU,EAAE,SAAS;SACtB;QACD,UAAU,EAAE;YACV,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE;gBACL,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE;gBAClC,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE;gBACnC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE;aACrC;SACF;QACD,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;KACzC;CACF,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAyB,CAAC"}