stand-variety: every pedestal is its own drawing
commit fd556e017253d30d61df7bbe7278a19c521c8aad · parent 6b3477bda1
· browse this tree
Ximianth, 2026-10-30 14:53:07 UTC
Each entrance stand's pedestal is generated fresh, seeded by its repo name: same silhouette, same family, a different hand's wobble -- a sketchbook, not a rubber stamp. Drawn inline with currentColor strokes, so one drawing follows the ink through both color schemes (the per-scheme asset pair that CSS backgrounds force is not needed here), and the index needs no extra fetches. The name now sits on the cap (the tune-name-on-cap item): baseline on the cap's top edge, descenders kissing the stroke. On its own branch for separate judgment: if nine different wobbles read as noise rather than a hand, this dies here.
diff --git a/chrome.go b/chrome.go index 6c97770..586ed8b 100644 --- a/chrome.go +++ b/chrome.go @@ -242,15 +242,14 @@ article ul.entrance { gap: 2.8rem 1.5rem; } .stand { text-align: center; min-width: 0; } -.stand .name { font-size: 1.35rem; margin: 0; } +/* The name sits on the cap (negative margin; the svg below is its seat). */ +.stand .name { font-size: 1.35rem; margin: 0 0 -7px; position: relative; } .stand .name a { text-decoration: none; } .stand .name a:hover { text-decoration: underline; } -.stand .pedestal { - height: 84px; - background-position: top center; - background-size: 140px 84px; - background-repeat: no-repeat; -} +/* Each stand's pedestal is its own inline drawing (seeded by the repo name; + see standSVG): currentColor strokes follow the ink through both schemes. */ +.stand .pedestal { height: 84px; color: var(--ink); } +.stand .pedestal svg { display: block; margin: 0 auto; } .stand .placard { font-size: .8rem; letter-spacing: .12em; @@ -494,7 +493,7 @@ func sketchCSS(scheme string) string { return fmt.Sprintf(` .flank { background-image: %s; } footer.ground .floor { background-image: %s; } -.stand .pedestal, .emptyroom .pedestal { background-image: %s; } +.emptyroom .pedestal { background-image: %s; } .marquee .pedestal { background-image: %s; } /* Hand-ruled lines replace solid borders on the nav and headings. */ nav.crumbs, article h1, article h2 { diff --git a/pages.go b/pages.go index edf48c0..2179ccd 100644 --- a/pages.go +++ b/pages.go @@ -100,7 +100,7 @@ var indexTmpl = template.Must(template.New("index").Parse(`<header class="marque <ul class="entrance"> {{range .Rows}}<li class="stand"> <p class="name"><a href="/{{.Name}}/">{{.Name}}</a></p> -<div class="pedestal"></div> +<div class="pedestal">{{.Pedestal}}</div> {{if or .Description .LangColor}}<p class="placard">{{if .LangColor}}<span class="swatch" style="background:{{.LangColor}}" title="{{.Lang}}"></span>{{end}}{{.Description}}</p> {{end}}{{if .Head}}<p class="showing" title="latest commit on {{.Branch}}">{{.Head}}</p> {{end}}</li> @@ -109,6 +109,7 @@ var indexTmpl = template.Must(template.New("index").Parse(`<header class="marque type indexRow struct { Name string + Pedestal template.HTML // this repo's own pedestal drawing; see standSVG Description string Branch string // the default branch the caption was read from Head string // subject of the newest commit on the default branch; empty if none @@ -120,7 +121,7 @@ func (s *server) serveIndex(w http.ResponseWriter, r *http.Request, snap *snapsh var rows []indexRow for _, name := range sortedNames(snap.repos) { rp := snap.repos[name] - row := indexRow{Name: name, Description: rp.description, Branch: rp.defaultBranch()} + row := indexRow{Name: name, Pedestal: template.HTML(standSVG(name)), Description: rp.description, Branch: rp.defaultBranch()} // Enrichment is best-effort, matching the caption's existing stance: // the entrance still stands when one repo cannot answer. if cs, err := rp.commits(row.Branch, 1); err == nil && len(cs) > 0 { diff --git a/sketch.go b/sketch.go index 7d1582a..0c422b1 100644 --- a/sketch.go +++ b/sketch.go @@ -373,6 +373,29 @@ func faviconSVG(seed string) []byte { return []byte(sb.String()) } +// standSVG is one entrance pedestal, drawn fresh for one repo: the plinth family's +// geometry, seeded by the repo's name, so no two stands in the gallery are the same +// drawing. Emitted inline in the page (not served as an asset) with currentColor +// strokes, so one drawing follows the page's ink through both color schemes -- +// which is also why this one, unlike its asset siblings, needs no per-scheme pair. +func standSVG(name string) []byte { + rng := newSketchRand("stand/" + name) + var sb strings.Builder + svgOpen(&sb, 140, 84) + boxes := func(d *strings.Builder, amp, over float64) { + roughBox(d, rng, 20, 10, 100, 14, amp, over) + roughBox(d, rng, 34, 24, 72, 40, amp, over) + roughBox(d, rng, 10, 64, 120, 16, amp, over) + } + var d1, d2 strings.Builder + boxes(&d1, 1.0, 2.5) + boxes(&d2, 1.5, 3.0) + svgPath(&sb, d1.String(), "currentColor", 1.6, 0.75) + svgPath(&sb, d2.String(), "currentColor", 1.2, 0.28) + sb.WriteString("</svg>\n") + return []byte(sb.String()) +} + // plinthGrandSVG is the marquee's pedestal: the same cap/die/plinth family at the // entrance-masthead size, drawn natively rather than scaled so the stroke weight // stays in step with its siblings. The site's own name stands on this one. diff --git a/testdata/pages.md b/testdata/pages.md index c523dc4..b0f2f97 100644 --- a/testdata/pages.md +++ b/testdata/pages.md @@ -51,7 +51,11 @@ test <ul class="entrance"> <li class="stand"> <p class="name"><a href="/fixturama/">fixturama</a></p> -<div class="pedestal"></div> +<div class="pedestal"><svg xmlns="http://www.w3.org/2000/svg" width="140" height="84" viewBox="0 0 140 84"> +<path d="M19.1 10.1C53.2 10.5 87.3 10.1 121.4 10.1M119.8 8.9C120.6 14.3 119.4 19.7 119.6 25.2M120.2 23.6C86.3 23.6 52.4 23.9 18.4 23.8M19.7 24.7C20.1 19.1 20.0 13.5 19.8 8.0M32.8 24.5C57.5 23.9 82.3 23.8 107.0 24.4M106.1 23.3C106.9 37.6 106.6 51.8 106.1 66.1M106.1 64.4C81.5 64.5 57.0 64.2 32.4 64.4M34.2 64.6C35.1 50.6 33.6 36.6 34.1 22.6M9.6 64.4C50.4 64.5 91.2 63.4 132.0 63.7M130.3 63.9C129.7 69.7 130.8 75.5 130.2 81.3M130.8 79.6C90.3 79.6 49.8 79.9 9.3 79.5M9.6 80.0C9.1 74.3 10.7 68.7 10.2 62.9" fill="none" stroke="currentColor" stroke-width="1.6" stroke-opacity="0.75" stroke-linecap="round"/> +<path d="M17.8 10.5C52.4 9.7 87.0 9.0 121.6 10.3M120.5 9.4C119.6 15.0 121.6 20.6 120.2 26.2M121.4 23.8C86.8 24.4 52.1 22.7 17.5 23.7M20.0 24.9C20.1 19.2 19.2 13.5 20.3 7.9M31.3 23.4C56.9 22.4 82.4 23.1 108.0 24.3M105.9 22.0C106.3 36.0 106.1 50.1 105.8 64.1M108.2 63.9C82.7 63.3 57.2 64.7 31.7 64.6M34.5 64.7C35.2 50.6 33.7 36.5 34.6 22.3M9.0 64.1C50.2 63.6 91.4 64.8 132.6 63.9M130.1 61.9C129.7 68.9 128.7 76.0 130.0 83.0M129.9 80.6C89.2 80.6 48.5 81.2 7.8 79.4M10.6 80.9C10.0 74.4 9.1 67.8 9.5 61.2" fill="none" stroke="currentColor" stroke-width="1.2" stroke-opacity="0.28" stroke-linecap="round"/> +</svg> +</div> <p class="placard"><span class="swatch" style="background:#00ADD8" title="Go"></span>the fixture</p> <p class="showing" title="latest commit on main">add docs and src</p> </li>