@arraypress/covers 1.4.0 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -0
- package/README.md +1 -1
- package/package.json +2 -2
- package/recipes/flyers/construction.json +36 -0
- package/recipes/flyers/dissolve-poster.json +72 -0
- package/recipes/flyers/fluted-poster.json +105 -0
- package/recipes/flyers/series-card.json +81 -0
- package/schema/recipe.schema.json +556 -2
- package/src/index.d.ts +5 -5
- package/src/layer-options.js +3 -1
- package/src/layers/construction.d.ts +34 -0
- package/src/layers/construction.js +137 -0
- package/src/layers/focal.d.ts +8 -0
- package/src/layers/focal.js +109 -0
- package/src/layers/guides.d.ts +38 -0
- package/src/layers/guides.js +212 -0
- package/src/layers/index.d.ts +6 -0
- package/src/layers/index.js +3 -0
- package/src/layers/isolines.d.ts +21 -0
- package/src/layers/isolines.js +271 -0
- package/src/layers/mark-draw.d.ts +21 -0
- package/src/layers/mark-draw.js +93 -0
- package/src/layers/outline.d.ts +26 -0
- package/src/layers/outline.js +105 -0
- package/src/layers.js +10 -4
- package/src/version.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,55 @@ All notable changes to `@arraypress/covers` are documented here.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.6.1] — 2026-11-06
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **`image` `focus` points** (with sharp): `[x, y]` (0–1 in the photo) centres that point in the box, and `'subject'` centres a cut-out's head across (the alpha-weighted centre of the top 45% of its opaque rows), its top at the box's top. A cut-out moves freely sideways, the ground showing round it; an opaque photo keeps its box filled. Without sharp, `'subject'` falls back to `'top'` and a point to `'center'`.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- **`dissolve-poster`**: the cut-out runs full bleed and is centred on its face (`focus: 'subject'`; `focus: [x, y]` overrides), so a cropped top runs off the poster instead of showing a flat cut. The fade starts lower so the eyes stay clean: from 0.5 without a title, and 0.24 above the merge with one.
|
|
17
|
+
|
|
18
|
+
## [1.6.0] — 2026-11-06
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- **`dissolve-poster`**, on the 400-wide grid (4:5, 1:1, 9:16): one flat strong ground (red `#e10a14` by default), the subject in the ink (a `cutout` or `photo` portrait, its tones mapped from the ink to the ground, or the mark large with no photo) dissolving into the ground through a growing diamond dot screen, tiny at the top of the fade and merging at its foot, a few seeded strays above. Small Swiss corner type (the name, a series or Vol. line, a credit, the year) and an optional big tight `title` along the foot sit over the dissolve; with a title the dots merge just above it. Options `ground`, `ink`, `dots` (default the ground), `direction`, `fadeStart`, `fadeEnd`, `cell`.
|
|
23
|
+
- The `halftoneFade` effect from `@logomarks/image-effects` 0.4.0 on any layer, and in the schema.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- Depends on `@logomarks/image-effects` `^0.4.0`.
|
|
28
|
+
|
|
29
|
+
## [1.5.2] — 2026-11-06
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- **`fluted-poster`**: `subject: 'name'` now sets the name's initial huge behind the glass, filling the height between the year and the title (stretched taller on tall canvases), the way a single letter stays legible and glassy behind ribs; the full name stays in the title and corner type. `initial` overrides the letter (one or two characters). The whole name across the width is `subject: 'word'`. With no mark, the initial is drawn.
|
|
34
|
+
- The gentle convex glass 1.5.1 gave the name is gone: every subject uses the `fluted` preset unless `preset` names another.
|
|
35
|
+
|
|
36
|
+
## [1.5.1] — 2026-11-06
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
|
|
40
|
+
- **`fluted-poster`** keeps the name readable: with `subject: 'name'` (or no mark) and no `preset`, the glass is gentler (12 convex ribs at refraction 0.15, little defocus, chroma 0.2), so the word steps at the rib edges but never doubles. A `preset` given is used as it is; the mark keeps the `fluted` preset. `preset` now defaults to `''` (the subject's default).
|
|
41
|
+
|
|
42
|
+
## [1.5.0] — 2026-11-06
|
|
43
|
+
|
|
44
|
+
Three more posters on the 400-wide grid, and the layers they stand on. Every published recipe renders as before (157 SVGs, flyers at 4:5 and as release covers, the release styles and the built-ins, byte-identical to 1.4.0).
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
|
|
48
|
+
- **Three posters**, drawn on a 400-wide grid as tall as the canvas, so they set at 4:5, 1:1, 9:16 and A-series portrait alike: `construction` (a construction sheet: the mark large over its own construction, read from its paths, a dashed grid, its box, a centre cross, the inscribed and circumscribed circles, the circles its curves are drawn on and the lines its straight edges lie on, in one thin accent; meta in the corners; dark or light by `ground` and `ink`), `fluted-poster` (the mark, or the name set huge, in white on black behind fluted glass, a soft light in one accent behind it, and vector Swiss type over it: the year stacked, the series, a two-line title with a glitched `||` of bars, credits and an edition line; `preset` picks the glass) and `series-card` (a numbered card for a run of posts: a flat soft colour, a two-line title, a large number and the mark solid or as contour lines).
|
|
49
|
+
- **`construction` layer**: a mark over its construction guides (`markGuides`: circles fitted to its arcs and Béziers, lines along its straight edges, added up where several lie on one); `grid`, `size`, `circles`, `lines`, `color`, `gridColor`, `gridOpacity`, `markColor`, `over` (the guides shown faintly over the mark), `stroke`.
|
|
50
|
+
- **`outline` layer**: a mark fitted by its real bounds and drawn as contour lines, its outline and `lines − 1` more `gap` apart (isolines of its signed distance field, from `@logomarks/core`'s raster fill and distance transform, measured exactly to its edges where the lines run, so parts merge as contours do and cusps stay sharp), out or `in`; `lines: 0` draws it solid.
|
|
51
|
+
- The image effects of `@logomarks/image-effects` 0.2–0.3 on any layer, and in the schema: `fluted` (reeded glass; presets `fluted`, `reeded-deep`, `reeded-prism`, `reeded-soft`) and `print` (letterpress, riso and stamp finishes).
|
|
52
|
+
|
|
53
|
+
### Changed
|
|
54
|
+
|
|
55
|
+
- Depends on `@logomarks/image-effects` `^0.3.2`.
|
|
56
|
+
|
|
8
57
|
## [1.4.0] — 2026-11-06
|
|
9
58
|
|
|
10
59
|
Three flyers that set on any canvas, and the layers they stand on. Every published recipe renders as before (185 SVGs, flyers at 4:5 and as release covers plus the built-ins, byte-identical to 1.3.1).
|
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ await writeFile('public/covers/introducing-covers.webp', webp);
|
|
|
36
36
|
- [API](https://github.com/arraypress/covers/blob/main/docs/api.md): every export and cover option
|
|
37
37
|
- [Layers](https://github.com/arraypress/covers/blob/main/docs/layers.md): mesh, grain, text, diagrams, riso inks, dithers, poster type and more
|
|
38
38
|
- [Effects](https://github.com/arraypress/covers/blob/main/docs/effects.md): filters and pixel effects on any layer, masks, paints
|
|
39
|
-
- [Recipes](https://github.com/arraypress/covers/blob/main/docs/recipes.md): seventeen built-ins,
|
|
39
|
+
- [Recipes](https://github.com/arraypress/covers/blob/main/docs/recipes.md): seventeen built-ins, 91 flyers and release covers, your own
|
|
40
40
|
- [JSON recipes](https://github.com/arraypress/covers/blob/main/docs/json-recipes.md): a cover style as data, with no JavaScript
|
|
41
41
|
- [Palettes](https://github.com/arraypress/covers/blob/main/docs/palettes.md): presets, one accent, a theme's tokens
|
|
42
42
|
- [Formats, print and brand kits](https://github.com/arraypress/covers/blob/main/docs/formats.md): social sizes with safe zones, print with bleed, `kit`, `lint`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arraypress/covers",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "Covers, flyers, posters, release art, social formats and print stationery from one seed and a stack of layers: mesh gradients, grain, riso inks and halftones, knockout and justified type, torn paper, barcodes, safe zones and bleed, as SVG or WebP/PNG/AVIF/JPEG. Recipes are JSON. Runs in Node, browsers and Cloudflare Workers.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"dependencies": {
|
|
87
87
|
"@arraypress/color-utils": "^1.3.0",
|
|
88
88
|
"@logomarks/core": "^0.1.5",
|
|
89
|
-
"@logomarks/image-effects": "^0.
|
|
89
|
+
"@logomarks/image-effects": "^0.4.0",
|
|
90
90
|
"harfbuzzjs": "^1.6.3"
|
|
91
91
|
},
|
|
92
92
|
"peerDependencies": {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../schema/recipe.schema.json",
|
|
3
|
+
"name": "construction",
|
|
4
|
+
"description": "Construction sheet: the mark large and centred over its own construction, read from its paths: a light dashed square grid behind (cells an eighth of the mark by default, centred on it), its bounding box, a centre cross, the circles inscribed in its box and round its outline, the circles its curves are drawn on (each centre marked) and the lines its straight edges lie on, run across the sheet, all in one thin accent (blue by default) and showing faintly over the mark. Small meta in the corners: a label and the name across the top, the grid's size and a ® (or any caption) along the foot. A dark ground by default; set ground and ink for a light one. Drawn on a 400-wide grid as tall as the canvas, so it sets at 4:5, 1:1, 9:16 and A-series portrait alike.",
|
|
5
|
+
"requires": ["mark"],
|
|
6
|
+
"params": {
|
|
7
|
+
"name": "Kestrel",
|
|
8
|
+
"meta": "Construction · v1.0",
|
|
9
|
+
"gridLabel": "",
|
|
10
|
+
"caption": "®",
|
|
11
|
+
"grid": 8,
|
|
12
|
+
"size": 0.58,
|
|
13
|
+
"ground": "#0b0b0c",
|
|
14
|
+
"ink": "#f2f1ec",
|
|
15
|
+
"accent": "#3b82f6"
|
|
16
|
+
},
|
|
17
|
+
"vars": {
|
|
18
|
+
"h": { "mul": [400, { "div": ["@height", "@width"] }] }
|
|
19
|
+
},
|
|
20
|
+
"layers": [
|
|
21
|
+
{ "id": "ground", "type": "solid", "color": "{ground}" },
|
|
22
|
+
{
|
|
23
|
+
"id": "sheet",
|
|
24
|
+
"type": "group",
|
|
25
|
+
"viewBox": [0, 0, 400, "$h"],
|
|
26
|
+
"fit": "contain",
|
|
27
|
+
"layers": [
|
|
28
|
+
{ "id": "construction", "type": "construction", "markup": "{mark}", "x": 16, "y": 40, "width": 368, "height": { "sub": ["$h", 80] }, "size": "{size}", "grid": "{grid}", "color": "{accent}", "markColor": "{ink}", "stroke": 0.55 },
|
|
29
|
+
{ "id": "meta", "type": "text", "content": "{meta}", "when": "meta", "font": "Inter Tight", "weight": 500, "size": 7, "letterSpacing": 0, "x": 16, "y": 24, "maxWidth": 200, "maxLines": 1, "color": "{ink}" },
|
|
30
|
+
{ "id": "name", "type": "text", "content": "{name}", "when": "name", "font": "Inter Tight", "weight": 600, "size": 7, "letterSpacing": 0, "x": 384, "y": 24, "align": "right", "maxWidth": 160, "maxLines": 1, "color": "{ink}" },
|
|
31
|
+
{ "id": "gridLabel", "type": "text", "content": { "if": "gridLabel", "then": "{gridLabel}", "else": { "join": [["Grid ", "{grid}", " × ", "{grid}"], ""] } }, "when": { "any": ["gridLabel", "grid"] }, "font": "Inter Tight", "weight": 500, "size": 7, "letterSpacing": 0, "x": 16, "y": { "sub": ["$h", 18] }, "maxWidth": 200, "maxLines": 1, "color": "{ink}", "opacity": 0.6 },
|
|
32
|
+
{ "id": "caption", "type": "text", "content": "{caption}", "when": "caption", "font": "Inter Tight", "weight": 500, "size": 9, "letterSpacing": 0, "x": 384, "y": { "sub": ["$h", 17] }, "align": "right", "maxWidth": 160, "maxLines": 1, "color": "{ink}" }
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../schema/recipe.schema.json",
|
|
3
|
+
"name": "dissolve-poster",
|
|
4
|
+
"description": "Halftone dissolve poster: one flat strong ground (red by default), the subject in the ink over it (a portrait, cut out or plain, its tones mapped from the ink to the ground; or, with no photo, the mark large), dissolving into the ground through a growing dot screen (@logomarks/image-effects' halftoneFade): tiny dots at the top of the fade, growing and merging at its foot, a few strays above, in the ground colour unless dots names another. By default the dots begin at half the height and merge by 92%; with a title they merge just above it, so the title stands on clear ground (fadeStart and fadeEnd, 0–1, set them). A cut-out runs full bleed, centred across on its face (focus [x, y], 0–1 in the photo, overrides), so a cropped top runs off the poster. Over it, small Swiss type the dots never touch: the name and a Vol. line across the top, an optional big tight title along the foot, a credit and the year under it. Drawn on a 400-wide grid as tall as the canvas, so it sets at 4:5, 1:1 and 9:16 alike; the strays follow the seed.",
|
|
5
|
+
"params": {
|
|
6
|
+
"name": "Kestrel",
|
|
7
|
+
"series": "Vol. 07 — Dissolve",
|
|
8
|
+
"year": "2026",
|
|
9
|
+
"credit": "",
|
|
10
|
+
"title": "",
|
|
11
|
+
"ground": "#e10a14",
|
|
12
|
+
"ink": "#0a0a0a",
|
|
13
|
+
"dots": "",
|
|
14
|
+
"direction": "up",
|
|
15
|
+
"fadeStart": "",
|
|
16
|
+
"fadeEnd": "",
|
|
17
|
+
"cell": "2.2vmin",
|
|
18
|
+
"focus": ""
|
|
19
|
+
},
|
|
20
|
+
"vars": {
|
|
21
|
+
"h": { "mul": [400, { "div": ["@height", "@width"] }] },
|
|
22
|
+
"end": { "if": "fadeEnd", "then": "{fadeEnd}", "else": { "if": "title", "then": { "sub": [0.78, { "div": [40, "$h"] }] }, "else": 0.92 } },
|
|
23
|
+
"start": { "if": "fadeStart", "then": "{fadeStart}", "else": { "if": "title", "then": { "sub": ["$end", 0.24] }, "else": { "min": [0.5, { "sub": ["$end", 0.1] }] } } }
|
|
24
|
+
},
|
|
25
|
+
"layers": [
|
|
26
|
+
{ "id": "ground", "type": "solid", "color": "{ground}" },
|
|
27
|
+
{
|
|
28
|
+
"id": "subject",
|
|
29
|
+
"type": "group",
|
|
30
|
+
"viewBox": [0, 0, 400, "$h"],
|
|
31
|
+
"fit": "contain",
|
|
32
|
+
"effects": [{ "kind": "halftoneFade", "color": { "if": "dots", "then": "{dots}", "else": "{ground}" }, "direction": "{direction}", "start": "$start", "end": "$end", "cell": "{cell}", "grid": "diamond", "shape": "dot", "jitter": 0.3 }],
|
|
33
|
+
"layers": [
|
|
34
|
+
{ "id": "field", "type": "solid", "color": "{ground}" },
|
|
35
|
+
{ "id": "cutout", "type": "image", "when": "cutout", "src": "{cutout}", "fit": "cover", "focus": { "if": "focus", "then": "{focus}", "else": "subject" }, "duotone": ["{ink}", "{ground}"] },
|
|
36
|
+
{ "id": "photo", "type": "image", "when": { "all": ["photo", { "not": "cutout" }] }, "src": "{photo}", "fit": "cover", "focus": { "if": "focus", "then": "{focus}", "else": "center" }, "duotone": ["{ink}", "{ground}"] },
|
|
37
|
+
{ "id": "mark", "type": "outline", "when": { "all": ["mark", { "not": "cutout" }, { "not": "photo" }] }, "markup": "{mark}", "lines": 0, "x": 40, "y": 60, "width": 320, "height": { "sub": ["$h", 120] }, "color": "{ink}" }
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": "type",
|
|
42
|
+
"type": "group",
|
|
43
|
+
"viewBox": [0, 0, 400, "$h"],
|
|
44
|
+
"fit": "contain",
|
|
45
|
+
"layers": [
|
|
46
|
+
{ "id": "name", "type": "text", "content": "{name}", "when": "name", "font": "Inter Tight", "weight": 700, "size": 8, "letterSpacing": 0, "x": 16, "y": 24, "maxWidth": 180, "maxLines": 1, "color": "{ink}" },
|
|
47
|
+
{ "id": "series", "type": "text", "content": "{series}", "when": "series", "font": "Inter Tight", "weight": 500, "size": 8, "letterSpacing": 0, "x": 384, "y": 24, "align": "right", "maxWidth": 180, "maxLines": 1, "color": "{ink}" },
|
|
48
|
+
{
|
|
49
|
+
"id": "title",
|
|
50
|
+
"type": "text",
|
|
51
|
+
"content": "{title}",
|
|
52
|
+
"when": "title",
|
|
53
|
+
"transform": "uppercase",
|
|
54
|
+
"font": "Inter Tight",
|
|
55
|
+
"weight": 800,
|
|
56
|
+
"size": 80,
|
|
57
|
+
"lineHeight": 0.86,
|
|
58
|
+
"letterSpacing": -0.05,
|
|
59
|
+
"fit": "width",
|
|
60
|
+
"maxWidth": 368,
|
|
61
|
+
"maxHeight": { "mul": ["$h", 0.22] },
|
|
62
|
+
"anchor": "bottom-left",
|
|
63
|
+
"margin": 0,
|
|
64
|
+
"offset": { "x": 16, "y": -34 },
|
|
65
|
+
"color": "{ink}"
|
|
66
|
+
},
|
|
67
|
+
{ "id": "credit", "type": "text", "content": { "if": "credit", "then": "{credit}", "else": "Design — {name}" }, "font": "Inter Tight", "weight": 500, "size": 7, "letterSpacing": 0, "x": 16, "y": { "sub": ["$h", 16] }, "maxWidth": 200, "maxLines": 1, "color": "{ink}" },
|
|
68
|
+
{ "id": "year", "type": "text", "content": "{year}", "when": "year", "font": "Inter Tight", "weight": 500, "size": 7, "letterSpacing": 0, "x": 384, "y": { "sub": ["$h", 16] }, "align": "right", "maxWidth": 100, "maxLines": 1, "color": "{ink}" }
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../schema/recipe.schema.json",
|
|
3
|
+
"name": "fluted-poster",
|
|
4
|
+
"description": "Fluted glass poster: a subject in white on black, seen through reeded glass (@logomarks/image-effects' fluted effect, its fluted preset unless preset names another: reeded-deep, reeded-prism, reeded-soft): the mark (subject 'mark', the default), the name's initial set huge, filling the height between the year and the title (about two thirds of a 4:5 poster, three quarters of a 9:16 one, stretched taller there) (subject 'name', or with no mark; initial overrides it, one or two characters), or the whole name across the width (subject 'word'). A soft light in one accent colour sits behind it (none with accent \"\"). Over the glass, small Swiss type stays vector: the year stacked large top-left, the series top-right, a two-line title bottom-left with a glitched || ornament of plain bars right of it in the accent, credits and an edition line along the foot. The glass is rastered at the output size and embedded; the type is outlines. Drawn on a 400-wide grid as tall as the canvas, so it sets at 4:5, 1:1, 9:16 and A-series portrait alike; the ornament's glitch follows the seed.",
|
|
5
|
+
"params": {
|
|
6
|
+
"name": "Kestrel",
|
|
7
|
+
"subject": "mark",
|
|
8
|
+
"preset": "",
|
|
9
|
+
"initial": "",
|
|
10
|
+
"title": ["Through", "the glass"],
|
|
11
|
+
"year": "2026",
|
|
12
|
+
"series": "",
|
|
13
|
+
"credits": "",
|
|
14
|
+
"edition": "Posters / Series 03",
|
|
15
|
+
"accent": "#ff4d1a",
|
|
16
|
+
"ground": "#000000",
|
|
17
|
+
"ink": "#ffffff"
|
|
18
|
+
},
|
|
19
|
+
"vars": {
|
|
20
|
+
"h": { "mul": [400, { "div": ["@height", "@width"] }] },
|
|
21
|
+
"bar": { "if": "accent", "then": "{accent}", "else": "{ink}" },
|
|
22
|
+
"tall": { "min": [2, { "max": [1, { "div": ["$h", 380] }] }] },
|
|
23
|
+
"s1": { "range": [-3, 3] },
|
|
24
|
+
"s2": { "range": [-3, 3] },
|
|
25
|
+
"s3": { "range": [-3, 3] },
|
|
26
|
+
"cut": { "range": [0.3, 0.6] }
|
|
27
|
+
},
|
|
28
|
+
"layers": [
|
|
29
|
+
{ "id": "ground", "type": "solid", "color": "{ground}" },
|
|
30
|
+
{
|
|
31
|
+
"id": "glass",
|
|
32
|
+
"type": "group",
|
|
33
|
+
"viewBox": [0, 0, 400, "$h"],
|
|
34
|
+
"fit": "contain",
|
|
35
|
+
"effects": [{ "kind": "fluted", "preset": { "if": "preset", "then": "{preset}", "else": "fluted" } }],
|
|
36
|
+
"layers": [
|
|
37
|
+
{ "id": "light", "type": "radial", "when": "accent", "x": 0.5, "y": 0.47, "colors": ["{accent}", "{ground}"], "radius": "52vmin", "opacity": 0.75 },
|
|
38
|
+
{ "id": "mark", "type": "outline", "when": { "all": ["mark", { "subject": "mark" }] }, "markup": "{mark}", "lines": 0, "x": 70, "y": { "sub": [{ "mul": ["$h", 0.47] }, 130] }, "width": 260, "height": 260, "color": "{ink}" },
|
|
39
|
+
{
|
|
40
|
+
"id": "initial",
|
|
41
|
+
"type": "group",
|
|
42
|
+
"when": { "any": [{ "subject": "name" }, { "all": [{ "not": "mark" }, { "subject": "mark" }] }] },
|
|
43
|
+
"transform": { "scale": [1, "$tall"], "origin": [200, { "div": [{ "sub": ["$h", 36] }, 2] }] },
|
|
44
|
+
"layers": [
|
|
45
|
+
{ "id": "letter", "type": "text", "content": { "if": "initial", "then": { "slice": ["{initial}", 0, 2] }, "else": { "slice": ["{name}", 0, 1] } }, "transform": "uppercase", "font": "Inter Tight", "weight": 800, "size": 400, "lineHeight": 0.73, "letterSpacing": -0.04, "fit": "width", "maxWidth": 330, "maxHeight": { "div": [{ "sub": ["$h", 164] }, "$tall"] }, "anchor": "center", "margin": 0, "offset": { "x": 0, "y": -18 }, "color": "{ink}" }
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "word",
|
|
50
|
+
"type": "group",
|
|
51
|
+
"when": { "subject": "word" },
|
|
52
|
+
"transform": { "scale": [1, "$tall"], "origin": [200, { "mul": ["$h", 0.47] }] },
|
|
53
|
+
"layers": [
|
|
54
|
+
{ "id": "name", "type": "text", "content": "{name}", "transform": "uppercase", "font": "Inter Tight", "weight": 800, "size": 120, "lineHeight": 0.9, "letterSpacing": -0.05, "fit": "width", "maxWidth": 360, "maxHeight": { "div": [{ "mul": ["$h", 0.42] }, "$tall"] }, "anchor": "center", "margin": 0, "offset": { "x": 0, "y": { "mul": ["$h", -0.03] } }, "color": "{ink}" }
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"id": "type",
|
|
61
|
+
"type": "group",
|
|
62
|
+
"viewBox": [0, 0, 400, "$h"],
|
|
63
|
+
"fit": "contain",
|
|
64
|
+
"layers": [
|
|
65
|
+
{ "id": "year", "type": "text", "when": "year", "content": [{ "slice": ["{year}", 0, 2] }, { "slice": ["{year}", 2] }], "font": "Inter Tight", "weight": 700, "size": 26, "lineHeight": 0.86, "letterSpacing": -0.04, "x": 15, "y": 36, "color": "{ink}" },
|
|
66
|
+
{ "id": "series", "type": "text", "content": { "if": "series", "then": "{series}", "else": "{name}\nGlass series" }, "font": "Inter Tight", "weight": 500, "size": 7, "lineHeight": 1.25, "letterSpacing": 0, "x": 384, "y": 24, "align": "right", "maxWidth": 140, "maxLines": 3, "color": "{ink}" },
|
|
67
|
+
{
|
|
68
|
+
"id": "title",
|
|
69
|
+
"type": "text",
|
|
70
|
+
"content": "{title}",
|
|
71
|
+
"when": "title",
|
|
72
|
+
"transform": "uppercase",
|
|
73
|
+
"font": "Inter Tight",
|
|
74
|
+
"weight": 700,
|
|
75
|
+
"size": 24,
|
|
76
|
+
"lineHeight": 0.92,
|
|
77
|
+
"letterSpacing": -0.035,
|
|
78
|
+
"fit": "shrink",
|
|
79
|
+
"maxWidth": 300,
|
|
80
|
+
"maxLines": 2,
|
|
81
|
+
"anchor": "bottom-left",
|
|
82
|
+
"margin": 0,
|
|
83
|
+
"offset": { "x": 15, "y": -46 },
|
|
84
|
+
"color": "{ink}"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"id": "ornament",
|
|
88
|
+
"type": "shape",
|
|
89
|
+
"fill": "$bar",
|
|
90
|
+
"items": [
|
|
91
|
+
{ "kind": "rect", "x": 362, "y": { "sub": ["$h", 90] }, "width": 5, "height": { "mul": [44, "$cut"] } },
|
|
92
|
+
{ "kind": "rect", "x": { "add": [362, "$s1"] }, "y": { "add": [{ "sub": ["$h", 90] }, { "mul": [44, "$cut"] }, 1.5] }, "width": 5, "height": 5 },
|
|
93
|
+
{ "kind": "rect", "x": 362, "y": { "add": [{ "sub": ["$h", 90] }, { "mul": [44, "$cut"] }, 8] }, "width": 5, "height": { "sub": [36, { "mul": [44, "$cut"] }] } },
|
|
94
|
+
{ "kind": "rect", "x": 375, "y": { "sub": ["$h", 90] }, "width": 5, "height": { "sub": [36, { "mul": [44, "$cut"] }] } },
|
|
95
|
+
{ "kind": "rect", "x": { "add": [375, "$s2"] }, "y": { "add": [{ "sub": ["$h", 90] }, { "sub": [36, { "mul": [44, "$cut"] }] }, 1.5] }, "width": 5, "height": 5 },
|
|
96
|
+
{ "kind": "rect", "x": { "add": [375, { "mul": ["$s3", 0.5] }] }, "y": { "add": [{ "sub": ["$h", 90] }, { "sub": [36, { "mul": [44, "$cut"] }] }, 8] }, "width": 5, "height": { "mul": [44, "$cut"] } }
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
{ "id": "credits", "type": "text", "content": { "if": "credits", "then": "{credits}", "else": "Design — {name}\nSet in Inter Tight" }, "font": "Inter Tight", "weight": 500, "size": 6.5, "lineHeight": 1.3, "letterSpacing": 0, "x": 16, "y": { "sub": ["$h", 27] }, "maxWidth": 180, "maxLines": 2, "color": "{ink}", "opacity": 0.72 },
|
|
100
|
+
{ "id": "edition", "type": "text", "content": "{edition}", "when": "edition", "font": "Inter Tight", "weight": 500, "size": 6.5, "letterSpacing": 0, "x": 384, "y": { "sub": ["$h", 18.5] }, "align": "right", "maxWidth": 180, "maxLines": 1, "color": "{ink}", "opacity": 0.72 }
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
{ "id": "print", "type": "grain", "amount": 0.035, "size": 1.5 }
|
|
104
|
+
]
|
|
105
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../schema/recipe.schema.json",
|
|
3
|
+
"name": "series-card",
|
|
4
|
+
"description": "Numbered series card, for a run of posts: one flat soft colour, a two-line uppercase title top-left, a large number bottom-left (\"01\"), and the mark large in the space left, solid or as contour lines (its outline and three to five more drawn round it, gap apart, merging where its parts meet). Set number and ground per post and keep the rest, and ten of them read as one series across a palette. An optional label top-right. Drawn on a 400-wide grid as tall as the canvas, so it sets at 1:1, 4:5, 9:16 and A-series portrait alike.",
|
|
5
|
+
"params": {
|
|
6
|
+
"title": ["Everything", "is connected"],
|
|
7
|
+
"number": "01",
|
|
8
|
+
"label": "",
|
|
9
|
+
"style": "contour",
|
|
10
|
+
"lines": 4,
|
|
11
|
+
"gap": 0.055,
|
|
12
|
+
"ground": "#f3c9b8",
|
|
13
|
+
"ink": "#1c1b19"
|
|
14
|
+
},
|
|
15
|
+
"vars": {
|
|
16
|
+
"h": { "mul": [400, { "div": ["@height", "@width"] }] }
|
|
17
|
+
},
|
|
18
|
+
"layers": [
|
|
19
|
+
{ "id": "ground", "type": "solid", "color": "{ground}" },
|
|
20
|
+
{
|
|
21
|
+
"id": "card",
|
|
22
|
+
"type": "group",
|
|
23
|
+
"viewBox": [0, 0, 400, "$h"],
|
|
24
|
+
"fit": "contain",
|
|
25
|
+
"layers": [
|
|
26
|
+
{
|
|
27
|
+
"id": "mark",
|
|
28
|
+
"type": "outline",
|
|
29
|
+
"when": "mark",
|
|
30
|
+
"markup": "{mark}",
|
|
31
|
+
"lines": { "if": { "style": "solid" }, "then": 0, "else": "{lines}" },
|
|
32
|
+
"gap": "{gap}",
|
|
33
|
+
"stroke": 1.15,
|
|
34
|
+
"x": 124,
|
|
35
|
+
"y": 84,
|
|
36
|
+
"width": 260,
|
|
37
|
+
"height": { "sub": ["$h", 100] },
|
|
38
|
+
"color": "{ink}"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": "title",
|
|
42
|
+
"type": "text",
|
|
43
|
+
"content": "{title}",
|
|
44
|
+
"when": "title",
|
|
45
|
+
"transform": "uppercase",
|
|
46
|
+
"font": "Inter Tight",
|
|
47
|
+
"weight": 700,
|
|
48
|
+
"size": 21,
|
|
49
|
+
"lineHeight": 0.95,
|
|
50
|
+
"letterSpacing": -0.025,
|
|
51
|
+
"fit": "shrink",
|
|
52
|
+
"maxWidth": 250,
|
|
53
|
+
"maxLines": 2,
|
|
54
|
+
"anchor": "top-left",
|
|
55
|
+
"margin": 0,
|
|
56
|
+
"offset": { "x": 18, "y": 20 },
|
|
57
|
+
"color": "{ink}"
|
|
58
|
+
},
|
|
59
|
+
{ "id": "label", "type": "text", "content": "{label}", "when": "label", "font": "Inter Tight", "weight": 500, "size": 7, "letterSpacing": 0, "x": 382, "y": 27, "align": "right", "maxWidth": 110, "maxLines": 2, "color": "{ink}" },
|
|
60
|
+
{
|
|
61
|
+
"id": "number",
|
|
62
|
+
"type": "text",
|
|
63
|
+
"content": "{number}",
|
|
64
|
+
"when": "number",
|
|
65
|
+
"font": "Inter Tight",
|
|
66
|
+
"weight": 600,
|
|
67
|
+
"size": 92,
|
|
68
|
+
"lineHeight": 0.8,
|
|
69
|
+
"letterSpacing": -0.06,
|
|
70
|
+
"fit": "shrink",
|
|
71
|
+
"maxWidth": 104,
|
|
72
|
+
"maxLines": 1,
|
|
73
|
+
"anchor": "bottom-left",
|
|
74
|
+
"margin": 0,
|
|
75
|
+
"offset": { "x": 14, "y": -16 },
|
|
76
|
+
"color": "{ink}"
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
}
|