Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions 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}