@jtakeit/astro 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +59 -0
- package/bin/jtk.mjs +41 -0
- package/docs/booking.md +164 -0
- package/docs/catalogue.md +459 -0
- package/docs/collections.md +249 -0
- package/docs/css.md +86 -0
- package/docs/gallery.md +127 -0
- package/docs/hero-motion.md +189 -0
- package/docs/kit.md +454 -0
- package/docs/languages.md +182 -0
- package/docs/lead-form.md +109 -0
- package/docs/pages.md +193 -0
- package/docs/photos.md +314 -0
- package/docs/scaffold.md +75 -0
- package/docs/shapes.md +140 -0
- package/docs/surface.md +187 -0
- package/lib/catalogue.mjs +1678 -0
- package/lib/codes.mjs +171 -0
- package/lib/create.mjs +282 -0
- package/package.json +16 -0
- package/template/astro.config.mjs +84 -0
- package/template/figures.mjs +122 -0
- package/template/gitignore +16 -0
- package/template/jtakeit-meta.mjs +112 -0
- package/template/jtk/content/index.json +38 -0
- package/template/jtk/design.json +24 -0
- package/template/markdown.mjs +36 -0
- package/template/package-lock.json +5320 -0
- package/template/package.json +26 -0
- package/template/specimens.mjs +46 -0
- package/template/src/components/Blocks.astro +151 -0
- package/template/src/components/BookingForm.astro +506 -0
- package/template/src/components/Clip.astro +155 -0
- package/template/src/components/Hero.astro +66 -0
- package/template/src/components/LeadForm.astro +347 -0
- package/template/src/components/OpeningHours.astro +69 -0
- package/template/src/components/Pile.astro +185 -0
- package/template/src/components/Shot.astro +472 -0
- package/template/src/components/gallery/Gallery.astro +381 -0
- package/template/src/components/gallery/galleries.ts +139 -0
- package/template/src/components/motion/HeroField.astro +520 -0
- package/template/src/components/motion/fields.ts +430 -0
- package/template/src/components/surface/Pattern.astro +278 -0
- package/template/src/components/surface/patterns.ts +187 -0
- package/template/src/content/blocks.ts +758 -0
- package/template/src/content.config.ts +19 -0
- package/template/src/copy/LOCALE.ts +324 -0
- package/template/src/data/site.ts +137 -0
- package/template/src/layouts/Layout.astro +282 -0
- package/template/src/lib/alive.ts +49 -0
- package/template/src/lib/entries.ts +106 -0
- package/template/src/lib/entryLoader.ts +315 -0
- package/template/src/lib/noise.ts +26 -0
- package/template/src/lib/page.ts +287 -0
- package/template/src/lib/photos.ts +168 -0
- package/template/src/lib/under.ts +32 -0
- package/template/src/lib/uploads.ts +85 -0
- package/template/src/pages/[...entry].astro +207 -0
- package/template/src/pages/[...feed].xml.ts +64 -0
- package/template/src/pages/index.astro +90 -0
- package/template/src/pages/llms.txt.ts +50 -0
- package/template/src/pages/privacy.astro +59 -0
- package/template/src/pages/robots.txt.ts +21 -0
- package/template/src/pages/sitemap.xml.ts +50 -0
- package/template/src/styles/global.css +411 -0
- package/template/src/styles/surface.css +375 -0
- package/template/tsconfig.json +5 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The grounds a page can be printed on.
|
|
3
|
+
*
|
|
4
|
+
* Data only — no DOM, no colour. `Pattern.astro` owns the layer, the ink and
|
|
5
|
+
* every way it is allowed to fail; this file is what each ground actually looks
|
|
6
|
+
* like, which is the part worth reading on its own.
|
|
7
|
+
*
|
|
8
|
+
* ── one idea holds the whole catalogue together ─────────────────────────────
|
|
9
|
+
*
|
|
10
|
+
* **A ground is a stencil, and the ink is a token.** Nothing here names a
|
|
11
|
+
* colour. A stencil ground is an alpha mask over a layer painted in
|
|
12
|
+
* `--pattern-ink`; a drawn ground is line art stroked in `currentColor`, which
|
|
13
|
+
* is the same token. So a variant that changes its palette — or the studio
|
|
14
|
+
* bar's live accent picker — repaints the ground with it, and a ground can
|
|
15
|
+
* never arrive in somebody else's colour the way a shipped background image
|
|
16
|
+
* would.
|
|
17
|
+
*
|
|
18
|
+
* The two mechanisms exist because they do different work:
|
|
19
|
+
*
|
|
20
|
+
* STENCILS a repeating figure with no beginning and no end. CSS only:
|
|
21
|
+
* a mask image, no markup, no bytes past this file.
|
|
22
|
+
* DRAWINGS one composition that bleeds off its box. SVG, because a figure
|
|
23
|
+
* has a size and a place, and because strokes can draw themselves.
|
|
24
|
+
*
|
|
25
|
+
* Adding one is a row in either record. What it has to earn is a *different
|
|
26
|
+
* job*: another spacing of parallel lines is `rules` with different constants,
|
|
27
|
+
* not a seventh ground. Ask what a design could do with it that it could not do
|
|
28
|
+
* with the six.
|
|
29
|
+
*
|
|
30
|
+
* ── what the geometry is measured in ────────────────────────────────────────
|
|
31
|
+
*
|
|
32
|
+
* --pattern-size the figure's pitch: line spacing, tile, wavelength.
|
|
33
|
+
* --pattern-weight stroke weight.
|
|
34
|
+
*
|
|
35
|
+
* Both are read straight out of CSS rather than passed through here, so a
|
|
36
|
+
* variant can retune a ground per breakpoint — a 22px rule pitch that reads on
|
|
37
|
+
* a laptop is a grey wash on a phone — without touching this file.
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
import { GRAIN_TILE, GRAIN_SIZE } from '../../lib/noise';
|
|
41
|
+
|
|
42
|
+
export type Pattern = 'grain' | 'rules' | 'hatch' | 'contour' | 'construction' | 'motif';
|
|
43
|
+
|
|
44
|
+
/** Grounds drawn as a CSS mask: a repeating figure, no markup. */
|
|
45
|
+
export type Stencil = 'grain' | 'rules' | 'hatch';
|
|
46
|
+
|
|
47
|
+
/** Grounds drawn as SVG: one composition, in a place, able to draw itself. */
|
|
48
|
+
export type Drawn = Exclude<Pattern, Stencil>;
|
|
49
|
+
|
|
50
|
+
export const STENCILS: Record<Stencil, string> = {
|
|
51
|
+
/*
|
|
52
|
+
* Film grain, paper fibre, plaster. The only ground with no figure at all —
|
|
53
|
+
* it is texture, and its whole job is that a flat token stops reading as a
|
|
54
|
+
* fill. The tile is shared with the `film` photo treatment, which is why it
|
|
55
|
+
* lives in src/lib rather than here.
|
|
56
|
+
*/
|
|
57
|
+
grain: GRAIN_TILE,
|
|
58
|
+
|
|
59
|
+
/*
|
|
60
|
+
* The ruled plane: ledger paper, a form, a chart. Horizontal only, on
|
|
61
|
+
* purpose — the square grid is the most-used background on the web and it
|
|
62
|
+
* reads as a designer's default rather than as the trade's own paper. A page
|
|
63
|
+
* that genuinely wants graph paper adds the second axis here as a second
|
|
64
|
+
* gradient, and says in a comment which trade asked for it.
|
|
65
|
+
*/
|
|
66
|
+
rules:
|
|
67
|
+
'repeating-linear-gradient(to bottom, #000 0 var(--pattern-weight), transparent var(--pattern-weight) var(--pattern-size))',
|
|
68
|
+
|
|
69
|
+
/*
|
|
70
|
+
* Engraved hatching: one direction, the way a burin goes. Crosshatch is
|
|
71
|
+
* deliberately not here — two sets at low opacity average out to a grey wash,
|
|
72
|
+
* which is a tint, not a texture.
|
|
73
|
+
*/
|
|
74
|
+
hatch:
|
|
75
|
+
'repeating-linear-gradient(48deg, #000 0 var(--pattern-weight), transparent var(--pattern-weight) var(--pattern-size))',
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Contour lines, the way a landscape is drawn.
|
|
80
|
+
*
|
|
81
|
+
* Generated rather than hand-drawn, because forty hand-drawn curves is forty
|
|
82
|
+
* chances to draw two the same. The seed is a constant and the arithmetic is
|
|
83
|
+
* integer: the same build produces the same page, or every rebuild is a diff
|
|
84
|
+
* nobody asked for.
|
|
85
|
+
*/
|
|
86
|
+
function contour(lines = 11, samples = 56, width = 1200, height = 800): string {
|
|
87
|
+
let seed = 20260825;
|
|
88
|
+
const rand = () => ((seed = (seed * 1103515245 + 12345) & 0x7fffffff) / 0x7fffffff);
|
|
89
|
+
const out: string[] = [];
|
|
90
|
+
|
|
91
|
+
for (let i = 0; i < lines; i++) {
|
|
92
|
+
const base = ((i + 0.6) / (lines + 0.2)) * height;
|
|
93
|
+
// Two waves per line, one slow and one fast, so no two lines run parallel
|
|
94
|
+
// for long — parallel is what makes generated contours look like a comb.
|
|
95
|
+
const slowAmp = 16 + rand() * 44;
|
|
96
|
+
const fastAmp = 6 + rand() * 22;
|
|
97
|
+
const slowFreq = 0.8 + rand() * 1.4;
|
|
98
|
+
const fastFreq = 2.4 + rand() * 2.6;
|
|
99
|
+
const phase = rand() * Math.PI * 2;
|
|
100
|
+
|
|
101
|
+
const points: string[] = [];
|
|
102
|
+
for (let s = 0; s <= samples; s++) {
|
|
103
|
+
const t = s / samples;
|
|
104
|
+
const y =
|
|
105
|
+
base +
|
|
106
|
+
Math.sin(t * Math.PI * slowFreq + phase) * slowAmp +
|
|
107
|
+
Math.cos(t * Math.PI * fastFreq - phase * 1.7) * fastAmp;
|
|
108
|
+
points.push(`${(t * width).toFixed(1)} ${y.toFixed(1)}`);
|
|
109
|
+
}
|
|
110
|
+
// pathLength="1" is what lets `draw` animate a stroke without anybody
|
|
111
|
+
// measuring the path by hand — see surface.md.
|
|
112
|
+
out.push(`<path pathLength="1" style="--i:${i}" d="M ${points.join(' L ')}"/>`);
|
|
113
|
+
}
|
|
114
|
+
return out.join('');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export const DRAWINGS: Record<Exclude<Drawn, 'motif'>, { viewBox: string; markup: string }> = {
|
|
118
|
+
contour: { viewBox: '0 0 1200 800', markup: contour() },
|
|
119
|
+
|
|
120
|
+
/*
|
|
121
|
+
* Setting-out: the axes, circles and dotted guides a drawing is built on
|
|
122
|
+
* before anything is drawn on it. It is the register of a studio that shows
|
|
123
|
+
* its process.
|
|
124
|
+
*
|
|
125
|
+
* **It is not anybody's signature.** The build this came from had its own
|
|
126
|
+
* construction geometry — the guides that particular tattooist leaves in red
|
|
127
|
+
* inside her own work — and that drawing is hers. This is the generic
|
|
128
|
+
* article: use it as furniture, and put the thing that could not move to
|
|
129
|
+
* another site somewhere else on the page. See surface.md, and the last
|
|
130
|
+
* section of shapes.md.
|
|
131
|
+
*/
|
|
132
|
+
construction: {
|
|
133
|
+
viewBox: '0 0 1200 800',
|
|
134
|
+
markup: [
|
|
135
|
+
// The thirds, set out first, the way a stencil is.
|
|
136
|
+
'<line pathLength="1" style="--i:0" x1="400" y1="0" x2="400" y2="800"/>',
|
|
137
|
+
'<line pathLength="1" style="--i:0" x1="800" y1="0" x2="800" y2="800"/>',
|
|
138
|
+
'<line pathLength="1" style="--i:1" x1="0" y1="267" x2="1200" y2="267"/>',
|
|
139
|
+
'<line pathLength="1" style="--i:1" x1="0" y1="533" x2="1200" y2="533"/>',
|
|
140
|
+
// The circle the composition hangs from, and its inner ring.
|
|
141
|
+
'<circle pathLength="1" style="--i:2" cx="800" cy="267" r="236"/>',
|
|
142
|
+
'<circle pathLength="1" style="--i:3" cx="800" cy="267" r="118"/>',
|
|
143
|
+
// The diagonal, and the arc that answers it.
|
|
144
|
+
'<line pathLength="1" style="--i:3" x1="120" y1="740" x2="1080" y2="120"/>',
|
|
145
|
+
'<path pathLength="1" style="--i:4" stroke-dasharray="2 8" d="M 164 533 A 400 400 0 0 0 964 533"/>',
|
|
146
|
+
// The nodes: where the guides agree.
|
|
147
|
+
'<circle pathLength="1" style="--i:5" cx="400" cy="533" r="6"/>',
|
|
148
|
+
'<circle pathLength="1" style="--i:5" cx="800" cy="267" r="6"/>',
|
|
149
|
+
'<circle pathLength="1" style="--i:5" cx="400" cy="267" r="6"/>',
|
|
150
|
+
].join(''),
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
/** In the order the reference table lists them. */
|
|
155
|
+
export const PATTERNS: Pattern[] = ['grain', 'rules', 'hatch', 'contour', 'construction', 'motif'];
|
|
156
|
+
|
|
157
|
+
export const isStencil = (pattern: Pattern): pattern is Stencil => pattern in STENCILS;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Per-ground starting values.
|
|
161
|
+
*
|
|
162
|
+
* Not a house style — a starting point that is *in range*. Grain wants a tile
|
|
163
|
+
* two hundred pixels wide and hatch wants fourteen; one shared default would
|
|
164
|
+
* put both in the wrong place, and a ground that arrives wrong is a ground
|
|
165
|
+
* somebody switches off instead of tuning. The design overrides any of them
|
|
166
|
+
* with a prop.
|
|
167
|
+
*
|
|
168
|
+
* `opacity` is the one to look at. These are quiet on purpose: a ground is read
|
|
169
|
+
* at a glance and never read *at*.
|
|
170
|
+
*/
|
|
171
|
+
export const DEFAULTS: Record<Pattern, { size: string; weight: string; opacity: number }> = {
|
|
172
|
+
grain: { size: GRAIN_SIZE, weight: '1px', opacity: 0.09 },
|
|
173
|
+
rules: { size: '26px', weight: '1px', opacity: 0.07 },
|
|
174
|
+
hatch: { size: '14px', weight: '1px', opacity: 0.06 },
|
|
175
|
+
contour: { size: '100%', weight: '1px', opacity: 0.09 },
|
|
176
|
+
construction: { size: '100%', weight: '1px', opacity: 0.08 },
|
|
177
|
+
motif: { size: '96px', weight: '1px', opacity: 0.08 },
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* A `<pattern>` needs an id, two motifs on one page need two, and a build must
|
|
182
|
+
* produce the same document twice. A module counter is all three: it lives for
|
|
183
|
+
* the build rather than for the render, so it does not reset per component and
|
|
184
|
+
* does not reach for randomness.
|
|
185
|
+
*/
|
|
186
|
+
let motifs = 0;
|
|
187
|
+
export const nextMotifId = (): string => `fl-motif-${(motifs += 1)}`;
|