@popcraft/kit 0.30.0 → 0.32.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/dist/chunks/{agent-CGSIEC2R.js → agent-LNZDZLDR.js} +1 -1
- package/dist/chunks/{build-AUXXY3JX.js → build-AKMRSWRB.js} +2 -2
- package/dist/chunks/{builtin-Q5UN4DWS.js → builtin-KY56DU2Y.js} +3 -3
- package/dist/chunks/{check-template-2EKU4JL7.js → check-template-OYCBJNDF.js} +2 -2
- package/dist/chunks/{chunk-YT6TGRM4.js → chunk-2PEG56PC.js} +40 -26
- package/dist/chunks/{chunk-KOKO3HTP.js → chunk-3NI5OGFT.js} +1 -1
- package/dist/chunks/{chunk-TQPKOPCW.js → chunk-3ZO43HDI.js} +2 -2
- package/dist/chunks/{chunk-MJ6VIF3D.js → chunk-4X5G4QPZ.js} +1 -1
- package/dist/chunks/{chunk-3MAEAHID.js → chunk-6CRT7IDI.js} +2 -2
- package/dist/chunks/chunk-6S72I27Z.js +194 -0
- package/dist/chunks/chunk-7DKGI65Y.js +305 -0
- package/dist/chunks/chunk-APBRV4W6.js +71 -0
- package/dist/chunks/{chunk-AN3H4JWT.js → chunk-APVJKUJP.js} +4 -4
- package/dist/chunks/chunk-CGNNKKW7.js +70 -0
- package/dist/chunks/{chunk-IPEOO7PN.js → chunk-CKBPEGTH.js} +2 -2
- package/dist/chunks/chunk-COJM27N2.js +73 -0
- package/dist/chunks/chunk-CVB5F7FJ.js +92 -0
- package/dist/chunks/{chunk-DVX7UAKA.js → chunk-DQ7AF2R5.js} +1 -1
- package/dist/chunks/{chunk-UHQTNURS.js → chunk-DVD56API.js} +5 -5
- package/dist/chunks/{chunk-UM6QUOOH.js → chunk-DZIPU2Q4.js} +3 -3
- package/dist/chunks/{chunk-7QYQVENQ.js → chunk-FC2FGSU2.js} +5 -5
- package/dist/chunks/{chunk-T2GF6JE3.js → chunk-GAZ57RX2.js} +1 -1
- package/dist/chunks/{chunk-R3D5OMSG.js → chunk-GF6N47NL.js} +1 -1
- package/dist/chunks/{chunk-3DNAX4HN.js → chunk-HBPURYPZ.js} +2 -2
- package/dist/chunks/{chunk-7J4MGACN.js → chunk-HN2A65AT.js} +10 -10
- package/dist/chunks/{chunk-HST5H23G.js → chunk-JRQ4ZPRK.js} +1 -1
- package/dist/chunks/chunk-LP7LPUQJ.js +81 -0
- package/dist/chunks/chunk-M2LWLS56.js +65 -0
- package/dist/chunks/{chunk-GT5X67P7.js → chunk-MFPMMKHP.js} +7 -7
- package/dist/chunks/{chunk-LE33OZ4V.js → chunk-N2RBQBUE.js} +43 -43
- package/dist/chunks/{chunk-DUYDXAR5.js → chunk-O3W7HYS7.js} +1 -1
- package/dist/chunks/chunk-OXI222BA.js +54 -0
- package/dist/chunks/chunk-P23KECK3.js +57 -0
- package/dist/chunks/{chunk-LNQN4PGS.js → chunk-P5M5QCAJ.js} +24 -24
- package/dist/chunks/{chunk-X3HT5IHG.js → chunk-POZOGQG7.js} +11 -11
- package/dist/chunks/{chunk-K7OOOI7B.js → chunk-QGE2XW66.js} +4 -4
- package/dist/chunks/{chunk-STG7FEIQ.js → chunk-S4Y3VMQH.js} +3 -3
- package/dist/chunks/chunk-UBT4DZYW.js +304 -0
- package/dist/chunks/chunk-UJTTWR5P.js +71 -0
- package/dist/chunks/{chunk-652VC4P7.js → chunk-UNAAYJKD.js} +39 -39
- package/dist/chunks/{chunk-AXKXWL35.js → chunk-WKKHCEXN.js} +5 -5
- package/dist/chunks/chunk-X22CGIKE.js +75 -0
- package/dist/chunks/chunk-X4UI5JKC.js +74 -0
- package/dist/chunks/chunk-XQJ2VVC6.js +69 -0
- package/dist/chunks/{chunk-CQ6QGYKJ.js → chunk-YI7HCLNY.js} +1 -1
- package/dist/chunks/{chunk-CVWIMZTL.js → chunk-YOYWFBRJ.js} +53 -53
- package/dist/chunks/chunk-ZBFR7DBR.js +70 -0
- package/dist/chunks/{chunk-KO24NRJ5.js → chunk-ZW7KTUDU.js} +2 -2
- package/dist/chunks/chunk-ZY3DR3P6.js +63 -0
- package/dist/chunks/chunk-ZYNF7B6N.js +70 -0
- package/dist/chunks/{client-NBSGVJPN.js → client-ORABD53R.js} +2 -2
- package/dist/chunks/{client-5YPZUV5L.js → client-YF3PYAFZ.js} +2 -2
- package/dist/chunks/{client-3FYDPRVC.js → client-YOSPARZX.js} +1 -1
- package/dist/chunks/{client-actions-J2SQWW4O.js → client-actions-LYJHQ4IE.js} +4 -4
- package/dist/chunks/{dangerous-3EDPWONV.js → dangerous-VCZB63L6.js} +3 -3
- package/dist/chunks/{editor-seams-NG3BESM6.js → editor-seams-4PF6BD4R.js} +9 -9
- package/dist/chunks/{editor-store-NDV4IXDK.js → editor-store-UAEROYSB.js} +1 -1
- package/dist/chunks/{export-watermark-SNBNUS3L.js → export-watermark-2N7ALJXN.js} +5 -5
- package/dist/chunks/{eyedropper-L5DVFZV5.js → eyedropper-3P75IZGM.js} +1 -1
- package/dist/chunks/{generate-media-ASNNFDML.js → generate-media-DYXU4BZL.js} +2 -2
- package/dist/chunks/{host-5DYGKFJ7.js → host-J4QG5WB7.js} +6 -6
- package/dist/chunks/{integrations-2BG5XVX3.js → integrations-KGJ2HE6V.js} +1 -1
- package/dist/chunks/{kit-modules-NMONCEP4.js → kit-modules-4HQU5EI2.js} +1 -1
- package/dist/chunks/{libraries-QV4QPEYK.js → libraries-NIRTR2IA.js} +5 -5
- package/dist/chunks/{live-EI26E2RB.js → live-XZKNAJ2I.js} +3 -3
- package/dist/chunks/{media-tool-OVVKBD3N.js → media-tool-YFIYMYI5.js} +1 -1
- package/dist/chunks/{new-file-DX5L4NF6.js → new-file-RNWHN4S6.js} +3 -3
- package/dist/chunks/{plugin-P6FYIVKR.js → plugin-AN5GLVH5.js} +2 -2
- package/dist/chunks/{plugin-import-V2ORN2OW.js → plugin-import-J5ZNYSIY.js} +13 -13
- package/dist/chunks/{presence-YNIJGI73.js → presence-YNSLRFAM.js} +2 -2
- package/dist/chunks/{project-UK457FEX.js → project-HSN7DOPK.js} +1 -1
- package/dist/chunks/{publish-site-E4A557HC.js → publish-site-T2C4IDD2.js} +6 -6
- package/dist/chunks/{publish-store-U5SDQCU4.js → publish-store-I2FOGDDF.js} +4 -4
- package/dist/chunks/{raster-actions-4E7H3G62.js → raster-actions-IVIGDYQU.js} +1 -1
- package/dist/chunks/{runner-DHWGPGPD.js → runner-IOXTGHBT.js} +16 -16
- package/dist/chunks/{store-CUL3XS5L.js → store-ZVOK3773.js} +5 -5
- package/dist/chunks/{sync-U23VGFOY.js → sync-XT2ZCTVE.js} +5 -5
- package/dist/chunks/{tabs-K6MESOUX.js → tabs-RIIW7KNI.js} +8 -8
- package/dist/chunks/{team-7APVVP43.js → team-KM3FZ6AU.js} +1 -1
- package/dist/chunks/{team-client-XTH5DXVW.js → team-client-2EXJKRDB.js} +1 -1
- package/dist/chunks/{tools-PE6DEYSG.js → tools-5ISIPPXP.js} +2 -2
- package/dist/chunks/{ui-commands-WQJFLB5K.js → ui-commands-GYCIF7UQ.js} +11 -11
- package/dist/chunks/{versions-Y4F3IO37.js → versions-JCQTXXUB.js} +5 -5
- package/dist/fonts/chars.txt +1 -1
- package/dist/index.js +4 -4
- package/dist/seed/files.json +1 -1
- package/dist/seed/popcraft.comic-nested.json.gz +0 -0
- package/dist/seed/popcraft.comic-pinup.json.gz +0 -0
- package/dist/templates/count.js +1 -1
- package/dist/templates/index.js +226 -210
- package/dist/templates/index.json +663 -0
- package/dist/templates/motion/landing-hero/index.js +4 -4
- package/dist/templates/motion/launch-trailer/document.js +226 -210
- package/dist/templates/motion/launch-trailer/index.js +4 -4
- package/dist/templates/motion/launch-trailer/scenes.js +3 -3
- package/dist/templates/motion/template-wall.js +2 -2
- package/dist/templates/print/comic-hero-cascade.js +100 -0
- package/dist/templates/print/comic-hero-chase.js +100 -0
- package/dist/templates/print/comic-hero-cover-modern.js +100 -0
- package/dist/templates/print/comic-hero-grid-break.js +100 -0
- package/dist/templates/print/comic-hero-interrogation.js +100 -0
- package/dist/templates/print/comic-hero-issue.js +109 -0
- package/dist/templates/print/comic-hero-manga-action.js +100 -0
- package/dist/templates/print/comic-hero-nested.js +100 -0
- package/dist/templates/print/comic-hero-overlap.js +100 -0
- package/dist/templates/print/comic-hero-parallel.js +100 -0
- package/dist/templates/print/comic-hero-pinup.js +100 -0
- package/dist/templates/print/comic-hero-widescreen.js +100 -0
- package/dist/templates/print/comic-modern-issue.js +4 -4
- package/dist/templates/saas/email-decks.js +2 -2
- package/dist/templates/saas/index.js +62 -62
- package/dist/templates/saas/launch-kit.js +5 -5
- package/dist/templates/saas/launch-video.js +2 -2
- package/dist/templates/saas/stores.js +4 -4
- package/dist/templates/slideshow/index.js +3 -3
- package/dist/templates/themes/bauhaus.js +2 -2
- package/dist/templates/themes/black-friday-coupons.js +2 -2
- package/dist/templates/themes/blueprint.js +2 -2
- package/dist/templates/themes/claymation.js +2 -2
- package/dist/templates/themes/comic-book.js +5 -5
- package/dist/{chunks/chunk-ATEECJLR.js → templates/themes/comic-hero-art.js} +11 -9
- package/dist/templates/themes/comic-hero-page.js +67 -0
- package/dist/templates/themes/comic-hero.js +97 -1
- package/dist/{chunks/chunk-ODXZPZKI.js → templates/themes/comic-indie-art.js} +7 -9
- package/dist/templates/themes/comic-indie-page.js +47 -0
- package/dist/templates/themes/comic-indie.js +85 -1
- package/dist/templates/themes/cyberpunk.js +2 -2
- package/dist/templates/themes/everyday.js +2 -2
- package/dist/templates/themes/festival-presale-family-a.js +2 -2
- package/dist/templates/themes/festival-presale-family-b.js +2 -2
- package/dist/templates/themes/holidays.js +11 -11
- package/dist/templates/themes/index.js +127 -111
- package/dist/templates/themes/lunar-new-year.js +2 -2
- package/dist/templates/themes/manuscript.js +2 -2
- package/dist/templates/themes/memories.js +5 -5
- package/dist/templates/themes/noir.js +2 -2
- package/dist/templates/themes/printshop.js +14 -14
- package/dist/templates/themes/psychedelic.js +2 -2
- package/dist/templates/themes/space-opera.js +2 -2
- package/dist/templates/themes/studio.js +2 -2
- package/dist/templates/themes/tour-tickets.js +2 -2
- package/package.json +1 -1
- package/src/templates/print/comic-hero-cascade.ts +42 -0
- package/src/templates/print/comic-hero-chase.ts +42 -0
- package/src/templates/print/comic-hero-cover-modern.ts +34 -0
- package/src/templates/print/comic-hero-grid-break.ts +39 -0
- package/src/templates/print/comic-hero-interrogation.ts +41 -0
- package/src/templates/print/comic-hero-issue.ts +44 -0
- package/src/templates/print/comic-hero-manga-action.ts +38 -0
- package/src/templates/print/comic-hero-nested.ts +39 -0
- package/src/templates/print/comic-hero-overlap.ts +40 -0
- package/src/templates/print/comic-hero-parallel.ts +40 -0
- package/src/templates/print/comic-hero-pinup.ts +29 -0
- package/src/templates/print/comic-hero-widescreen.ts +35 -0
- package/src/templates/themes/comic-hero-art.ts +66 -0
- package/src/templates/themes/comic-hero-page.ts +326 -0
- package/src/templates/themes/comic-hero.ts +15 -2
- package/src/templates/themes/comic-indie-art.ts +73 -0
- package/src/templates/themes/comic-indie-page.ts +182 -0
- package/src/templates/themes/comic-indie.ts +280 -2
- package/types/templates/src/print/comic-hero-cascade.d.ts +5 -0
- package/types/templates/src/print/comic-hero-chase.d.ts +5 -0
- package/types/templates/src/print/comic-hero-cover-modern.d.ts +5 -0
- package/types/templates/src/print/comic-hero-grid-break.d.ts +5 -0
- package/types/templates/src/print/comic-hero-interrogation.d.ts +5 -0
- package/types/templates/src/print/comic-hero-issue.d.ts +2 -0
- package/types/templates/src/print/comic-hero-manga-action.d.ts +5 -0
- package/types/templates/src/print/comic-hero-nested.d.ts +5 -0
- package/types/templates/src/print/comic-hero-overlap.d.ts +5 -0
- package/types/templates/src/print/comic-hero-parallel.d.ts +5 -0
- package/types/templates/src/print/comic-hero-pinup.d.ts +5 -0
- package/types/templates/src/print/comic-hero-widescreen.d.ts +5 -0
- package/types/templates/src/themes/comic-hero-art.d.ts +318 -0
- package/types/templates/src/themes/comic-hero-page.d.ts +177 -0
- package/types/templates/src/themes/comic-indie-art.d.ts +371 -0
- package/types/templates/src/themes/comic-indie-page.d.ts +125 -0
- package/dist/chunks/{chunk-BAZUZXS6.js → chunk-2BVGM5PJ.js} +3 -3
- package/dist/chunks/{chunk-WXY6LWRB.js → chunk-2J3PCCBE.js} +3 -3
- package/dist/chunks/{chunk-RH6WJNB4.js → chunk-2ZOSBENB.js} +3 -3
- package/dist/chunks/{chunk-FLXSWF6O.js → chunk-5GSRWIV2.js} +3 -3
- package/dist/chunks/{chunk-2WCMIJSA.js → chunk-5NGWNEKU.js} +3 -3
- package/dist/chunks/{chunk-IUK367P7.js → chunk-5PSOLUKI.js} +0 -0
- package/dist/chunks/{chunk-RUBJMQMF.js → chunk-7A3MIEOO.js} +3 -3
- package/dist/chunks/{chunk-R66IPFG4.js → chunk-7D46BJKY.js} +32 -32
- package/dist/chunks/{chunk-6H5ULKBL.js → chunk-7KFQX6N5.js} +3 -3
- package/dist/chunks/{chunk-EWGXFNXM.js → chunk-DF5IDTZB.js} +3 -3
- package/dist/chunks/{chunk-VT7UU3UP.js → chunk-ESV3AAQ4.js} +3 -3
- package/dist/chunks/{chunk-UJORPKRW.js → chunk-GN5W7TJD.js} +3 -3
- package/dist/chunks/{chunk-HQAHQJHQ.js → chunk-IPRJUV2O.js} +9 -9
- package/dist/chunks/{chunk-JVKC6UFV.js → chunk-KWXWK2LA.js} +3 -3
- package/dist/chunks/{chunk-PN6KHUSF.js → chunk-LOQNCZFE.js} +3 -3
- package/dist/chunks/{chunk-AKCMEBIQ.js → chunk-MNN76UQS.js} +12 -12
- package/dist/chunks/{chunk-ZRK4E77C.js → chunk-OGZJE5X2.js} +3 -3
- package/dist/chunks/{chunk-OTJJNSLB.js → chunk-PEDQKANG.js} +3 -3
- package/dist/chunks/{chunk-LDIYJJ24.js → chunk-PTRN7H4N.js} +11 -11
- package/dist/chunks/{chunk-J3XCBROI.js → chunk-QQMSM7EK.js} +3 -3
- package/dist/chunks/{chunk-FRFW37G6.js → chunk-TBIZI5NH.js} +3 -3
- package/dist/chunks/{chunk-BSX52WVT.js → chunk-UTFC2DI3.js} +8 -8
- package/dist/chunks/{chunk-GTR25NJ5.js → chunk-XIIFQUWN.js} +3 -3
- package/dist/chunks/{chunk-PGUAHUFE.js → chunk-XTFV46GB.js} +9 -9
- package/dist/chunks/{chunk-4ENF3NH3.js → chunk-ZLVYZPUR.js} +28 -28
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// "Nightstar: Blackout", page two: the chase. Slanted gutters keep the eye running, the way the two of them run over the roofs.
|
|
2
|
+
|
|
3
|
+
import { Kit, preset } from '../kit'
|
|
4
|
+
import { defineTemplate } from '../build'
|
|
5
|
+
import { caption, folio, FOLIO, comicMeta, comicSetup, pageGrid, panel, rows, say, sfx, slantTier, tier, tierBox } from '../themes/comic-hero-page'
|
|
6
|
+
|
|
7
|
+
export default defineTemplate({
|
|
8
|
+
id: 'comic-chase',
|
|
9
|
+
meta: comicMeta('Chase page', 'Page two of "Nightstar: Blackout": Voltrix tears open a substation, Nightstar watches from a gargoyle, and the chase runs across the rooftops on slanted gutters to a lightning bolt and an exploding water tower', ['chase', 'slanted', 'rooftops', 'sound effects']),
|
|
10
|
+
stableNumbers: true,
|
|
11
|
+
build() {
|
|
12
|
+
const k = new Kit('Chase page', preset('comic-page'))
|
|
13
|
+
comicSetup(k)
|
|
14
|
+
drawPage(k)
|
|
15
|
+
return k.finish()
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
/** This page's drawing onto the kit's last sheet: shared with the whole issue (comic-hero-issue). */
|
|
20
|
+
export function drawPage(k: Kit) {
|
|
21
|
+
const g = 12, { W, H } = pageGrid(k, k.sheet, 36, g)
|
|
22
|
+
const [h1, h2, h3] = rows(H - FOLIO, g, [30, 34, 36])
|
|
23
|
+
const t1 = tierBox(k, k.sheet, W, h1, 'Tier 1')
|
|
24
|
+
const [a] = tier(W, h1, [1], g)
|
|
25
|
+
panel(k, t1, a, 'chase-1', { ground: 'heroG1', name: 'The substation' })
|
|
26
|
+
caption(k, t1, 'Midnight. The Eastside substation.', { x: 10, y: 10, width: 200 })
|
|
27
|
+
say(k, t1, 'The whole grid. All of it. Mine.', { x: W - 180, y: 12, width: 160, to: { x: W * 0.5, y: h1 * 0.36 } })
|
|
28
|
+
const t2 = tierBox(k, k.sheet, W, h2, 'Tier 2')
|
|
29
|
+
const [b, c] = slantTier(W, h2, [2, 3], 22, g)
|
|
30
|
+
panel(k, t2, b, 'chase-2', { ground: 'heroG2', name: 'On the ledge' })
|
|
31
|
+
panel(k, t2, c, 'chase-3', { ground: 'heroG3', name: 'Through the wall' })
|
|
32
|
+
say(k, t2, 'Not tonight, Voltrix.', { x: 12, y: 12, width: 110, to: { x: b.width * 0.45, y: h2 * 0.3 }, thought: true })
|
|
33
|
+
sfx(k, t2, 'Krakk!', { x: W - 210, y: h2 - 110, w: 190, h: 96, deg: -8, seed: 4 })
|
|
34
|
+
const t3 = tierBox(k, k.sheet, W, h3, 'Tier 3')
|
|
35
|
+
const [d, e, f] = slantTier(W, h3, [3, 2, 3], -20, g)
|
|
36
|
+
panel(k, t3, d, 'chase-4', { ground: 'heroG1', name: 'The leap' })
|
|
37
|
+
panel(k, t3, e, 'chase-5', { ground: 'heroG2', name: 'Voltrix looks back' })
|
|
38
|
+
panel(k, t3, f, 'chase-6', { ground: 'heroG3', name: 'The bolt' })
|
|
39
|
+
say(k, t3, 'Keep up, hero!', { x: e.x + 4, y: 12, width: 96, to: { x: e.x + e.width * 0.5, y: h3 * 0.4 } })
|
|
40
|
+
sfx(k, t3, 'Zzrakk!', { x: f.x + 10, y: h3 - 100, w: 200, h: 90, deg: 6, fill: 'primary', seed: 11 })
|
|
41
|
+
folio(k, k.sheet, 'Nightstar: Blackout — page 2')
|
|
42
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// "Nightstar: Blackout", the front cover. One moment, full bleed, the masthead across the top.
|
|
2
|
+
|
|
3
|
+
import { Kit, preset } from '../kit'
|
|
4
|
+
import { defineTemplate } from '../build'
|
|
5
|
+
import { bleedFrame, foot, rectFrame, comicMeta, comicSetup, display, panel, say, caption, SIZE, tierBox } from '../themes/comic-hero-page'
|
|
6
|
+
|
|
7
|
+
export default defineTemplate({
|
|
8
|
+
id: 'comic-cover-modern',
|
|
9
|
+
meta: comicMeta('Comic cover (modern)', 'The front cover of "Nightstar: Blackout" no. 1: full-bleed art of Nightstar bursting up through the rain with Voltrix looming in green lightning behind him, a red masthead band with the issue box, and the cover line at the foot', ['cover', 'masthead', 'full bleed']),
|
|
10
|
+
stableNumbers: true,
|
|
11
|
+
build() {
|
|
12
|
+
const k = new Kit('Comic cover (modern)', preset('comic-cover'))
|
|
13
|
+
comicSetup(k)
|
|
14
|
+
drawPage(k)
|
|
15
|
+
return k.finish()
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
/** This page's drawing onto the kit's last sheet: shared with the whole issue (comic-hero-issue). */
|
|
20
|
+
export function drawPage(k: Kit) {
|
|
21
|
+
const { w: W, h: H } = SIZE.cover
|
|
22
|
+
k.flowSheet(k.sheet, 0, 0)
|
|
23
|
+
const t = tierBox(k, k.sheet, W, H, 'Cover')
|
|
24
|
+
const b = bleedFrame(k, W, H)
|
|
25
|
+
panel(k, t, rectFrame(b.x, b.y, b.width, H - 96 - b.y), 'cover', { ground: 'heroG1', name: 'Cover art', edge: false })
|
|
26
|
+
const band = k.stack(t, { direction: 'HORIZONTAL', align: 'CENTER', gap: 14, width: W - 64, padding: { top: 12, right: 16, bottom: 12, left: 16 }, fill: 'primary', stroke: { color: 'onPrimary', width: 3, align: 'INSIDE', join: 'MITER' }, name: 'Masthead band', absolute: { x: 32, y: 34 } })
|
|
27
|
+
const box = k.stack(band, { width: 74, align: 'CENTER', fill: 'card', padding: { top: 6, right: 6, bottom: 6, left: 6 }, stroke: { color: 'onCard', width: 2, align: 'INSIDE', join: 'MITER' }, name: 'Issue box' })
|
|
28
|
+
k.text(box, '{{brand.issue}}', { style: display(k, 'Title'), color: 'onCard', align: 'CENTER', width: 'FILL', name: 'Issue number' })
|
|
29
|
+
k.text(box, 'OCT', { style: display(k, 'Credit'), color: 'onCard', align: 'CENTER', width: 'FILL', name: 'Month' })
|
|
30
|
+
k.text(band, '{{brand.title}}', { style: display(k, 'Masthead'), color: 'onPrimary', width: 'FILL', name: 'Masthead' })
|
|
31
|
+
caption(k, t, "Harbour City's last light is a star.", { x: 20, y: Math.round(H * 0.6), width: 190, name: 'Cover line' })
|
|
32
|
+
say(k, t, 'Lights out, star boy!', { x: W - 180, y: H * 0.24, width: 128, to: { x: W * 0.62, y: H * 0.3 } })
|
|
33
|
+
foot(k, t, W, 96, 'The night the city went dark, one star stayed lit.', 'Cover line')
|
|
34
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// "Nightstar: Blackout", page four: the arrival. The hero's frame tilts out of the grid because he does.
|
|
2
|
+
|
|
3
|
+
import { Kit, preset } from '../kit'
|
|
4
|
+
import { defineTemplate } from '../build'
|
|
5
|
+
import { caption, folio, FOLIO, comicMeta, comicSetup, pageGrid, panel, rows, say, sfx, tier, tierBox, tilted } from '../themes/comic-hero-page'
|
|
6
|
+
|
|
7
|
+
export default defineTemplate({
|
|
8
|
+
id: 'comic-grid-break',
|
|
9
|
+
meta: comicMeta('Grid-break page', 'Page four of "Nightstar: Blackout": Voltrix lifts Rosa off the street, her eyes go wide, and Nightstar breaks the grid feet first on a tilted splash with "KRASH!" before the two of them lock up in the crater', ['grid break', 'splash', 'impact', 'sound effects']),
|
|
10
|
+
stableNumbers: true,
|
|
11
|
+
build() {
|
|
12
|
+
const k = new Kit('Grid-break page', preset('comic-page'))
|
|
13
|
+
comicSetup(k)
|
|
14
|
+
drawPage(k)
|
|
15
|
+
return k.finish()
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
/** This page's drawing onto the kit's last sheet: shared with the whole issue (comic-hero-issue). */
|
|
20
|
+
export function drawPage(k: Kit) {
|
|
21
|
+
const g = 12, { W, H } = pageGrid(k, k.sheet, 36, g)
|
|
22
|
+
const [h1, h2, h3] = rows(H - FOLIO, g, [28, 42, 30])
|
|
23
|
+
const t1 = tierBox(k, k.sheet, W, h1, 'Tier 1')
|
|
24
|
+
const [a, b] = tier(W, h1, [3, 2], g)
|
|
25
|
+
panel(k, t1, a, 'break-1', { ground: 'heroG1', name: 'Grabbed' })
|
|
26
|
+
panel(k, t1, b, 'break-2', { ground: 'heroG2', name: 'Her eyes' })
|
|
27
|
+
say(k, t1, 'You’re coming with me, courier.', { x: 12, y: 12, width: 128, to: { x: a.width * 0.3, y: h1 * 0.3 } })
|
|
28
|
+
const t2 = tierBox(k, k.sheet, W, h2, 'Tier 2')
|
|
29
|
+
panel(k, t2, tilted(0, 0, W, h2, 28, -28), 'break-3', { ground: 'heroG3', name: 'Feet first' })
|
|
30
|
+
sfx(k, t2, 'Krash!', { x: W - 330, y: h2 - 150, w: 300, h: 130, deg: -10, big: true, seed: 21 })
|
|
31
|
+
say(k, t2, 'Put. Her. Down.', { x: 16, y: 34, width: 96, to: { x: W * 0.32, y: h2 * 0.3 } })
|
|
32
|
+
const t3 = tierBox(k, k.sheet, W, h3, 'Tier 3')
|
|
33
|
+
const [c, d] = tier(W, h3, [2, 3], g)
|
|
34
|
+
panel(k, t3, c, 'break-4', { ground: 'heroG1', name: 'Rosa rolls clear' })
|
|
35
|
+
panel(k, t3, d, 'break-5', { ground: 'heroG2', name: 'Locked up' })
|
|
36
|
+
say(k, t3, 'Who—?', { x: 12, y: 12, width: 96, to: { x: c.width * 0.5, y: h3 * 0.4 } })
|
|
37
|
+
caption(k, t3, 'Nightstar. The one light this city has left.', { x: d.x + 10, y: h3 - 52, width: 220 })
|
|
38
|
+
folio(k, k.sheet, 'Nightstar: Blackout — page 4')
|
|
39
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// "Nightstar: Blackout", page ten: the questions. Shot, reverse shot, and a grin that says this is not over.
|
|
2
|
+
|
|
3
|
+
import { Kit, preset } from '../kit'
|
|
4
|
+
import { defineTemplate } from '../build'
|
|
5
|
+
import { caption, folio, FOLIO, comicMeta, comicSetup, pageGrid, panel, rows, say, sfx, tier, tierBox } from '../themes/comic-hero-page'
|
|
6
|
+
|
|
7
|
+
export default defineTemplate({
|
|
8
|
+
id: 'comic-interrogation',
|
|
9
|
+
meta: comicMeta('Interrogation page', 'Page ten of "Nightstar: Blackout": dawn in a warehouse, Voltrix chained to a chair under one bulb, shot and reverse shot as Nightstar asks who sold him the codes, a fist on the table, a grin, and Rosa waiting outside', ['interrogation', 'dialogue', 'shot reverse shot', 'aftermath']),
|
|
10
|
+
stableNumbers: true,
|
|
11
|
+
build() {
|
|
12
|
+
const k = new Kit('Interrogation page', preset('comic-page'))
|
|
13
|
+
comicSetup(k)
|
|
14
|
+
drawPage(k)
|
|
15
|
+
return k.finish()
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
/** This page's drawing onto the kit's last sheet: shared with the whole issue (comic-hero-issue). */
|
|
20
|
+
export function drawPage(k: Kit) {
|
|
21
|
+
const g = 12, { W, H } = pageGrid(k, k.sheet, 36, g)
|
|
22
|
+
const [h1, h2, h3] = rows(H - FOLIO, g, [32, 34, 34])
|
|
23
|
+
const t1 = tierBox(k, k.sheet, W, h1, 'Tier 1')
|
|
24
|
+
panel(k, t1, tier(W, h1, [1], g)[0], 'interro-1', { ground: 'heroG1', name: 'The warehouse' })
|
|
25
|
+
caption(k, t1, 'Dawn. Pier 9 warehouse.', { x: 10, y: 10, width: 170 })
|
|
26
|
+
const t2 = tierBox(k, k.sheet, W, h2, 'Tier 2')
|
|
27
|
+
const [a, b] = tier(W, h2, [1, 1], g)
|
|
28
|
+
panel(k, t2, a, 'interro-2', { ground: 'heroG2', name: 'Nightstar asks' })
|
|
29
|
+
panel(k, t2, b, 'interro-3', { ground: 'heroG3', name: 'Voltrix smirks' })
|
|
30
|
+
say(k, t2, 'Who sold you the substation codes?', { x: 10, y: 10, width: 160, to: { x: a.width * 0.5, y: h2 * 0.35 } })
|
|
31
|
+
say(k, t2, 'Ask nicely.', { x: W - 108, y: 10, width: 96, to: { x: b.x + b.width * 0.5, y: h2 * 0.45 } })
|
|
32
|
+
const t3 = tierBox(k, k.sheet, W, h3, 'Tier 3')
|
|
33
|
+
const [c, d, e] = tier(W, h3, [1, 1, 2], g)
|
|
34
|
+
panel(k, t3, c, 'interro-4', { ground: 'heroG1', name: 'The table' })
|
|
35
|
+
panel(k, t3, d, 'interro-5', { ground: 'heroG2', name: 'The grin' })
|
|
36
|
+
panel(k, t3, e, 'interro-6', { ground: 'heroG3', name: 'Morning' })
|
|
37
|
+
sfx(k, t3, 'Blam!', { x: 4, y: h3 - 96, w: 150, h: 84, deg: -10, seed: 19 })
|
|
38
|
+
say(k, t3, 'There’s a lot more where I came from.', { x: d.x - 20, y: 10, width: 128, to: { x: d.x + d.width * 0.5, y: h3 * 0.55 } })
|
|
39
|
+
caption(k, t3, 'To be continued.', { x: W - 150, y: h3 - 44, width: 140 })
|
|
40
|
+
folio(k, k.sheet, 'Nightstar: Blackout — page 10')
|
|
41
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// "Nightstar: Blackout", the whole issue: the cover, nine story pages in facing pages, and the pin-up as the back
|
|
2
|
+
// cover. Every page is the same drawing as its own template (each page file's `drawPage`), so the issue and the
|
|
3
|
+
// single pages never drift apart.
|
|
4
|
+
|
|
5
|
+
import { Kit, preset } from '../kit'
|
|
6
|
+
import { defineTemplate } from '../build'
|
|
7
|
+
import { comicMeta, comicSetup } from '../themes/comic-hero-page'
|
|
8
|
+
import { drawPage as cover } from './comic-hero-cover-modern'
|
|
9
|
+
import { drawPage as chase } from './comic-hero-chase'
|
|
10
|
+
import { drawPage as widescreen } from './comic-hero-widescreen'
|
|
11
|
+
import { drawPage as gridBreak } from './comic-hero-grid-break'
|
|
12
|
+
import { drawPage as cascade } from './comic-hero-cascade'
|
|
13
|
+
import { drawPage as overlap } from './comic-hero-overlap'
|
|
14
|
+
import { drawPage as nested } from './comic-hero-nested'
|
|
15
|
+
import { drawPage as parallel } from './comic-hero-parallel'
|
|
16
|
+
import { drawPage as mangaAction } from './comic-hero-manga-action'
|
|
17
|
+
import { drawPage as interrogation } from './comic-hero-interrogation'
|
|
18
|
+
import { drawPage as pinup } from './comic-hero-pinup'
|
|
19
|
+
|
|
20
|
+
const PAGES: [string, (k: Kit) => void][] = [
|
|
21
|
+
['Page 1', chase], ['Page 2', widescreen], ['Page 3', gridBreak], ['Page 4', cascade], ['Page 5', overlap],
|
|
22
|
+
['Page 6', nested], ['Page 7', parallel], ['Page 8', mangaAction], ['Page 9', interrogation], ['Back cover', pinup],
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
export default defineTemplate({
|
|
26
|
+
id: 'comic-hero-issue',
|
|
27
|
+
meta: comicMeta('Whole comic issue (Nightstar)', '"Nightstar: Blackout", the whole action issue in one file: the cover, nine story pages in facing pages and the pin-up on the back, ready to print as a booklet', ['book', 'issue', 'story', 'action']),
|
|
28
|
+
sequence: true,
|
|
29
|
+
stableNumbers: true,
|
|
30
|
+
build() {
|
|
31
|
+
const k = new Kit('Whole comic issue (Nightstar)', preset('comic-cover'))
|
|
32
|
+
comicSetup(k)
|
|
33
|
+
k.doc = { ...k.doc, settings: { ...k.doc.settings, facingPages: true } }
|
|
34
|
+
const front = k.sheet
|
|
35
|
+
k.nameSheet(front, 'Front cover')
|
|
36
|
+
cover(k)
|
|
37
|
+
k.setCover(front)
|
|
38
|
+
for (const [name, draw] of PAGES) {
|
|
39
|
+
k.addSheet(preset('comic-page'), name)
|
|
40
|
+
draw(k)
|
|
41
|
+
}
|
|
42
|
+
return k.finish()
|
|
43
|
+
},
|
|
44
|
+
})
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// "Nightstar: Blackout", page nine: the last punch. Steep diagonals and one huge frame for the hit.
|
|
2
|
+
|
|
3
|
+
import { Kit, preset } from '../kit'
|
|
4
|
+
import { defineTemplate } from '../build'
|
|
5
|
+
import { caption, folio, FOLIO, comicMeta, comicSetup, pageGrid, panel, rows, say, sfx, slantTier, tierBox, tilted } from '../themes/comic-hero-page'
|
|
6
|
+
|
|
7
|
+
export default defineTemplate({
|
|
8
|
+
id: 'comic-manga-action',
|
|
9
|
+
meta: comicMeta('Manga action page', 'Page nine of "Nightstar: Blackout": the finishing blow on steep diagonal frames, Nightstar coming straight at the reader, Voltrix out of power, the punch through his armour with "KRAKKOOM!" and him flying through a truck', ['manga', 'action', 'diagonal', 'speed', 'sound effects']),
|
|
10
|
+
stableNumbers: true,
|
|
11
|
+
build() {
|
|
12
|
+
const k = new Kit('Manga action page', preset('comic-page'))
|
|
13
|
+
comicSetup(k)
|
|
14
|
+
drawPage(k)
|
|
15
|
+
return k.finish()
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
/** This page's drawing onto the kit's last sheet: shared with the whole issue (comic-hero-issue). */
|
|
20
|
+
export function drawPage(k: Kit) {
|
|
21
|
+
const g = 12, { W, H } = pageGrid(k, k.sheet, 36, g)
|
|
22
|
+
const [h1, h2, h3] = rows(H - FOLIO, g, [38, 34, 28])
|
|
23
|
+
const t1 = tierBox(k, k.sheet, W, h1, 'Tier 1')
|
|
24
|
+
const [a, b] = slantTier(W, h1, [3, 2], 44, g)
|
|
25
|
+
panel(k, t1, a, 'manga-1', { ground: 'heroG1', name: 'Straight at him' })
|
|
26
|
+
panel(k, t1, b, 'manga-2', { ground: 'heroG2', name: 'No power left' })
|
|
27
|
+
say(k, t1, 'This one’s for the city.', { x: 10, y: 10, width: 128, to: { x: a.width * 0.4, y: h1 * 0.3 } })
|
|
28
|
+
say(k, t1, 'W-wait—', { x: W - 108, y: h1 - 80, width: 96, to: { x: b.x + b.width * 0.6, y: h1 * 0.4 } })
|
|
29
|
+
const t2 = tierBox(k, k.sheet, W, h2, 'Tier 2')
|
|
30
|
+
panel(k, t2, tilted(0, 0, W, h2, -30, 30), 'manga-3', { ground: 'heroG3', name: 'The hit' })
|
|
31
|
+
sfx(k, t2, 'Krakkoom!', { x: 20, y: h2 - 150, w: 480, h: 140, deg: -7, big: true, fill: 'primary', seed: 23 })
|
|
32
|
+
const t3 = tierBox(k, k.sheet, W, h3, 'Tier 3')
|
|
33
|
+
const [c, d] = slantTier(W, h3, [2, 3], -30, g)
|
|
34
|
+
panel(k, t3, c, 'manga-4', { ground: 'heroG1', name: 'His eyes' })
|
|
35
|
+
panel(k, t3, d, 'manga-5', { ground: 'heroG2', name: 'Through the truck' })
|
|
36
|
+
caption(k, t3, 'Lights out, Voltrix.', { x: W - 170, y: h3 - 44, width: 160 })
|
|
37
|
+
folio(k, k.sheet, 'Nightstar: Blackout — page 9')
|
|
38
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// "Nightstar: Blackout", page seven: the overload. Close-ups sit inside the big frame, the way a moment holds smaller ones.
|
|
2
|
+
|
|
3
|
+
import { Kit, preset } from '../kit'
|
|
4
|
+
import { defineTemplate } from '../build'
|
|
5
|
+
import { caption, folio, FOLIO, comicMeta, comicSetup, pageGrid, panel, rectFrame, rows, say, sfx, tier, tierBox } from '../themes/comic-hero-page'
|
|
6
|
+
|
|
7
|
+
export default defineTemplate({
|
|
8
|
+
id: 'comic-nested',
|
|
9
|
+
meta: comicMeta('Nested page', 'Page seven of "Nightstar: Blackout": Voltrix drinks the whole grid in one big frame, with two inset close-ups nested inside it, while the skyline goes dark block by block and Rosa spots the cable that feeds him', ['nested', 'inset', 'keyline', 'sound effects']),
|
|
10
|
+
stableNumbers: true,
|
|
11
|
+
build() {
|
|
12
|
+
const k = new Kit('Nested page', preset('comic-page'))
|
|
13
|
+
comicSetup(k)
|
|
14
|
+
drawPage(k)
|
|
15
|
+
return k.finish()
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
/** This page's drawing onto the kit's last sheet: shared with the whole issue (comic-hero-issue). */
|
|
20
|
+
export function drawPage(k: Kit) {
|
|
21
|
+
const g = 12, { W, H } = pageGrid(k, k.sheet, 36, g)
|
|
22
|
+
const [h1, h2] = rows(H - FOLIO, g, [54, 46])
|
|
23
|
+
const t1 = tierBox(k, k.sheet, W, h1, 'Tier 1')
|
|
24
|
+
panel(k, t1, rectFrame(0, 0, W, h1), 'nest-1', { ground: 'heroG1', name: 'The overload' })
|
|
25
|
+
const s = Math.round(W * 0.3)
|
|
26
|
+
panel(k, t1, rectFrame(16, h1 - s - 16, s, s), 'nest-2', { ground: 'heroG2', name: 'The coils', keyline: 6 })
|
|
27
|
+
panel(k, t1, rectFrame(W - s - 16, h1 - s - 16, s, s), 'nest-3', { ground: 'heroG3', name: 'The glare', keyline: 6 })
|
|
28
|
+
caption(k, t1, '11:58 p.m. He doesn’t want power. He wants all of it.', { x: 10, y: 10, width: 230 })
|
|
29
|
+
sfx(k, t1, 'Vrrmm!', { x: W - 230, y: 14, w: 200, h: 96, deg: 6, seed: 13 })
|
|
30
|
+
say(k, t1, 'More!', { x: 16 + s - 40, y: h1 - s - 70, width: 96, to: { x: 16 + s * 0.5, y: h1 - s * 0.6 } })
|
|
31
|
+
say(k, t1, 'Too bright. Can’t get close.', { x: W - s - 120, y: h1 - s - 90, width: 128, to: { x: W - s * 0.5, y: h1 - s * 0.6 }, thought: true })
|
|
32
|
+
const t2 = tierBox(k, k.sheet, W, h2, 'Tier 2')
|
|
33
|
+
const [a, b] = tier(W, h2, [3, 2], g)
|
|
34
|
+
panel(k, t2, a, 'nest-4', { ground: 'heroG2', name: 'The blackout' })
|
|
35
|
+
panel(k, t2, b, 'nest-5', { ground: 'heroG3', name: 'The cable' })
|
|
36
|
+
caption(k, t2, 'Block by block, the city goes dark.', { x: 10, y: 10, width: 200 })
|
|
37
|
+
say(k, t2, 'That cable... it feeds him.', { x: b.x + 6, y: 12, width: 128, to: { x: b.x + b.width * 0.4, y: h2 * 0.35 }, thought: true })
|
|
38
|
+
folio(k, k.sheet, 'Nightstar: Blackout — page 7')
|
|
39
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// "Nightstar: Blackout", page six: the fight. Frames laid over each other on keylines, so each blow lands on top of the last.
|
|
2
|
+
|
|
3
|
+
import { Kit, preset } from '../kit'
|
|
4
|
+
import { defineTemplate } from '../build'
|
|
5
|
+
import { caption, folio, FOLIO, comicMeta, comicSetup, pageGrid, panel, rectFrame, rows, say, sfx, tier, tierBox } from '../themes/comic-hero-page'
|
|
6
|
+
|
|
7
|
+
export default defineTemplate({
|
|
8
|
+
id: 'comic-overlap',
|
|
9
|
+
meta: comicMeta('Overlapping page', 'Page six of "Nightstar: Blackout": the fist fight, with frames laid over each other on paper keylines: the punch lands, the backhand lands harder, and Nightstar goes through a bus window before standing up again', ['overlap', 'keyline', 'fight', 'sound effects']),
|
|
10
|
+
stableNumbers: true,
|
|
11
|
+
build() {
|
|
12
|
+
const k = new Kit('Overlapping page', preset('comic-page'))
|
|
13
|
+
comicSetup(k)
|
|
14
|
+
drawPage(k)
|
|
15
|
+
return k.finish()
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
/** This page's drawing onto the kit's last sheet: shared with the whole issue (comic-hero-issue). */
|
|
20
|
+
export function drawPage(k: Kit) {
|
|
21
|
+
const g = 12, { W, H } = pageGrid(k, k.sheet, 36, g)
|
|
22
|
+
const [h1, h2, h3] = rows(H - FOLIO, g, [30, 40, 30])
|
|
23
|
+
const t1 = tierBox(k, k.sheet, W, h1, 'Tier 1')
|
|
24
|
+
const [a, b] = tier(W, h1, [3, 2], g)
|
|
25
|
+
panel(k, t1, a, 'over-1', { ground: 'heroG1', name: 'The charge' })
|
|
26
|
+
panel(k, t1, rectFrame(b.x - 40, 14, b.width + 40, h1 - 14), 'over-2', { ground: 'heroG2', name: 'The punch', keyline: 7 })
|
|
27
|
+
caption(k, t1, 'Round two.', { x: 10, y: 10, width: 110 })
|
|
28
|
+
sfx(k, t1, 'Thwakk!', { x: W - 220, y: h1 - 96, w: 200, h: 86, deg: -8, seed: 5 })
|
|
29
|
+
const t2 = tierBox(k, k.sheet, W, h2, 'Tier 2')
|
|
30
|
+
panel(k, t2, rectFrame(0, 0, W, h2), 'over-3', { ground: 'heroG3', name: 'The backhand' })
|
|
31
|
+
panel(k, t2, rectFrame(Math.round(W * 0.6), 20, Math.round(W * 0.4) - 12, h2 - 40), 'over-4', { ground: 'heroG1', name: 'Through the bus', keyline: 8 })
|
|
32
|
+
sfx(k, t2, 'Wham!', { x: 14, y: h2 - 120, w: 210, h: 100, deg: -6, fill: 'primary', seed: 8 })
|
|
33
|
+
const t3 = tierBox(k, k.sheet, W, h3, 'Tier 3')
|
|
34
|
+
const [c, d] = tier(W, h3, [3, 2], g)
|
|
35
|
+
panel(k, t3, c, 'over-5', { ground: 'heroG2', name: 'Back up' })
|
|
36
|
+
panel(k, t3, d, 'over-6', { ground: 'heroG3', name: 'The grin' })
|
|
37
|
+
say(k, t3, 'That all you’ve got?', { x: 12, y: 12, width: 128, to: { x: c.width * 0.18, y: h3 * 0.4 } })
|
|
38
|
+
say(k, t3, 'Not even close.', { x: W - 108, y: h3 - 70, width: 96, to: { x: d.x + d.width * 0.5, y: h3 * 0.45 } })
|
|
39
|
+
folio(k, k.sheet, 'Nightstar: Blackout — page 6')
|
|
40
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// "Nightstar: Blackout", page eight: the cross-cut. Him on the left, her on the right, both halves of one move.
|
|
2
|
+
|
|
3
|
+
import { Kit, preset } from '../kit'
|
|
4
|
+
import { defineTemplate } from '../build'
|
|
5
|
+
import { caption, folio, FOLIO, comicMeta, comicSetup, pageGrid, panel, rows, say, sfx, slantTier, tierBox } from '../themes/comic-hero-page'
|
|
6
|
+
|
|
7
|
+
export default defineTemplate({
|
|
8
|
+
id: 'comic-parallel',
|
|
9
|
+
meta: comicMeta('Parallel page', 'Page eight of "Nightstar: Blackout": two columns side by side, Nightstar holding off the lightning on the left while Rosa runs for the junction box on the right, until she pulls the lever and the storm dies', ['parallel', 'two columns', 'cross-cutting', 'sound effects']),
|
|
10
|
+
stableNumbers: true,
|
|
11
|
+
build() {
|
|
12
|
+
const k = new Kit('Parallel page', preset('comic-page'))
|
|
13
|
+
comicSetup(k)
|
|
14
|
+
drawPage(k)
|
|
15
|
+
return k.finish()
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
/** This page's drawing onto the kit's last sheet: shared with the whole issue (comic-hero-issue). */
|
|
20
|
+
export function drawPage(k: Kit) {
|
|
21
|
+
const g = 12, { W, H } = pageGrid(k, k.sheet, 36, g)
|
|
22
|
+
const hs = rows(H - FOLIO, g, [1, 1, 1])
|
|
23
|
+
const pairs = [['para-1', 'para-2', 'Into the glare', 'Rosa runs'], ['para-3', 'para-4', 'Holding on', 'The lever'], ['para-5', 'para-6', 'The storm dies', 'Thumbs up']] as const
|
|
24
|
+
const ts = hs.map((h, i) => {
|
|
25
|
+
const t = tierBox(k, k.sheet, W, h, `Tier ${i + 1}`)
|
|
26
|
+
const [a, b] = slantTier(W, h, [1, 1], i % 2 ? -14 : 14, g)
|
|
27
|
+
panel(k, t, a, pairs[i][0], { ground: i % 2 ? 'heroG2' : 'heroG1', name: pairs[i][2] })
|
|
28
|
+
panel(k, t, b, pairs[i][1], { ground: 'heroG3', name: pairs[i][3] })
|
|
29
|
+
return t
|
|
30
|
+
})
|
|
31
|
+
const half = W / 2
|
|
32
|
+
caption(k, ts[0], 'Him.', { x: 10, y: 10, width: 70 })
|
|
33
|
+
caption(k, ts[0], 'Her.', { x: half + 20, y: 10, width: 70 })
|
|
34
|
+
say(k, ts[1], 'Hold... on...', { x: 10, y: 10, width: 96, to: { x: half * 0.6, y: hs[1] * 0.4 } })
|
|
35
|
+
sfx(k, ts[1], 'Ka-chunk!', { x: W - 280, y: hs[1] - 100, w: 260, h: 90, deg: -8, seed: 6 })
|
|
36
|
+
say(k, ts[1], 'Lights out, big guy!', { x: half + 24, y: 10, width: 128, to: { x: half + half * 0.3, y: hs[1] * 0.35 } })
|
|
37
|
+
say(k, ts[2], 'What?! No—', { x: 10, y: 10, width: 96, to: { x: half * 0.5, y: hs[2] * 0.3 } })
|
|
38
|
+
say(k, ts[2], 'Nice work, courier.', { x: W - 140, y: 10, width: 128, to: { x: half + half * 0.4, y: hs[2] * 0.25 } })
|
|
39
|
+
folio(k, k.sheet, 'Nightstar: Blackout — page 8')
|
|
40
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// "Nightstar: Blackout", the pin-up. One figure, full bleed, the morning after.
|
|
2
|
+
|
|
3
|
+
import { Kit, preset } from '../kit'
|
|
4
|
+
import { defineTemplate } from '../build'
|
|
5
|
+
import { bleedFrame, foot, rectFrame, comicMeta, comicSetup, panel, say, caption, SIZE, tierBox } from '../themes/comic-hero-page'
|
|
6
|
+
|
|
7
|
+
export default defineTemplate({
|
|
8
|
+
id: 'comic-pinup',
|
|
9
|
+
meta: comicMeta('Pin-up page', 'The pin-up from "Nightstar: Blackout": Nightstar on the edge of a rooftop at sunrise over the city he kept alive, full bleed, with one line for the morning and the series line on a strip at the foot', ['pin-up', 'splash', 'full bleed', 'hero']),
|
|
10
|
+
stableNumbers: true,
|
|
11
|
+
build() {
|
|
12
|
+
const k = new Kit('Pin-up page', preset('comic-page'))
|
|
13
|
+
comicSetup(k)
|
|
14
|
+
drawPage(k)
|
|
15
|
+
return k.finish()
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
/** This page's drawing onto the kit's last sheet: shared with the whole issue (comic-hero-issue). */
|
|
20
|
+
export function drawPage(k: Kit) {
|
|
21
|
+
const { w: W, h: H } = SIZE.page
|
|
22
|
+
k.flowSheet(k.sheet, 0, 0)
|
|
23
|
+
const t = tierBox(k, k.sheet, W, H, 'Pin-up')
|
|
24
|
+
const b = bleedFrame(k, W, H)
|
|
25
|
+
panel(k, t, rectFrame(b.x, b.y, b.width, H - 84 - b.y), 'pinup', { ground: 'heroG1', name: 'Splash art', edge: false })
|
|
26
|
+
caption(k, t, 'The night is over. Nightstar stays.', { x: 20, y: 20, width: 190, name: 'Cover line' })
|
|
27
|
+
say(k, t, 'Morning, city.', { x: 40, y: H * 0.18, width: 96, to: { x: W * 0.5, y: H * 0.13 } })
|
|
28
|
+
foot(k, t, W, 84, 'Nightstar. Blackout, part one.', 'Pin-up line')
|
|
29
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// "Nightstar: Blackout", page three: the street. Four letterbox frames read like a film running, one beat a frame.
|
|
2
|
+
|
|
3
|
+
import { Kit, preset } from '../kit'
|
|
4
|
+
import { defineTemplate } from '../build'
|
|
5
|
+
import { caption, folio, FOLIO, comicMeta, comicSetup, pageGrid, panel, rows, say, sfx, tier, tierBox } from '../themes/comic-hero-page'
|
|
6
|
+
|
|
7
|
+
export default defineTemplate({
|
|
8
|
+
id: 'comic-widescreen',
|
|
9
|
+
meta: comicMeta('Widescreen page', 'Page three of "Nightstar: Blackout": four letterbox frames, one under the other like a film, as Rosa rides home, Voltrix lands in the avenue, her bike goes flying and he stands over her', ['widescreen', 'cinematic', 'letterbox', 'sound effects']),
|
|
10
|
+
stableNumbers: true,
|
|
11
|
+
build() {
|
|
12
|
+
const k = new Kit('Widescreen page', preset('comic-page'))
|
|
13
|
+
comicSetup(k)
|
|
14
|
+
drawPage(k)
|
|
15
|
+
return k.finish()
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
/** This page's drawing onto the kit's last sheet: shared with the whole issue (comic-hero-issue). */
|
|
20
|
+
export function drawPage(k: Kit) {
|
|
21
|
+
const g = 12, { W, H } = pageGrid(k, k.sheet, 36, g)
|
|
22
|
+
const hs = rows(H - FOLIO, g, [1, 1, 1, 1])
|
|
23
|
+
const pics = ['wide-1', 'wide-2', 'wide-3', 'wide-4'] as const
|
|
24
|
+
const names = ['Rosa rides home', 'Voltrix lands', 'Thrown', 'Cornered']
|
|
25
|
+
const tiers = hs.map((h, i) => {
|
|
26
|
+
const t = tierBox(k, k.sheet, W, h, `Tier ${i + 1}`)
|
|
27
|
+
panel(k, t, tier(W, h, [1], g)[0], pics[i], { ground: (['heroG1', 'heroG2', 'heroG3', 'heroG1'] as const)[i], name: names[i] })
|
|
28
|
+
return t
|
|
29
|
+
})
|
|
30
|
+
caption(k, tiers[0], 'Rosa Vega. Last delivery of the night.', { x: 10, y: 10, width: 220 })
|
|
31
|
+
sfx(k, tiers[1], 'Kra-thoom!', { x: W - 330, y: 8, w: 300, h: 110, deg: -6, big: false, seed: 3 })
|
|
32
|
+
say(k, tiers[2], 'No no no—', { x: W - 120, y: 12, width: 96, to: { x: W * 0.62, y: hs[2] * 0.45 } })
|
|
33
|
+
say(k, tiers[3], 'Wrong street, kid.', { x: 12, y: 12, width: 128, to: { x: W * 0.38, y: hs[3] * 0.3 } })
|
|
34
|
+
folio(k, k.sheet, 'Nightstar: Blackout — page 3')
|
|
35
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// The comic hero pack's own art (./comic-hero-*.ts): one panel each, made with an image model (FLUX.3 through the
|
|
2
|
+
// Vercel AI Gateway) from one fixed style line and one fixed sentence per character, so the series stays on model.
|
|
3
|
+
// Shipped as JPEG under the media store's content hash in public/templates/media, at most 1152 px on the long side.
|
|
4
|
+
// Made for these templates: free to use with them.
|
|
5
|
+
|
|
6
|
+
/** The style line every panel prompt starts with. */
|
|
7
|
+
export const STYLE = "Gritty energetic modern indie action comic art, rough expressive brush inks, scratchy hatching, explosive motion, raw kinetic linework."
|
|
8
|
+
/** The cast, each a fixed sentence reused word for word in every prompt they appear in. */
|
|
9
|
+
export const CAST = { nightstar: "Nightstar is an original masked hero: a lean athletic man in a sleek midnight-blue bodysuit with a large gold five-pointed star emblem on the chest, a midnight-blue cowl mask covering the upper face, gold gloves and gold boots.", voltrix: "Voltrix is an original villain: a hulking bald man in scorched charcoal-grey armour plating with crackling green electric coils on his shoulders and round glowing green goggles.", rosa: "Rosa is an original young woman bike courier with a curly black ponytail, a bright yellow rain jacket, a red messenger bag and a white cycling helmet." } as const
|
|
10
|
+
|
|
11
|
+
export const ART = {
|
|
12
|
+
'cover': { hash: '0520923bafe128b0edbdcc30fd65a023', width: 768, height: 1152, subject: "Low-angle cover shot: Nightstar bursts upward through a shattering neon-lit night sky over a rain-soaked city, fist forward, while the giant shadowy figure of Voltrix looms behind him wreathed in green lightning." },
|
|
13
|
+
'chase-1': { hash: '5ef8494cf4126515d8fca8060f411195', width: 1152, height: 651, subject: "Establishing wide shot: a city power substation at midnight in the rain, Voltrix tearing a transformer open with his bare hands, green electricity arcing everywhere." },
|
|
14
|
+
'chase-2': { hash: '1365a184ce73877fc228f8990656c17d', width: 1024, height: 1024, subject: "Medium shot: Nightstar crouched on a gargoyle ledge high above the rainy city, looking down, cape-less, alert." },
|
|
15
|
+
'chase-3': { hash: 'f1b38bcc56e2f6aa164528c7940fe9a8', width: 1152, height: 651, subject: "Action: Voltrix smashes through a brick wall onto a rooftop and runs, Nightstar sprinting after him across the rooftops, rain and debris flying." },
|
|
16
|
+
'chase-4': { hash: '40ef203c1fad0b155377653cc3ad6717', width: 1152, height: 651, subject: "Nightstar leaps across a wide gap between two skyscrapers, seen from below, the street far beneath, body stretched, explosive motion." },
|
|
17
|
+
'chase-5': { hash: '9e5b62ed93b6cf6a76edfbb87e74c09e', width: 1024, height: 1024, subject: "Close-up: Voltrix glancing back over his shoulder with a snarl, green goggles blazing, sparks in the rain." },
|
|
18
|
+
'chase-6': { hash: 'c4fe9f3ce9be13c97f930513fca1e3bc', width: 1152, height: 651, subject: "Voltrix hurls a crackling bolt of green lightning backward at Nightstar, who twists mid-air to dodge it, a water tower exploding behind them." },
|
|
19
|
+
'wide-1': { hash: '02e36cd0fde4da676db1d5cbcd97e702', width: 1152, height: 651, subject: "Wide cinematic street shot at night: Rosa riding her bicycle down a wet neon avenue, headlights and reflections, unaware of danger." },
|
|
20
|
+
'wide-2': { hash: 'd142ece06355008414409995bcc8efbe', width: 1152, height: 651, subject: "Wide shot: Voltrix crashes down from above into the middle of the avenue, the asphalt cracking in a crater, cars flipping, green lightning." },
|
|
21
|
+
'wide-3': { hash: 'b5819cb6b068143e82a0130c5acfdf96', width: 1152, height: 651, subject: "Rosa flung from her bicycle, tumbling across the wet street, her bike spinning away, shards of glass in the air." },
|
|
22
|
+
'wide-4': { hash: 'fd743798c2c8ac767c882c54aadfe879', width: 856, height: 1152, subject: "Voltrix towers over Rosa who scrambles backward on the wet street, terrified, the villain reaching for her with crackling hand." },
|
|
23
|
+
'break-1': { hash: '24864c9ff00eaad797ee689c1edceb68', width: 1024, height: 1024, subject: "Medium shot: Voltrix grabs Rosa, in her bright yellow rain jacket, by the red messenger bag strap, lifting her off the ground, green sparks crackling." },
|
|
24
|
+
'break-2': { hash: 'db24fc4cb6ad05abf82015ab3808caec', width: 1024, height: 1024, subject: "Extreme close-up of Rosa's frightened eyes reflecting green lightning, rain on her face." },
|
|
25
|
+
'break-3': { hash: '788a368f7c91115beffba384edd6a8cb', width: 1152, height: 651, subject: "Explosive splash: Nightstar crashes feet-first down onto Voltrix from above, a huge shockwave of rain and debris, the gold star blazing, raw kinetic impact." },
|
|
26
|
+
'break-4': { hash: 'a58e82a3827c6e8c1be23ad3e815955d', width: 1024, height: 1024, subject: "Rosa dropped free, landing hard on the pavement and rolling clear, debris raining around her." },
|
|
27
|
+
'break-5': { hash: '2da6d96fbb481845e780cf6240ece2d1', width: 1152, height: 651, subject: "Nightstar and Voltrix grappling in the crater, sparks and rain, faces close, straining." },
|
|
28
|
+
'cascade-1': { hash: 'ba3f66a4535367034168b1f7c257f23a', width: 1152, height: 651, subject: "Voltrix slams both fists into a street lamp, sending a surge of green electricity up into a neon billboard on a building above." },
|
|
29
|
+
'cascade-2': { hash: '9c7d695c57cca051f10c4b4d1877c911', width: 856, height: 1152, subject: "Looking up from street level: a huge burning neon billboard and steel scaffolding breaking loose and falling toward Rosa below." },
|
|
30
|
+
'cascade-3': { hash: '60514687976f160868b3e94a4a57f890', width: 1024, height: 1024, subject: "Close-up: Rosa looking up in horror, arm raised, sparks falling around her." },
|
|
31
|
+
'cascade-4': { hash: '504c48cf772656d01816a0a0e3288b87', width: 1152, height: 651, subject: "Nightstar dives in and sweeps Rosa out of the way just as the falling billboard smashes into the street behind them, explosion of sparks and glass." },
|
|
32
|
+
'cascade-5': { hash: '5e76b5ac2000cee5fe5b2c0b5affc1a9', width: 1024, height: 1024, subject: "Nightstar kneels shielding Rosa with his body as burning debris settles, both covered in dust, rain hissing on embers." },
|
|
33
|
+
'cascade-6': { hash: 'fa7831e2704e9b69b06136766d710406', width: 1152, height: 651, subject: "Wide: Voltrix standing in the flames on the street, laughing, green coils glowing brighter, the city lights flickering out behind him." },
|
|
34
|
+
'over-1': { hash: 'c92e06d52a7587127ac2396136bfa0ef', width: 1152, height: 651, subject: "Nightstar charges at Voltrix through fire and rain, fist cocked back, heavy motion streaks." },
|
|
35
|
+
'over-2': { hash: '6569e01fd26e0ec21599d18239beeecb', width: 1024, height: 1024, subject: "Close impact: Nightstar's gold-gloved fist connects with Voltrix's jaw, shockwave, teeth and sparks flying." },
|
|
36
|
+
'over-3': { hash: 'f18dc474dbb6f05a0ec0a1dd5f035373', width: 1024, height: 1024, subject: "Voltrix backhands Nightstar, sending him spinning backward through the air in a spray of rain." },
|
|
37
|
+
'over-4': { hash: 'efccaca49150c0ffc3ff4d19751acf4b', width: 1152, height: 651, subject: "Nightstar crashes through the front window of a parked city bus, glass exploding outward, dynamic angle." },
|
|
38
|
+
'over-5': { hash: '8b715da4ff00f7d65667f4723ce20ed2', width: 1152, height: 651, subject: "Nightstar rising from the wrecked bus, bruised, gold star cracked and glinting, facing Voltrix across the burning street." },
|
|
39
|
+
'over-6': { hash: '20b922922d145451550a308ef18f058e', width: 1024, height: 1024, subject: "Close-up of Voltrix's grinning face, green goggles glowing, lightning crackling across his armour." },
|
|
40
|
+
'nest-1': { hash: '49804db37766dd3fbf8815741311bcdb', width: 1152, height: 651, subject: "Wide: Voltrix grabs a high-voltage power line with both hands, absorbing the whole city's electricity, a column of green lightning shooting into the clouds." },
|
|
41
|
+
'nest-2': { hash: 'd04f29f9b8a27e12512e270abd239548', width: 1024, height: 1024, subject: "Close-up: Voltrix's armour coils overloading, glowing white-green, steam and sparks pouring off them." },
|
|
42
|
+
'nest-3': { hash: '0ae711478fafb2a9e7445ec561073121', width: 1024, height: 1024, subject: "Close-up: Nightstar shielding his masked eyes against the blinding green glare, wind whipping." },
|
|
43
|
+
'nest-4': { hash: '3c9ff7ef455e356c4b09fe598b2ca5e9', width: 1152, height: 651, subject: "Wide: the whole city skyline going dark block by block as the lights are drained, one green glow in the middle." },
|
|
44
|
+
'nest-5': { hash: 'bb84d4f02a8f45c8904d06bb164f92b5', width: 1152, height: 651, subject: "Rosa crouched alone behind a wrecked car, clutching her red messenger bag, eyes fixed on a thick black power cable snaking across the empty wet street, green glow on the horizon. No creatures, no other people." },
|
|
45
|
+
'para-1': { hash: '58b0040a4025bda6c8fc77f2cf9b7d95', width: 1024, height: 1024, subject: "Nightstar battered and staggering forward into the glare toward Voltrix, who stands in the background wreathed in green lightning, one arm up against the energy storm." },
|
|
46
|
+
'para-2': { hash: '8252a932560a2e6eb96ce5e178e39063', width: 1024, height: 1024, subject: "Rosa sprinting low along the wet street toward a junction box where the thick power cable connects, yellow jacket bright." },
|
|
47
|
+
'para-3': { hash: 'e03aca5703774849c89a6223d4bd3691', width: 1024, height: 1024, subject: "Voltrix blasts Nightstar with a beam of green lightning, Nightstar bracing behind crossed arms, being pushed back, feet dragging sparks." },
|
|
48
|
+
'para-4': { hash: '5e515e2b6f1e7715c17057f908858e09', width: 1024, height: 1024, subject: "Rosa yanking a big red emergency lever on the open junction box, sparks flying in her face, teeth gritted." },
|
|
49
|
+
'para-5': { hash: '70fdd68ee6f96ea603dede17f979cebf', width: 1024, height: 1024, subject: "Voltrix's lightning suddenly sputtering out, his coils dimming, shock on his face." },
|
|
50
|
+
'para-6': { hash: '7a7f8d301383756e74caeb6ae8c8ae1f', width: 1024, height: 1024, subject: "Nightstar glances back at Rosa by the junction box, she gives him a thumbs up, rain and smoke between them." },
|
|
51
|
+
'manga-1': { hash: '533e5dacbce7966d8b537ccb767d1460', width: 856, height: 1152, subject: "Extreme dynamic foreshortening: Nightstar launches himself straight at the viewer, fist leading, speed lines radiating, rain frozen around him." },
|
|
52
|
+
'manga-2': { hash: '89bf37366fabc1a9ce15b22e70eca072', width: 1024, height: 1024, subject: "Voltrix raising both armoured arms to block, terror in his face, coils dead." },
|
|
53
|
+
'manga-3': { hash: 'e45832e1da6f3927ab09d0fe31a3aa8b', width: 1152, height: 651, subject: "The final punch: Nightstar's fist smashes through Voltrix's guard into his chest armour, the armour shattering into pieces, enormous radiating impact burst." },
|
|
54
|
+
'manga-4': { hash: 'e781ad2b37fd73e79755868622eccd21', width: 1024, height: 1024, subject: "Close-up of Nightstar's masked eyes, intense, a trickle of blood, rain." },
|
|
55
|
+
'manga-5': { hash: 'c6a44369f7251227f7161c5de7d001a1', width: 1152, height: 651, subject: "Voltrix flying backward and crashing through a parked delivery truck, armour pieces scattering, smoke." },
|
|
56
|
+
'interro-1': { hash: '67578b7d4a3caae86cc4501a7d8f5672', width: 1152, height: 651, subject: "Wide: an abandoned warehouse at dawn lit by one hanging bulb, Voltrix in broken armour chained to a steel chair, Nightstar standing over him." },
|
|
57
|
+
'interro-2': { hash: '835dd9bf563b21c08f02439d97ab2356', width: 1024, height: 1024, subject: "Close-up: Nightstar leaning in, masked face half in shadow under the bulb, stern." },
|
|
58
|
+
'interro-3': { hash: '56a8c320e8a651b852abb492a0e35029', width: 1024, height: 1024, subject: "Close-up: Voltrix in his chair, goggles cracked, smirking, a bruise on his cheek." },
|
|
59
|
+
'interro-4': { hash: '9cf91fa3b2d4853704f7d699b60d49eb', width: 1024, height: 1024, subject: "Nightstar slamming a gold-gloved fist on a metal table, the bulb swinging, shadows lurching." },
|
|
60
|
+
'interro-5': { hash: '21dd22e30cccfb6bb82925dd46ee7b1c', width: 1024, height: 1024, subject: "Extreme close-up of Voltrix's mouth as he grins, a single green spark on a broken tooth." },
|
|
61
|
+
'interro-6': { hash: '01d85a8b550d80743fbc01002c800ced', width: 1152, height: 651, subject: "Nightstar walking out of the warehouse doorway into morning light where Rosa waits with her bicycle, backlit silhouettes." },
|
|
62
|
+
'pinup': { hash: '7f2004bc780c91f788d95e68009147b1', width: 856, height: 1152, subject: "Pin-up: Nightstar standing heroically on the edge of a skyscraper rooftop at sunrise, wind in the scene, the city below washed in orange light, gold star gleaming." },
|
|
63
|
+
} as const
|
|
64
|
+
|
|
65
|
+
export type ArtId = keyof typeof ART
|
|
66
|
+
export const art = (id: ArtId): string => `media://${ART[id].hash}`
|