mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-09 20:29:58 +02:00
79 lines
3.1 KiB
Typst
79 lines
3.1 KiB
Typst
// App Store screenshot composition.
|
|
// Rendered per (locale, screen) via:
|
|
// typst compile screens.typ out.png --input locale=fr --input screen=share-securely --ppi 72
|
|
// Canvas is 1284x2778pt -> at 72ppi that's exactly 1284x2778px.
|
|
|
|
#let strings = json("strings.json")
|
|
|
|
// ---- inputs (with dev-friendly defaults) --------------------------------
|
|
#let locale = sys.inputs.at("locale", default: "en")
|
|
#let screen-id = sys.inputs.at("screen", default: "share-securely")
|
|
// A pre-framed device PNG (mockup + screenshot, produced by frame.sh), or "none"
|
|
// to show the empty mockup. Screen curvature comes from the mockup mask, not Typst.
|
|
#let device-image = sys.inputs.at("device", default: "none")
|
|
|
|
#let cap = strings.locales.at(locale).at(screen-id)
|
|
|
|
// ---- canvas -------------------------------------------------------------
|
|
#let CW = 1284pt
|
|
#let CH = 2778pt
|
|
|
|
// ---- per-screen layout data --------------------------------------------
|
|
#let screens = (
|
|
"choose-receivers": (
|
|
bg: gradient.linear(angle: 160deg, rgb("#f1eafc"), rgb("#e6d8fb"), rgb("#d9c4f7")),
|
|
text: (place: "top", theme: "dark"),
|
|
device: (mockup: "straight", w: 860pt, dx: 212pt, dy: 560pt, rot: 4deg),
|
|
),
|
|
"share-securely": (
|
|
bg: gradient.linear(angle: 165deg, rgb("#efe7fb"), rgb("#e3d3f8"), rgb("#d5bff4")),
|
|
text: (place: "top", theme: "dark"),
|
|
device: (mockup: "straight", w: 820pt, dx: 232pt, dy: 470pt, rot: 0deg),
|
|
),
|
|
"send-anywhere": (
|
|
bg: gradient.linear(dir: ttb, rgb("#e9ddf9"), rgb("#ddc9f4")),
|
|
text: (place: "bottom", theme: "dark"),
|
|
globe: (w: 1180pt, dx: 52pt, dy: -160pt),
|
|
device: (mockup: "rotated", w: 900pt, dx: 90pt, dy: 980pt, rot: 0deg),
|
|
),
|
|
"stay-private": (
|
|
bg: gradient.linear(dir: ttb, rgb("#2a0f4d"), rgb("#6b3fa0"), rgb("#e9dcf8"), rgb("#ddc7f4")),
|
|
text: (place: "top", theme: "light"),
|
|
),
|
|
)
|
|
|
|
#let cfg = screens.at(screen-id)
|
|
|
|
#set page(width: CW, height: CH, margin: 0pt, fill: cfg.bg)
|
|
#set text(font: ("SF NS", "Helvetica Neue")) // "SF NS" is macOS San Francisco (= SF Pro)
|
|
|
|
// ---- compose ------------------------------------------------------------
|
|
|
|
// globe (transparent PNG)
|
|
#if "globe" in cfg [
|
|
#place(top + left, dx: cfg.globe.dx, dy: cfg.globe.dy,
|
|
image("assets/globe.png", width: cfg.globe.w))
|
|
]
|
|
|
|
// device: a pre-framed PNG (frame.sh) when available, else the empty mockup.
|
|
#if "device" in cfg [
|
|
#let d = cfg.device
|
|
#let img = if device-image != "none" { device-image } else { "assets/mockup-" + d.mockup + ".png" }
|
|
#place(top + left, dx: d.dx, dy: d.dy,
|
|
rotate(d.rot, origin: center, image(img, width: d.w)))
|
|
]
|
|
|
|
// caption
|
|
#let theme-color = if cfg.text.theme == "light" { white } else { rgb("#1b1226") }
|
|
#let sub-color = if cfg.text.theme == "light" { rgb("#f3ecfb") } else { rgb("#2c2138") }
|
|
#let caption = align(center)[
|
|
#text(size: 104pt, weight: 800, fill: theme-color)[#cap.title]
|
|
#v(10pt, weak: true)
|
|
#text(size: 60pt, weight: 600, fill: sub-color)[#cap.subtitle]
|
|
]
|
|
#if cfg.text.place == "top" [
|
|
#place(top + center, dy: 96pt, box(width: CW - 160pt, caption))
|
|
] else [
|
|
#place(bottom + center, dy: -220pt, box(width: CW - 160pt, caption))
|
|
]
|