the entrance: repos as exhibit stands on pedestals
commit dc0cfb64ecb1f5db844e01685c93c02272f572f5 · parent 307eaf9bb4
· browse this tree
Ximianth, 2026-10-26 23:16:26 UTC
Each repo at the index stands on a plinth miniature drawn by the ground glyph's generator family, with the description as a placard beneath and the newest commit subject as a one-line caption in soft ink. The stands flow in a responsive grid, so the entrance also stops crushing at phone widths. The placard carries a dominant-language dot when the language meter knows one; enrichment stays best-effort, matching the caption's existing stance. The swatch style is shared with the meter's legend rather than duplicated.
diff --git a/chrome.go b/chrome.go index 51a9152..ed8bc62 100644 --- a/chrome.go +++ b/chrome.go @@ -188,6 +188,42 @@ nav.arc.corner a { font-size: .72rem; } +/* The entrance: repos as exhibit stands, surveyed rather than parsed. + Each stand is name / pedestal / placard / one-line "now showing" caption. */ +article ul.entrance { + list-style: none; + margin: 2.5rem 0 1rem; + padding: 0; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); + gap: 2.8rem 1.5rem; +} +.stand { text-align: center; min-width: 0; } +.stand .name { font-size: 1.35rem; margin: 0; } +.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; +} +.stand .placard { + font-size: .8rem; + letter-spacing: .12em; + color: var(--ink-soft); + margin: .7rem 0 .15rem; +} +.stand .showing { + font-size: .78rem; + font-style: italic; + color: var(--ink-soft); + margin: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + /* The tagline: the repo description, read as the exhibit's subtitle. */ article .tagline { text-align: center; @@ -231,7 +267,8 @@ article .langmeter { } .langmeter .chip { white-space: nowrap; } .langmeter .chip + .chip { margin-left: .9rem; } -.langmeter .swatch { +/* The swatch is shared: the meter's legend and the entrance placards both wear it. */ +.swatch { display: inline-block; width: 10px; height: 10px; @@ -316,6 +353,7 @@ func sketchCSS(scheme string) string { return fmt.Sprintf(` .flank { background-image: %s; } footer.ground .floor { background-image: %s; } +.stand .pedestal { background-image: %s; } /* Hand-ruled lines replace solid borders on the nav and headings. */ nav.crumbs, article h1, article h2 { border-bottom: none; @@ -350,7 +388,7 @@ nav.arc a.va:active { background-image: %s; } nav.arc a.vb:active { background-image: %s; } nav.arc a.vc:active { background-image: %s; } `, - u("flank"), u("ground"), u("rule"), u("frame"), u("frame"), + u("flank"), u("ground"), u("plinth"), u("rule"), u("frame"), u("frame"), u("circle-a"), u("circle-b"), u("circle-c"), u("circle-b"), u("circle-c"), u("circle-a"), u("circle-c"), u("circle-a"), u("circle-b")) diff --git a/pages.go b/pages.go index 9fc9775..9d01fd7 100644 --- a/pages.go +++ b/pages.go @@ -87,27 +87,42 @@ func repoCrumbs(name string, more ...crumbLink) []display.Crumb { // ---- index ---- +// The entrance: every repo is an exhibit stand -- the name atop a pedestal +// (the ground glyph's family), the description as its placard, and the newest +// commit subject as a one-line "now showing" caption in soft ink. var indexTmpl = template.Must(template.New("index").Parse(`<h1>repositories</h1> -<table class="log"> -<tbody> -{{range .}}<tr><td class="name"><a href="/{{.Name}}/">{{.Name}}</a></td><td>{{.Description}}</td><td class="soft">{{.Head}}</td></tr> -{{end}}</tbody> -</table> +<ul class="entrance"> +{{range .}}<li class="stand"> +<p class="name"><a href="/{{.Name}}/">{{.Name}}</a></p> +<div class="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> +{{end}}</ul> `)) type indexRow struct { Name string 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 + Lang string // dominant language at that commit; empty if nothing classified + LangColor string // its linguist color; the placard dot only shows when one exists } func (s *server) serveIndex(w http.ResponseWriter, r *http.Request) { var rows []indexRow for _, name := range sortedNames(s.repos) { rp := s.repos[name] - row := indexRow{Name: name, Description: rp.description} - if cs, err := rp.commits(rp.defaultBranch(), 1); err == nil && len(cs) > 0 { + row := indexRow{Name: 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 { row.Head = cs[0].subject + if stats, err := s.langStats(rp, cs[0].hash); err == nil && len(stats) > 0 { + row.Lang = stats[0].name + row.LangColor = enry.GetColor(stats[0].name) + } } rows = append(rows, row) } diff --git a/sketch.go b/sketch.go index 3f1a993..16b5284 100644 --- a/sketch.go +++ b/sketch.go @@ -138,6 +138,7 @@ func sketchAssets(seed string) map[string][]byte { m["rule-"+p.scheme+".svg"] = ruleSVG(seed, p) m["flank-"+p.scheme+".svg"] = flankSVG(seed, p) m["ground-"+p.scheme+".svg"] = groundSVG(seed, p) + m["plinth-"+p.scheme+".svg"] = plinthSVG(seed, p) for _, v := range []string{"a", "b", "c"} { m["circle-"+v+"-"+p.scheme+".svg"] = circleSVG(seed+"/"+v, p) } @@ -317,3 +318,24 @@ func groundSVG(seed string, p sketchPalette) []byte { sb.WriteString("</svg>\n") return []byte(sb.String()) } + +// plinthSVG is the entrance's pedestal: the ground glyph's cap/die/plinth family, +// redrawn at exhibit-stand size, with the usual crisp and ghost passes. +// Repos stand on these at the index; the footer's empty pedestal echoes them. +func plinthSVG(seed string, p sketchPalette) []byte { + rng := newSketchRand(seed + "/plinth/" + p.scheme) + 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(), p.ink, 1.6, 0.75) + svgPath(&sb, d2.String(), p.ink, 1.2, 0.28) + sb.WriteString("</svg>\n") + return []byte(sb.String()) +} diff --git a/testdata/pages.md b/testdata/pages.md index 7356d41..f5b0546 100644 --- a/testdata/pages.md +++ b/testdata/pages.md @@ -38,11 +38,14 @@ Content-Type: text/html; charset=utf-8 socle<span class="theme">@test</span> </nav> <main><article><h1>repositories</h1> -<table class="log"> -<tbody> -<tr><td class="name"><a href="/fixturama/">fixturama</a></td><td>the fixture</td><td class="soft">add docs and src</td></tr> -</tbody> -</table> +<ul class="entrance"> +<li class="stand"> +<p class="name"><a href="/fixturama/">fixturama</a></p> +<div class="pedestal"></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> +</ul> </article></main> </div> <footer class="ground"> diff --git a/testdata/sketch.md b/testdata/sketch.md index 1cf595f..b55977c 100644 --- a/testdata/sketch.md +++ b/testdata/sketch.md @@ -46,6 +46,16 @@ Regenerate with `go test -run TestSketchSnapshots -testmark.regen` and review th </svg> ``` +### plinth-light.svg + +[testmark]:# (plinth-light.svg) +```svg +<svg xmlns="http://www.w3.org/2000/svg" width="140" height="84" viewBox="0 0 140 84"> +<path d="M17.4 9.8C52.4 10.3 87.4 9.7 122.5 9.9M119.5 10.1C120.4 15.0 120.7 19.9 120.0 24.8M121.2 24.0C87.0 23.2 52.8 23.5 18.6 24.0M20.0 25.3C19.9 19.7 19.3 14.0 19.9 8.4M32.8 23.9C57.4 24.1 82.1 24.1 106.8 24.1M105.6 21.8C105.1 35.8 106.5 49.9 106.0 63.9M106.8 64.1C82.4 63.1 57.9 63.2 33.4 64.1M33.7 66.7C33.0 51.7 34.0 36.8 34.2 21.9M8.0 64.0C49.3 63.8 90.7 63.0 132.1 63.8M129.5 63.8C129.3 69.9 130.1 76.0 130.5 82.0M129.8 80.2C89.2 79.5 48.7 79.1 8.1 79.6M10.2 80.3C9.4 74.0 9.5 67.8 9.5 61.5" fill="none" stroke="#24292f" stroke-width="1.6" stroke-opacity="0.75" stroke-linecap="round"/> +<path d="M18.4 10.7C52.8 10.8 87.2 8.9 121.6 9.8M120.6 9.2C120.8 14.9 121.0 20.6 120.3 26.3M120.6 23.9C86.7 22.4 52.9 22.4 19.1 23.3M19.7 24.8C20.6 19.0 21.6 13.3 20.5 7.4M32.5 24.5C57.0 24.6 81.6 24.4 106.1 23.4M106.1 21.5C104.6 36.4 106.1 51.5 105.8 66.4M106.2 64.7C81.5 65.4 56.8 66.0 32.1 64.6M33.8 67.2C33.2 52.6 34.3 38.0 33.6 23.4M9.6 64.6C50.0 64.0 90.3 65.2 130.7 63.6M129.5 62.2C129.9 68.9 129.4 75.7 130.7 82.4M130.1 79.7C89.8 80.0 49.5 80.0 9.1 80.6M9.3 81.3C9.8 75.1 10.1 69.0 9.7 62.8" fill="none" stroke="#24292f" stroke-width="1.2" stroke-opacity="0.28" stroke-linecap="round"/> +</svg> +``` + ### circle-a-light.svg [testmark]:# (circle-a-light.svg) @@ -117,6 +127,16 @@ Regenerate with `go test -run TestSketchSnapshots -testmark.regen` and review th </svg> ``` +### plinth-dark.svg + +[testmark]:# (plinth-dark.svg) +```svg +<svg xmlns="http://www.w3.org/2000/svg" width="140" height="84" viewBox="0 0 140 84"> +<path d="M17.9 10.4C52.3 11.1 86.6 9.9 121.0 10.5M119.7 9.4C118.9 15.0 119.9 20.5 119.6 26.0M121.0 24.1C87.2 23.9 53.5 24.5 19.8 23.6M19.8 26.2C20.8 20.0 20.4 13.8 20.4 7.6M31.4 24.3C56.8 23.9 82.3 24.8 107.8 23.8M106.0 23.0C106.7 36.9 106.8 50.9 106.2 64.8M107.6 63.6C82.9 64.4 58.2 64.5 33.5 63.9M34.3 64.4C33.7 50.7 33.6 37.0 33.8 23.3M8.8 63.6C49.7 63.3 90.6 63.9 131.5 64.2M129.8 62.7C129.1 68.8 129.1 74.9 130.2 80.9M130.6 80.2C89.7 79.8 48.8 80.1 8.0 80.5M9.8 82.4C10.4 75.7 10.5 68.9 10.1 62.2" fill="none" stroke="#e6edf3" stroke-width="1.6" stroke-opacity="0.75" stroke-linecap="round"/> +<path d="M17.2 9.8C52.2 10.0 87.1 10.3 122.1 10.6M120.6 9.8C120.3 15.4 119.9 20.9 120.0 26.5M122.1 23.8C87.9 22.3 53.6 24.3 19.4 23.6M20.4 26.6C19.9 20.9 20.2 15.3 20.7 9.7M33.4 23.5C57.9 22.3 82.4 24.1 106.8 24.2M105.9 22.8C105.4 37.0 105.2 51.2 106.5 65.4M106.1 64.5C81.9 65.0 57.8 62.9 33.6 63.3M33.3 66.3C34.2 51.6 32.5 37.0 33.8 22.4M8.2 63.5C49.5 63.2 90.7 64.7 132.0 63.6M129.5 61.5C129.3 68.3 130.3 75.2 129.5 82.0M131.4 79.4C90.5 80.4 49.7 79.0 8.9 80.2M10.6 81.8C9.3 75.7 9.2 69.6 10.4 63.5" fill="none" stroke="#e6edf3" stroke-width="1.2" stroke-opacity="0.28" stroke-linecap="round"/> +</svg> +``` + ### circle-a-dark.svg [testmark]:# (circle-a-dark.svg)