frame the contents list, and give the highlight its own colours
Two defects only a screenshot could find, both mine. The table of contents did not look like one: list-style:none stripped the markers and nothing replaced them, so the entries read as two loose links in the prose. Hairlines above and below make it a block again. <mark> was using the browser default, black on yellow, which fights a dark page. It has explicit colours now, and a muted pair in dark mode. Also records a third, which is not a defect but reads like one: an included file's footnotes render where the include sits, so the page appears to end and restart halfway down. That is ADR-0038 working as documented — a fragment is converted on its own bytes — and the ids are correctly namespaced. Only the placement is unfortunate, so it goes on the latent list with the trigger that would justify changing it. Verified in the browser this time rather than by curl: the aside floats at 1280px and flows inline at 375px, grouped panels close each other with no script, and dark mode is readable throughout.
This commit is contained in:
@@ -119,6 +119,7 @@ with a stated reason. A list nothing drains is a graveyard of known defects.
|
||||
| The root listing's `<title>` repeats itself — "A Khosra Demo · A Khosra Demo" | Spotted 2026-08-01 by looking at the served page, not by any test: `base.html` joins page title and site title unconditionally, and at the root those are the same string. Cosmetic, and the fix is one `if` in a template — theme layer, not engine | The first time the reference theme is worked on (Phase G4 touches it), or sooner if a feed or OpenGraph title inherits the same doubling |
|
||||
| The theme and the index are two separate `atomic.Pointer` stores, so a request landing between them sees a new theme with the previous index | Accepted 2026-08-01 with ADR-0056: both halves are internally coherent and the gap is microseconds, so no page is ever internally inconsistent — it is simply not a snapshot of the disk. Closing it means one pointer holding both, which changes `web.Handler`'s signature and 20 test construction sites | Anything that makes the gap observable — a request rate high enough to land in it, or a feature where content and theme must agree exactly (an export, where every page is generated in one pass) |
|
||||
| `internal/web/example_test.go` rebuilds the extender list by hand, so it can drift from `cmd/khosra/wire.go` | A package cannot import a `main`, and `extensions.md` puts the list in `cmd` on purpose — nothing below it may know which features exist. Bounded today: the dialect's own test lives in `cmd/khosra/wire_test.go`, beside the real list, and the demo test fails loudly when the copy lags | The next change to the extender list, which must touch both — or a third copy appearing, which is the point at which the list wants a home a test can import |
|
||||
| An included file's footnotes render where the include sits, so a long fragment puts an `<hr>` and a numbered list in the middle of the article | Spotted 2026-08-01 by looking at the served page, not by any test. It is ADR-0038's documented consequence — a fragment is converted on its own bytes, so its notes belong to it — and the ids are correctly namespaced (ADR-0058). Only the placement reads badly | A fragment long enough that the break is jarring, or a theme that wants one endnote list per page — which needs the include to contribute notes to the parent document rather than render its own |
|
||||
| The picture memo is never evicted — one entry per picture on the site, for the life of the process | Correct for one author's site, and the alternative is an eviction policy nothing needs. It is keyed on size and modification time, so it cannot go stale, only grow | A site root large enough that memory matters, or a long-running process where pictures churn |
|
||||
|
||||
## Open questions
|
||||
|
||||
@@ -29,7 +29,9 @@ summary { cursor: pointer; font-weight: 600; }
|
||||
aside.side { border-left: 3px solid #d8d5cd; border-radius: 0; padding: 0 0 0 1rem; margin: 1.5rem 0; font-size: 0.95em; }
|
||||
.side-title { font-weight: 600; margin: 0 0 0.5rem; }
|
||||
@media (min-width: 55rem) { aside.side { float: right; width: 12rem; margin: 0.25rem 0 1rem 1.5rem; } }
|
||||
nav.toc ol { list-style: none; padding-left: 0; }
|
||||
mark { background: #fbf1a9; color: #16161a; padding: 0 0.15em; }
|
||||
nav.toc { border-top: 1px solid #d8d5cd; border-bottom: 1px solid #d8d5cd; padding: 0.5rem 0; margin: 1.5rem 0; font-size: 0.95em; }
|
||||
nav.toc ol { list-style: none; padding-left: 0; margin: 0; }
|
||||
nav.toc .toc-3 { padding-left: 1rem; }
|
||||
nav.toc .toc-4 { padding-left: 2rem; }
|
||||
@media (prefers-color-scheme: dark) {
|
||||
@@ -39,4 +41,6 @@ nav.toc .toc-4 { padding-left: 2rem; }
|
||||
.kind { color: #9a9a9a; }
|
||||
th, td { border-bottom-color: #33333c; }
|
||||
.admonition, aside.side { border-left-color: #33333c; }
|
||||
mark { background: #5d5320; color: #f2efe6; }
|
||||
nav.toc { border-color: #33333c; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user