the provenance ledger: the log drops its table
commit 65137bffd74f89b7ad0fb8cdbfcd727066656159 · parent dc0cfb64ec
· browse this tree
Ximianth, 2026-10-26 23:18:31 UTC
A museum documents an object's history as provenance; the log page now reads that way. Each commit is a ledger row under a light hand-rule: the subject as prose, wrapping freely, and a soft attribution line whose short sha wears a chip outline (the frame tile's small sibling, drawn so repeat: round can stretch to any text width) and reads as the button to the commit page. The subject links too, in quiet ink: tap targets and forge habit both want it, and a hundred accent rows would shout. Dropping the table is also the phone-width fix: nothing is left to crush.
diff --git a/chrome.go b/chrome.go index ed8bc62..f616807 100644 --- a/chrome.go +++ b/chrome.go @@ -319,15 +319,43 @@ footer.ground .colophon { margin: .5rem 0 1.1rem; } -/* Listing and log tables. */ -article table.tree td, article table.tree th, -article table.log td, article table.log th { border: none; padding: .15rem .6rem; } -article table.tree tbody tr:hover, article table.log tbody tr:hover { background: var(--well); } +/* The ledger: provenance rows on the log page. Subjects are prose and wrap + freely; the attribution line stays soft and small. Links wear ink, not accent: + a hundred accent rows would shout; hover answers the "is it live" question. */ +article .provenance { + margin: -.4rem 0 1.6rem; + font-size: .78rem; + letter-spacing: .16em; + color: var(--ink-soft); +} +article ul.ledger { list-style: none; padding: 0; } +ul.ledger li { padding: .5rem 0 .8rem; } +ul.ledger .subject { margin: 0; max-width: 44rem; } +ul.ledger .subject a { color: var(--ink); text-decoration: none; } +ul.ledger .subject a:hover { color: var(--accent); text-decoration: underline; } +ul.ledger .attrib { + margin: .3rem 0 0; + font-size: .78rem; + color: var(--ink-soft); +} +a.sha { + font-family: monospace; + color: var(--ink); + text-decoration: none; + display: inline-block; + padding: 0 .35rem; + margin-right: .35rem; +} +a.sha:hover { color: var(--accent); } + +/* Listing tables. */ +article table.tree td, article table.tree th { border: none; padding: .15rem .6rem; } +article table.tree tbody tr:hover { background: var(--well); } article th { text-align: left; background: none; } /* Table links skip the underline: in a column of links it is pure noise; the accent color and the row hover carry the affordance. Hover restores it. */ -article table.tree a, article table.log a { text-decoration: none; } -article table.tree a:hover, article table.log a:hover { text-decoration: underline; } +article table.tree a { text-decoration: none; } +article table.tree a:hover { text-decoration: underline; } article td.name { white-space: nowrap; } article td.size { text-align: right; color: var(--ink-soft); white-space: nowrap; } article td.date { color: var(--ink-soft); white-space: nowrap; } @@ -363,6 +391,18 @@ nav.crumbs, article h1, article h2 { background-size: auto 10px; padding-bottom: .55rem; } +/* Each ledger row sits under its own light hand-rule; the chip outline around a + sha is the small sibling of the frames, so it reads as a button, not a well. */ +ul.ledger li { + background-image: %s; + background-position: bottom left; + background-repeat: repeat-x; + background-size: auto 9px; +} +a.sha { + border: 7px solid transparent; + border-image: %s 8 / 7px round; +} /* Rough-ruled frames, as border-images. The tile is sliced at 16 and the border is near that size, so the stroke renders at the weight it was drawn. */ .exhibit { @@ -388,7 +428,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("plinth"), u("rule"), u("frame"), u("frame"), + u("flank"), u("ground"), u("plinth"), u("rule"), u("rule"), u("chip"), 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 9d01fd7..47f42b6 100644 --- a/pages.go +++ b/pages.go @@ -561,13 +561,18 @@ func looksBinary(b []byte) bool { // ---- log ---- +// The provenance ledger: no table. Each commit is a row under a light hand-ruled +// line -- the subject as prose, free to wrap, and a soft second line carrying the +// sha (a chip-outlined button to the commit page), author, and absolute date. +// This shape is also why the page survives phone widths. var logTmpl = template.Must(template.New("log").Parse(`<h1>log: {{.Title}}</h1> -<table class="log"> -<thead><tr><th>commit</th><th>date</th><th>author</th><th>subject</th></tr></thead> -<tbody> -{{range .Rows}}<tr><td class="hash"><a href="{{.Href}}">{{.Sha}}</a></td><td class="date">{{.Date}}</td><td>{{.Author}}</td><td>{{.Subject}}</td></tr> -{{end}}</tbody> -</table> +<p class="provenance">provenance · newest first</p> +<ul class="ledger"> +{{range .Rows}}<li> +<p class="subject"><a href="{{.Href}}">{{.Subject}}</a></p> +<p class="attrib"><a class="sha" href="{{.Href}}">{{.Sha}}</a> {{.Author}} · {{.Date}}</p> +</li> +{{end}}</ul> {{if .Capped}}<p>Showing the {{.Limit}} most recent commits.</p> {{end}}`)) diff --git a/sketch.go b/sketch.go index 16b5284..443bf4d 100644 --- a/sketch.go +++ b/sketch.go @@ -139,6 +139,7 @@ func sketchAssets(seed string) map[string][]byte { m["flank-"+p.scheme+".svg"] = flankSVG(seed, p) m["ground-"+p.scheme+".svg"] = groundSVG(seed, p) m["plinth-"+p.scheme+".svg"] = plinthSVG(seed, p) + m["chip-"+p.scheme+".svg"] = chipSVG(seed, p) for _, v := range []string{"a", "b", "c"} { m["circle-"+v+"-"+p.scheme+".svg"] = circleSVG(seed+"/"+v, p) } @@ -339,3 +340,28 @@ func plinthSVG(seed string, p sketchPalette) []byte { sb.WriteString("</svg>\n") return []byte(sb.String()) } + +// chipSVG is the frame's small sibling: a border-image tile for inline chips +// (the ledger's sha buttons). A 48x48 tile sliced at 8 with lines at inset 4, +// so a border a hair under the slice renders the stroke near 1:1; displacement +// pins to zero at the slice crossings, same scheme as frameSVG, so repeat: round +// tiles the middles cleanly at whatever width the chip's text wants. +func chipSVG(seed string, p sketchPalette) []byte { + rng := newSketchRand(seed + "/chip/" + p.scheme) + var sb strings.Builder + svgOpen(&sb, 48, 48) + edge := func(d *strings.Builder, amp float64) { + j := func() float64 { return rng.rangef(-amp, amp) } + wobblePath(d, rng, []pt{{1.8 + j(), 4 + j()}, {8, 4}, {24 + j(), 4 + j()}, {40, 4}, {46.2 + j(), 4 + j()}}, amp) + wobblePath(d, rng, []pt{{44 + j(), 1.8 + j()}, {44, 8}, {44 + j(), 24 + j()}, {44, 40}, {44 + j(), 46.2 + j()}}, amp) + wobblePath(d, rng, []pt{{46.2 + j(), 44 + j()}, {40, 44}, {24 + j(), 44 + j()}, {8, 44}, {1.8 + j(), 44 + j()}}, amp) + wobblePath(d, rng, []pt{{4 + j(), 46.2 + j()}, {4, 40}, {4 + j(), 24 + j()}, {4, 8}, {4 + j(), 1.8 + j()}}, amp) + } + var d1, d2 strings.Builder + edge(&d1, 0.8) + edge(&d2, 1.1) + svgPath(&sb, d1.String(), p.ink, 1.2, 0.75) + svgPath(&sb, d2.String(), p.ink, 0.9, 0.28) + sb.WriteString("</svg>\n") + return []byte(sb.String()) +} diff --git a/testdata/pages.md b/testdata/pages.md index f5b0546..3b749bb 100644 --- a/testdata/pages.md +++ b/testdata/pages.md @@ -390,13 +390,17 @@ Content-Type: text/html; charset=utf-8 <a class="vb" href="/fixturama/" title="repo home" style="--dy:2px">home</a> </nav> <main><article><h1>log: main</h1> -<table class="log"> -<thead><tr><th>commit</th><th>date</th><th>author</th><th>subject</th></tr></thead> -<tbody> -<tr><td class="hash"><a href="/fixturama/commit/ced91a8519b59966124301e6383532f24223528b">ced91a8519</a></td><td class="date">2026-01-02</td><td>Ada Fixture</td><td>add docs and src</td></tr> -<tr><td class="hash"><a href="/fixturama/commit/64ac67a35d36079e167cb8f929fd57f859c8b5d1">64ac67a35d</a></td><td class="date">2026-01-02</td><td>Ada Fixture</td><td>inaugurate with a readme</td></tr> -</tbody> -</table> +<p class="provenance">provenance · newest first</p> +<ul class="ledger"> +<li> +<p class="subject"><a href="/fixturama/commit/ced91a8519b59966124301e6383532f24223528b">add docs and src</a></p> +<p class="attrib"><a class="sha" href="/fixturama/commit/ced91a8519b59966124301e6383532f24223528b">ced91a8519</a> Ada Fixture · 2026-01-02</p> +</li> +<li> +<p class="subject"><a href="/fixturama/commit/64ac67a35d36079e167cb8f929fd57f859c8b5d1">inaugurate with a readme</a></p> +<p class="attrib"><a class="sha" href="/fixturama/commit/64ac67a35d36079e167cb8f929fd57f859c8b5d1">64ac67a35d</a> Ada Fixture · 2026-01-02</p> +</li> +</ul> </article></main> </div> <footer class="ground"> diff --git a/testdata/sketch.md b/testdata/sketch.md index b55977c..8ee5cdf 100644 --- a/testdata/sketch.md +++ b/testdata/sketch.md @@ -56,6 +56,16 @@ Regenerate with `go test -run TestSketchSnapshots -testmark.regen` and review th </svg> ``` +### chip-light.svg + +[testmark]:# (chip-light.svg) +```svg +<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"> +<path d="M2.4 4.1C4.3 4.1 6.1 4.2 8.0 4.0C13.3 3.7 18.6 4.1 23.9 3.4C29.2 3.5 34.6 4.4 40.0 4.0C42.3 3.7 44.6 4.5 46.9 3.6M43.2 2.2C43.3 4.2 43.7 6.1 44.0 8.0C44.1 13.3 44.3 18.6 44.2 24.0C43.9 29.3 44.6 34.7 44.0 40.0C43.9 42.1 44.4 44.3 44.0 46.4M45.9 44.8C43.9 44.9 41.9 44.8 40.0 44.0C34.5 44.4 29.0 43.6 23.5 44.0C18.3 44.2 13.2 44.7 8.0 44.0C5.8 44.0 3.8 45.1 1.6 44.6M4.0 46.9C4.4 44.6 4.8 42.3 4.0 40.0C3.9 34.5 3.5 29.1 4.1 23.6C3.5 18.4 3.4 13.2 4.0 8.0C4.4 6.2 3.3 4.3 4.1 2.5" fill="none" stroke="#24292f" stroke-width="1.2" stroke-opacity="0.75" stroke-linecap="round"/> +<path d="M2.6 3.9C4.4 3.1 6.2 4.6 8.0 4.0C13.3 4.1 18.6 3.8 23.8 4.8C29.2 4.4 34.6 3.5 40.0 4.0C42.1 4.7 43.7 2.4 45.7 3.0M45.1 1.1C44.1 3.3 43.5 5.6 44.0 8.0C43.5 13.5 44.4 19.0 43.5 24.5C43.0 29.7 43.5 34.9 44.0 40.0C44.6 42.1 44.8 44.3 43.8 46.3M45.2 42.9C43.5 43.7 41.7 43.7 40.0 44.0C34.8 44.8 29.7 44.0 24.6 43.7C19.1 43.2 13.5 43.0 8.0 44.0C6.1 44.4 4.1 43.1 2.3 44.2M3.4 45.3C2.9 43.4 2.9 41.7 4.0 40.0C3.0 34.7 3.4 29.4 4.1 24.1C3.3 18.7 3.2 13.4 4.0 8.0C4.1 5.6 3.5 3.3 3.0 1.0" fill="none" stroke="#24292f" stroke-width="0.9" stroke-opacity="0.28" stroke-linecap="round"/> +</svg> +``` + ### circle-a-light.svg [testmark]:# (circle-a-light.svg) @@ -137,6 +147,16 @@ Regenerate with `go test -run TestSketchSnapshots -testmark.regen` and review th </svg> ``` +### chip-dark.svg + +[testmark]:# (chip-dark.svg) +```svg +<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"> +<path d="M1.3 3.6C3.5 3.9 5.8 3.8 8.0 4.0C13.1 4.4 18.2 4.6 23.4 4.8C28.9 4.8 34.5 4.8 40.0 4.0C41.9 4.4 43.9 4.0 45.7 4.8M44.5 1.7C44.2 3.8 44.0 5.9 44.0 8.0C44.1 13.2 44.3 18.4 44.2 23.6C44.5 29.0 44.2 34.5 44.0 40.0C44.0 42.1 44.4 44.3 43.8 46.4M46.6 43.8C44.4 43.6 42.2 43.6 40.0 44.0C34.6 44.1 29.2 44.3 23.8 44.0C18.6 43.8 13.3 44.4 8.0 44.0C5.8 44.1 3.6 44.8 1.3 44.1M4.1 45.5C3.8 43.7 3.2 41.8 4.0 40.0C3.5 34.4 4.6 28.9 4.0 23.3C4.6 18.2 4.2 13.1 4.0 8.0C3.8 5.7 3.8 3.4 3.5 1.1" fill="none" stroke="#e6edf3" stroke-width="1.2" stroke-opacity="0.75" stroke-linecap="round"/> +<path d="M1.7 3.3C3.8 3.7 6.0 3.2 8.0 4.0C13.1 4.3 18.2 4.4 23.3 3.5C28.9 2.8 34.4 3.6 40.0 4.0C42.4 4.3 44.6 2.7 47.0 3.4M43.4 1.4C43.9 3.6 43.0 5.9 44.0 8.0C44.0 13.5 43.3 19.1 43.9 24.6C43.7 29.8 44.7 34.9 44.0 40.0C44.4 41.7 44.3 43.5 44.7 45.2M47.1 43.6C44.8 44.7 42.4 44.8 40.0 44.0C34.4 44.3 28.8 44.1 23.2 43.2C18.2 44.3 13.1 43.8 8.0 44.0C5.9 43.9 3.9 43.8 1.8 43.9M5.0 46.9C4.8 44.6 5.3 42.2 4.0 40.0C4.1 34.8 5.1 29.7 4.7 24.6C4.0 19.1 4.2 13.5 4.0 8.0C4.1 5.6 4.9 3.3 5.0 1.0" fill="none" stroke="#e6edf3" stroke-width="0.9" stroke-opacity="0.28" stroke-linecap="round"/> +</svg> +``` + ### circle-a-dark.svg [testmark]:# (circle-a-dark.svg)