Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

banner.gno

2.76 Kb · 52 lines
 1package home
 2
 3import "encoding/base64"
 4
 5// This file is shared, unchanged, by every Samouraï home realm, so the pages
 6// keep one visual identity. What differs lives in content.gno.
 7
 8// toriiMask is the Samouraï Coop mark, redrawn as vectors: a torii gate cut
 9// out of a full circle, in a 480x480 box. Everything painted through the mask
10// takes the shape of the mark.
11const toriiMask = `<mask id="torii"><circle cx="238" cy="240" r="240" fill="#fff"/><g fill="#000">` +
12	`<path d="M-10 90 Q238 164 490 90 L490 140 Q238 190 -10 140 Z"/>` +
13	`<path d="M102 140 L165 140 L162 206 L96 206 Z"/>` +
14	`<path d="M302 140 L364 140 L370 206 L304 206 Z"/>` +
15	`<rect x="-10" y="205" width="500" height="41"/>` +
16	`<path d="M89 245 L159 245 L145 490 L55 490 Z"/>` +
17	`<rect x="-10" y="274" width="100" height="32"/>` +
18	`<path d="M307 245 L377 245 L411 490 L321 490 Z"/>` +
19	`<path d="M382 296 L490 398 L490 455 L390 358 Z"/>` +
20	`</g></mask>`
21
22type heroText struct {
23	kicker   string // small red caps line above the title
24	title    string
25	subtitle string
26	tagline  string // red monospace line
27	footline string // grey monospace line
28	alt      string
29}
30
31// heroSVG draws the page banner: the mark set in a red sun on the right, the
32// text stack on the left.
33func heroSVG(h heroText) string {
34	return `<svg xmlns="http://www.w3.org/2000/svg" width="960" height="300" viewBox="0 0 960 300">` +
35		`<defs><linearGradient id="bg" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#0e0e0e"/><stop offset="1" stop-color="#2a0c10"/></linearGradient>` +
36		toriiMask + `</defs>` +
37		`<rect width="960" height="300" rx="18" fill="url(#bg)"/>` +
38		`<g stroke="#ffffff" stroke-opacity=".05"><path d="M0 60H960M0 120H960M0 180H960M0 240H960"/></g>` +
39		`<circle cx="790" cy="150" r="128" fill="#e63946"/>` +
40		`<g transform="translate(686 46) scale(.4333)"><rect width="480" height="480" fill="#f4efe6" mask="url(#torii)"/></g>` +
41		`<text x="56" y="78" font-family="ui-monospace,Menlo,monospace" font-size="13" letter-spacing="3" fill="#e63946">` + xmlText(h.kicker) + `</text>` +
42		`<text x="52" y="160" font-family="system-ui,-apple-system,Segoe UI,sans-serif" font-weight="800" font-size="76" fill="#ffffff">` + xmlText(h.title) + `</text>` +
43		`<text x="56" y="200" font-family="system-ui,-apple-system,Segoe UI,sans-serif" font-size="22" fill="#e8e2d8">` + xmlText(h.subtitle) + `</text>` +
44		`<text x="56" y="236" font-family="ui-monospace,Menlo,monospace" font-size="16" fill="#e63946">` + xmlText(h.tagline) + `</text>` +
45		`<text x="56" y="266" font-family="ui-monospace,Menlo,monospace" font-size="12" fill="#8a8a8a">` + xmlText(h.footline) + `</text>` +
46		`</svg>`
47}
48
49func heroImage() string {
50	return "![" + mdText(hero.alt) + "](data:image/svg+xml;base64," +
51		base64.StdEncoding.EncodeToString([]byte(heroSVG(hero))) + ")"
52}