Brand mark: scallop ribbon shape, app icon in light / dark / tinted (#11)
CI / build-and-deploy (push) Successful in 18s

This commit was merged in pull request #11.
This commit is contained in:
2026-08-03 17:00:52 +00:00
parent b3d8719874
commit c932814166
10 changed files with 1073 additions and 0 deletions
+72
View File
@@ -0,0 +1,72 @@
<!doctype html>
<!--
App icon artwork for Marks. Rendered to PNG by generate.sh — do not edit the
PNGs in AppIcon.appiconset directly, they are build output.
The path below is the same geometry as ScallopMark in
Marks/Views/Library/MarksMark.swift, in the same canonical 88 x 98 box. If you
change one, change the other; there is no shared source between Swift and SVG.
Three variants, per Apple's iOS 18+ app icon model:
light — full-bleed artwork on the paper ground, flattened (icons may not
carry an alpha channel).
dark — artwork only, on transparency. The system supplies the dark
background, so the bands are the palette's dark counterparts,
which are lifted rather than dimmed.
tinted — greyscale on transparency. The system maps luminance to the user's
chosen tint, so the three bands are carried as three greys whose
relative luminance matches the colour version. Flattening them to
one grey would throw away the band reading in exactly the mode
that has nothing else left.
-->
<html lang="en">
<head>
<meta charset="utf-8">
<title>Marks app icon</title>
<style>
html,body{margin:0;padding:0;background:transparent}
#tile{width:1024px;height:1024px;display:flex;align-items:center;justify-content:center}
svg{display:block}
</style>
</head>
<body>
<div id="tile"></div>
<script>
// 88 x 98 canonical box. 4 tails => 3 steps of 88/3.
const W = 88, H = 98, R = 10, DEPTH = 16, TAILS = 4
const step = W / (TAILS - 1)
let d = `M${R} 0 H${W - R} A${R} ${R} 0 0 1 ${W} ${R} V${H}`
for (let i = 1; i < TAILS; i++) {
d += ` L${(W - step * (i - 0.5)).toFixed(3)} ${H - DEPTH}`
d += ` L${(W - step * i).toFixed(3)} ${H}`
}
d += ` V${R} A${R} ${R} 0 0 1 ${R} 0 Z`
const VARIANTS = {
// navy, vermilion, yellow on the paper sheet
light: {ground: '#F8F5EF', bands: ['#001A55', '#ED663F', '#FECD00']},
// the palette's dark counterparts, lifted so they carry on a dark ground
dark: {ground: null, bands: ['#5B8FD0', '#E07A5C', '#D8AD10']},
// greys ordered by the colour version's relative luminance
tinted: {ground: null, bands: ['#737373', '#B8B8B8', '#F2F2F2']},
}
const v = VARIANTS[new URLSearchParams(location.search).get('v') || 'light']
// Mark occupies 62% of the tile's height, which lands it inside Apple's grid
// with the margin the squircle mask wants.
const markH = 1024 * 0.62
const svg = [`<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024">`]
if (v.ground) svg.push(`<rect width="1024" height="1024" fill="${v.ground}"/>`)
svg.push(`<defs><clipPath id="mark"><path d="${d}"/></clipPath></defs>`)
svg.push(`<g transform="translate(${512 - markH * W / H / 2} ${512 - markH / 2}) scale(${markH / H})">`)
svg.push(`<g clip-path="url(#mark)">`)
v.bands.forEach((color, i) => {
svg.push(`<rect x="${(W / 3 * i).toFixed(3)}" y="0" width="${(W / 3).toFixed(3)}" height="${H}" fill="${color}"/>`)
})
svg.push(`</g></g></svg>`)
document.getElementById('tile').innerHTML = svg.join('')
</script>
</body>
</html>