import type { BookLockup, BookLockupRole, BookLockupShapePart, BookLockupTextPart, BookLockupTone, } from './book-lockups'; /** * The 24 lockups, in the units of a box 100 wide (book-lockups.ts). * * Type sizes are chosen against the share of the page a lockup takes, so the * printed sizes land where the type scale wants them on a 210 mm page: a cover * title between 70 and 180 pt, spaced capitals at 8 to 11 pt with a quarter to * half an em of tracking, a title at least three times its subtitle. Every * frame is a little taller than its line, and the parts never touch unless * they are meant to layer, so a lockup placed as it comes has no severe finding. * * The faces are the book's own (book-fonts.data.ts): condensed and heavy * poster faces for titles, Montserrat for spaced capitals, a thin serif and its * italic for quiet titles and quotes, a script for the word laid over a title, * DM Mono for coordinates. */ /** A line of spaced capitals: a date line, a kicker, a year. */ function spaced( role: BookLockupRole, y: number, size: number, tone: BookLockupTone = 'muted', more: Partial = {}, ): BookLockupTextPart { return { kind: 'text', role, x: 0, y, w: 100, h: size * 2, font: 'montserrat', size, weight: 600, tracking: 0.4, transform: 'upper', tone, ...more, }; } /** A filled bar: a rule when it is thin, a band when it is not. */ function bar(x: number, y: number, w: number, h: number, fill: BookLockupTone = 'ink'): BookLockupShapePart { return { kind: 'shape', shape: 'rect', x, y, w, h, fill }; } /** A circle drawn as a line only. */ function ring(inset: number, stroke: BookLockupTone, strokeWidth: number, size = 100): BookLockupShapePart { const side = size - inset * 2; return { kind: 'shape', shape: 'ellipse', x: inset, y: inset, w: side, h: side, fill: null, stroke, strokeWidth }; } /** A condensed poster face, Bebas unless the part says another: capitals, tight lines. */ function poster( role: BookLockupRole, y: number, size: number, more: Partial = {}, ): BookLockupTextPart { return { kind: 'text', role, x: 0, y, w: 100, h: size * 1.05, font: 'bebas', size, leading: 0.9, tracking: 0.02, transform: 'upper', tone: 'ink', ...more, }; } export const BOOK_LOCKUPS: readonly BookLockup[] = [ { id: 'poster-stack', descr: 'Heavy poster title with a hard accent shadow, a subtitle on an accent band, the year under it', height: 62, share: 0.8, parts: [ poster('title', 0, 34, { font: 'anton', shadow: { dx: 0.9, dy: 0.9, tone: 'accent' } }), poster('subtitle', 38, 7.5, { h: 11, tracking: 0.3, tone: 'paper', highlight: { tone: 'accent', padX: 2.4, padY: 0.5 }, }), spaced('year', 54, 2.4, 'ink', { h: 6 }), ], }, { id: 'spaced-date', descr: 'A spaced date line over a condensed title, a short accent rule and the place', height: 50, share: 0.75, parts: [ spaced('dates', 0, 2.4, 'muted', { h: 6 }), poster('title', 7, 30, { font: 'league', tracking: 0.04 }), bar(42, 40.5, 16, 0.5, 'accent'), spaced('place', 43.5, 2.4, 'ink', { h: 6, tracking: 0.3 }), ], }, { id: 'serif-sun', descr: 'A large thin serif title, an italic subtitle, a sun between two hairlines and the year', height: 64, share: 0.8, parts: [ { kind: 'text', role: 'title', x: 0, y: 0, w: 100, h: 28, font: 'cormorant', size: 26, weight: 300, leading: 1, tracking: -0.01, tone: 'ink', }, { kind: 'text', role: 'subtitle', x: 0, y: 29, w: 100, h: 10, font: 'cormorant', size: 7.5, italic: true, tone: 'ink', }, bar(18, 46.8, 26, 0.3), { kind: 'shape', shape: 'sun', x: 46, y: 43, w: 8, h: 8, fill: 'accent' }, bar(56, 46.8, 26, 0.3), spaced('year', 55, 2.2, 'muted', { h: 6, tracking: 0.5 }), ], }, { id: 'title-script-year', descr: 'A bold serif title, an accent script subtitle turned across its foot, the year in spaced capitals', height: 50, share: 0.75, parts: [ { kind: 'text', role: 'title', x: 0, y: 0, w: 100, h: 25, font: 'playfair', size: 22, weight: 700, leading: 0.95, tone: 'ink', }, { kind: 'text', role: 'subtitle', x: 12, y: 24, w: 76, h: 13, rotation: -4, font: 'vibes', size: 12, italic: false, tone: 'accent', }, spaced('year', 42, 2.4, 'muted', { h: 6, tracking: 0.45 }), ], }, { id: 'circle-badge', descr: 'A round accent badge: a kicker run round its rim inside a paper ring, the title and the year in the middle', height: 100, share: 0.45, parts: [ { kind: 'shape', shape: 'ellipse', x: 0, y: 0, w: 100, h: 100, fill: 'accent' }, ring(5, 'paper', 0.7), spaced('kicker', 0, 6, 'paper', { x: 7, y: 7, w: 86, h: 86, tracking: 0.25, curve: { type: 'circle', bend: 0, start: 0 }, }), poster('title', 36, 22, { x: 16, w: 68, h: 24, tone: 'paper', tracking: 0.04 }), spaced('year', 62, 4.4, 'paper', { x: 25, w: 50, h: 8, tracking: 0.3 }), ], }, { id: 'postmark', descr: 'A round postmark: the place round its rim between two rings, the date in the middle over a cancel wave', height: 100, share: 0.42, parts: [ ring(0.5, 'ink', 1), ring(14, 'ink', 0.5), poster('place', 0, 12, { x: 1, y: 1, w: 98, h: 98, tracking: 0.16, curve: { type: 'circle', bend: 0, start: 0 }, }), poster('dates', 38, 10, { x: 20, w: 60, h: 11, tracking: 0.08 }), { kind: 'shape', shape: 'wave', x: 22, y: 53, w: 56, h: 8, fill: 'ink' }, spaced('year', 63, 4.4, 'ink', { x: 25, w: 50, h: 8, tracking: 0.3 }), ], }, { id: 'script-overlay', descr: 'A spaced poster title with a large accent script word turned over it, outlined in paper', height: 58, share: 0.8, parts: [ poster('title', 22, 32, { tracking: 0.1 }), { kind: 'text', role: 'overlay', x: 8, y: 0, w: 84, h: 30, rotation: -6, font: 'yellowtail', size: 24, weight: 400, italic: false, tone: 'accent', outline: { tone: 'paper', width: 0.6 }, }, ], }, { id: 'photo-word', descr: 'A huge poster word filled with a photo, a spaced kicker over it', height: 50, share: 0.85, parts: [ spaced('kicker', 0, 2.4, 'ink', { h: 6, tracking: 0.45 }), poster('title', 7, 40, { h: 42, font: 'anton', fill: 'photo' }), ], }, { id: 'fabric-band', descr: 'A poster title in paper on a full accent band, a script subtitle under it', height: 44, share: 0.8, parts: [ bar(0, 0, 100, 26, 'accent'), poster('title', 4, 18, { h: 18, tracking: 0.14, tone: 'paper' }), { kind: 'text', role: 'subtitle', x: 0, y: 29, w: 100, h: 13, font: 'satisfy', size: 7, italic: false, tone: 'ink', }, ], }, { id: 'quote-classic', descr: 'A large accent quotation mark, the quote in a serif italic, an accent rule and the source in spaced capitals', height: 56, share: 0.6, parts: [ { kind: 'text', role: 'quote', literal: '“', x: 0, y: 0, w: 22, h: 22, font: 'playfair', size: 26, weight: 700, leading: 0.8, align: 'left', tone: 'accent', }, { kind: 'text', role: 'quote', x: 0, y: 23, w: 100, h: 24, font: 'cormorant', size: 6.5, italic: true, leading: 1.3, align: 'left', tone: 'ink', }, bar(0, 50.8, 9, 0.4, 'accent'), spaced('caption', 48, 2.8, 'muted', { x: 12, w: 88, h: 6, align: 'left', tracking: 0.3 }), ], }, { id: 'quote-band', descr: 'A quote set in paper on ink bands behind each line, the source under it', height: 42, share: 0.7, parts: [ { kind: 'text', role: 'quote', x: 0, y: 0, w: 100, h: 32, font: 'sans', size: 5, weight: 600, leading: 1.6, align: 'left', tone: 'paper', highlight: { tone: 'ink', padX: 1.4, padY: 0.4 }, }, spaced('caption', 35, 2.6, 'muted', { h: 6, align: 'left', tracking: 0.3 }), ], }, { id: 'caption-rule', descr: 'A caption in spaced capitals after a short rule', height: 8, share: 0.5, parts: [ bar(0, 3.85, 8, 0.3), spaced('caption', 0, 3.1, 'ink', { x: 11, w: 89, h: 8, align: 'left', tracking: 0.3 }), ], }, { id: 'caption-number', descr: 'An accent figure beside a caption in a serif italic', height: 16, share: 0.5, parts: [ poster('number', 0, 14, { w: 16, h: 16, align: 'left', tone: 'accent' }), { kind: 'text', role: 'caption', x: 18, y: 1, w: 82, h: 14, font: 'cormorant', size: 4.8, italic: true, leading: 1.3, align: 'left', tone: 'ink', }, ], }, { id: 'ticket', descr: 'A ticket outline holding a kicker, the place in poster capitals and the dates', height: 40, share: 0.55, parts: [ { kind: 'shape', shape: 'ticket', x: 0, y: 0, w: 100, h: 40, fill: null, stroke: 'ink', strokeWidth: 0.5 }, spaced('kicker', 7, 2.8, 'muted', { x: 12, w: 76, h: 5 }), poster('place', 12, 15, { x: 12, w: 76, h: 16, tracking: 0.08 }), spaced('dates', 28.5, 2.8, 'ink', { x: 12, w: 76, h: 5, font: 'mono', weight: 500, tracking: 0.12 }), ], }, { id: 'coords-pin', descr: 'Coordinates in spaced figures after an accent map pin', height: 10, share: 0.5, parts: [ { kind: 'shape', shape: 'pin', x: 0, y: 1, w: 6, h: 8, fill: 'accent' }, spaced('coords', 0, 3.2, 'ink', { x: 9, w: 91, h: 10, align: 'left', font: 'mono', weight: 400, tracking: 0.12, transform: 'none', }), ], }, { id: 'coords-stack', descr: 'The place in poster capitals, an accent rule and the coordinates under it', height: 30, share: 0.5, parts: [ poster('place', 0, 15, { h: 16, tracking: 0.1 }), bar(42, 17.5, 16, 0.4, 'accent'), spaced('coords', 21, 3, 'muted', { h: 7, font: 'mono', weight: 400, tracking: 0.08, transform: 'none' }), ], }, { id: 'chapter-outline', descr: 'A huge hollow outlined figure, a spaced accent label under it and the title in a serif italic', height: 62, share: 0.45, parts: [ poster('number', 0, 42, { h: 42, fill: { tone: 'ink', alpha: 0 }, outline: { tone: 'accent', width: 0.5 } }), spaced('label', 43, 3.6, 'accent', { h: 7, tracking: 0.5 }), { kind: 'text', role: 'title', x: 0, y: 51, w: 100, h: 11, font: 'cormorant', size: 8, italic: true, tone: 'ink', }, ], }, { id: 'chapter-rules', descr: 'A serif figure between two hairlines, the title in spaced capitals under it', height: 34, share: 0.5, parts: [ bar(0, 12.8, 32, 0.35), { kind: 'text', role: 'number', x: 34, y: 2, w: 32, h: 22, font: 'bodoni', size: 17, leading: 1, tone: 'ink' }, bar(68, 12.8, 32, 0.35), spaced('title', 26, 3.4, 'ink', { h: 7 }), ], }, { id: 'day-opener', descr: 'A spaced label, a huge accent serif figure and the place in poster capitals, set flush left', height: 58, share: 0.5, parts: [ spaced('label', 0, 3.4, 'muted', { h: 7, align: 'left', tracking: 0.5 }), { kind: 'text', role: 'number', x: 0, y: 7, w: 100, h: 37, font: 'fraunces', size: 40, weight: 800, leading: 0.85, align: 'left', tone: 'accent', }, poster('place', 46, 10, { h: 11, align: 'left', tracking: 0.14 }), ], }, { id: 'stamp', descr: 'A rubber stamp set at an angle: a double accent frame round the place and the dates', height: 44, share: 0.45, rotation: -7, parts: [ { kind: 'shape', shape: 'rect', x: 0, y: 0, w: 100, h: 44, fill: null, stroke: 'accent', strokeWidth: 1, radius: 2, }, { kind: 'shape', shape: 'rect', x: 3.5, y: 3.5, w: 93, h: 37, fill: null, stroke: 'accent', strokeWidth: 0.35, radius: 1, }, poster('place', 8, 17, { x: 7, w: 86, h: 18, tracking: 0.12, tone: 'accent' }), spaced('dates', 28, 3.4, 'accent', { x: 7, w: 86, h: 7, tracking: 0.35 }), ], }, { id: 'arched-title', descr: 'A poster title arched over a script subtitle, a sparkle at each side', height: 58, share: 0.75, parts: [ poster('title', 0, 20, { h: 42, tracking: 0.08, curve: { type: 'arc', bend: 42, start: 0 } }), { kind: 'shape', shape: 'sparkle', x: 6, y: 43, w: 7, h: 7, fill: 'accent' }, { kind: 'text', role: 'subtitle', x: 16, y: 41, w: 68, h: 12, font: 'dancing', size: 7, italic: false, weight: 500, tone: 'ink', }, { kind: 'shape', shape: 'sparkle', x: 87, y: 43, w: 7, h: 7, fill: 'accent' }, ], }, { id: 'retro-shadow', descr: 'A heavy retro title in the accent, outlined in ink with a hard ink shadow, a subtitle and the year', height: 48, share: 0.75, parts: [ { kind: 'text', role: 'title', x: 0, y: 0, w: 100, h: 28, font: 'shrikhand', size: 21, weight: 400, leading: 0.95, tracking: -0.01, tone: 'accent', outline: { tone: 'ink', width: 0.5 }, shadow: { dx: 1.3, dy: 1.3, tone: 'ink' }, }, spaced('subtitle', 32, 2.8, 'ink', { h: 7, tracking: 0.35 }), spaced('year', 40, 2.4, 'muted', { h: 7, tracking: 0.35 }), ], }, { id: 'outline-echo', descr: 'The title three times in poster capitals: two hollow outlines over the solid word, the year under it', height: 66, share: 0.7, parts: [ poster('title', 0, 17, { h: 18, fill: { tone: 'ink', alpha: 0 }, outline: { tone: 'ink', width: 0.3 } }), poster('title', 19, 17, { h: 18, fill: { tone: 'ink', alpha: 0 }, outline: { tone: 'ink', width: 0.3 } }), poster('title', 38, 17, { h: 18 }), spaced('year', 59, 2.6, 'muted', { h: 6, tracking: 0.45 }), ], }, { id: 'minimal-caps', descr: 'A title in widely spaced light capitals, a hairline and the year: quiet and elegant', height: 30, share: 0.7, parts: [ spaced('title', 0, 8, 'ink', { h: 13, weight: 300, tracking: 0.55 }), bar(44, 16.5, 12, 0.3), spaced('year', 21, 2.6, 'muted', { h: 7, weight: 400, tracking: 0.5 }), ], }, ];