solo-io / solo-io/docs-theme-extras

reuse-image: version overrides resolve by convention, dark variants do not

Open
#41 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
0
Forks
0
Avg merge
18h 13m
Merged PRs (30d)
20

Description

Summary

reuse-image resolves one axis by convention and the other by explicit parameter, and I think that asymmetry is the bug rather than any single rendering behavior.

  • Version overrides are automatic. utils/resolve-versioned-image.html prefers assets/<dir>/<version>/<file> over the bare path with no author input. A page writes img/foo.png and a version-specific override is picked up wherever it exists, and dropped again when it is removed.
  • Dark variants are not. A dark counterpart needs an explicit srcDark= on the call, even though <stem>-dark.<ext> is a rigid naming convention across every consumer repo, and even though the screenshot harnesses generate the dark file by that convention automatically.

So the same authoring model gives one override for free and makes the other manual. That is worth closing, but the obvious fix regresses kgateway, so this issue proposes a sequence rather than a patch.

Where this surfaced

agentgateway/website#999 converts 21 provider tabs in the standalone LLM quickstart from the legacy reuse-image-light + reuse-image-dark pair to a single reuse-image. Its Playwright spec captures a light and a dark baseline per provider, and docs-image-map.json declares a -dark.png destination for all 21, but 20 of the 21 tabs are written as {{< reuse-image src="…" >}} with no srcDark. Per reuse-image.html, a call with no srcDark takes the SINGLE branch and emits one figure shown in both modes, so that PR publishes 20 dark PNGs no page ever references.

That is fixable in the PR by adding srcDark to 20 tabs. The reason it is filed here instead is that under convention-based resolution those 20 edits would not have been necessary at all.

Why auto-discovery cannot just be turned on

Making the SINGLE branch look for <stem>-dark.<ext> breaks the legacy stacked pattern that docs-theme-extras.css:40 currently defends:

.dark .reuse-image-nodark:has(+ .toggle-light) { display: none; }

That rule exists because a lone reuse-image followed by a sibling reuse-image-dark for the same figure would otherwise stack two images in dark mode. It works by keying on the .reuse-image-nodark wrapper class that only the SINGLE branch emits.

If the SINGLE branch starts auto-resolving a dark file, those sites flip to the PAIR branch. The wrapper becomes .toggle-dark, the :has() guard no longer matches, and the sibling reuse-image-dark still emits its own .toggle-light figure, so dark mode renders two dark images. A Hugo shortcode cannot see whether a reuse-image-dark follows it, which is precisely why the current guard lives in CSS rather than in the template, so there is no in-template way to make auto-discovery conditional on the absence of that sibling.

In other words, the legacy pattern and convention-based dark resolution are mutually exclusive. The legacy sites have to go first.

Consumer survey

Scanned for lone reuse-image src= calls with no srcDark, excluding public/, resources/, node_modules/, and any nested worktree or clone directory.

Repo Commit Lone calls Legacy stacked pairs Stranded -dark asset in canonical content
kgateway-oss 8abb1a4c 114 62 0
agentgateway-oss-website 98223d2a 416 0 0
docs bd1868b97 193 6 0

Two things this shows:

  1. Auto-discovery would be a no-op in agentgateway and near-enough in the hub. Zero stranded dark assets means the convention is already airtight in canonical content: wherever a -dark file exists, the page references it. Nothing would change rendering.
  2. kgateway carries the whole cost. 62 of the 68 legacy pairs across all three consumers are in kgateway-oss.

Every "stranded" hit in an early pass turned out to be inside .claude/worktrees/ or .oss-clones/, so they are duplicates of content already counted, not additional sites.

Scoping: the kgateway-oss migration

62 pairs across 36 files, 26 of them under assets/kgw-docs/ where one edit serves every version.

The transform is fully mechanical. Across all 62 pairs:

  • 0 have any attribute divergence between the two calls. Where one carries width, alt, or caption, so does the other, identically.
  • 0 have a blank line between the two calls, so the two are always adjacent lines.
  • Extensions split 32 .svg / 30 .png, which makes no difference to the transform.

Two classes, and they get opposite treatment:

Class 1: 46 pairs where srcDark points at the same file as src

The dark call is a pure no-op duplicate. 45 of the 46 have no -dark asset on disk at all, so there is no dark variant to preserve.

Migration: delete the reuse-image-dark line. No srcDark is added. The lone reuse-image already renders in both modes via the SINGLE branch, which is the correct end state, and it is what the page effectively shows today anyway.

Class 2: 16 pairs where srcDark points at a distinct, real file

All 16 dark assets exist. Migration: merge into srcDark= on the first call, delete the second.

File Light Dark
assets/kgw-docs/pages/about/architecture.md:7 gw-control-plane-components.svg …-dark.svg
assets/kgw-docs/pages/about/architecture.md:43 translation-loop.svg …-dark.svg
assets/kgw-docs/pages/integrations/istio/sidecar/ingress.md:23 sidecar-ingress.svg …-dark.svg
assets/kgw-docs/pages/setup/listeners/sni.md:13 sni-listener.svg …-dark.svg
assets/kgw-docs/snippets/cr-ov.md:3 kgw-crs-light.svg kgw-crs-dark.svg
assets/kgw-docs/pages/traffic-management/route-delegation/basic.md:7 route-delegation-basic.svg …-dark.svg
assets/kgw-docs/pages/traffic-management/route-delegation/label.md:10 route-delegation-labels.svg …-dark.svg
assets/kgw-docs/pages/traffic-management/route-delegation/label.md:31 route-delegation-labels-wildcard.svg …-dark.svg
assets/kgw-docs/pages/traffic-management/route-delegation/multi-parent.md:7 route-delegation-multi-parent.svg …-dark.svg
assets/kgw-docs/pages/traffic-management/route-delegation/multi-level-delegation.md:7 route-delegation-multi-level.svg …-dark.svg
assets/kgw-docs/pages/traffic-management/route-delegation/header-query.md:11 route-delegation-header-query.svg …-dark.svg
assets/kgw-docs/pages/traffic-management/route-delegation/inheritance/kgateway-policies.md:16 route-delegation-inheritance-kgateway.svg …-dark.svg
assets/kgw-docs/pages/traffic-management/route-delegation/inheritance/native-policies.md:16 route-delegation-inheritance-native.svg …-dark.svg
content/docs/envoy/latest/setup/listeners/sni.md:18 sni-listener.svg …-dark.svg
content/docs/envoy/2.3.x/setup/listeners/sni.md:18 sni-listener.svg …-dark.svg
content/docs/envoy/main/setup/listeners/sni.md:18 sni-listener.svg …-dark.svg

sni-listener.svg appears four times because the three versioned content/docs/envoy/* copies duplicate the shared assets/kgw-docs/pages/setup/listeners/sni.md snippet. Worth checking whether the versioned copies can be replaced by a reuse of the snippet as part of this.

One content bug found while scoping

assets/kgw-docs/pages/about/deployment-patterns.md:73 renders img/sidecar-ingress.svg and points srcDark at the same light file, while assets/kgw-docs/pages/integrations/istio/sidecar/ingress.md:23 pairs that same diagram correctly with img/sidecar-ingress-dark.svg. The dark diagram exists and that page does not use it. This is worth fixing regardless of what happens to the shortcode.

Note for anyone re-running a scan: a <stem>-dark.<ext> heuristic undercounts, because cr-ov.md uses a -light/-dark suffix pair (kgw-crs-light.svg / kgw-crs-dark.svg) rather than a bare stem plus -dark. My first pass reported 15 of 16 dark assets present for that reason; the real figure is 16 of 16.

Proposed sequence

  1. Migrate kgateway-oss. 36 files, two mechanical classes as above, plus the deployment-patterns.md fix. Scriptable, but the diff should be eyeballed in both modes because class 1 deletes lines.
  2. Migrate the 6 legacy pairs in solo-io/docs. Not yet broken out by class in this issue.
  3. Delete the .reuse-image-nodark guard from docs-theme-extras.css:40 and the SINGLE branch's wrapper class, once no consumer relies on it. That removal is the actual prize here: the guard is a CSS workaround for an authoring pattern nothing would still use.
  4. Then decide on auto-discovery in the SINGLE branch, which by that point has no pattern left to collide with.

Open question on step 4

Even with the legacy pattern gone, auto-discovery makes srcDark redundant on the happy path but changes the meaning of a lone reuse-image from "show this in both modes" to "show this, or its dark sibling if one happens to exist on disk". That is action-at-a-distance: adding an asset changes how an untouched page renders. The alternative is to keep srcDark explicit and instead add a build-time check that fails when a -dark asset exists on disk and no page references it, which would have caught agentgateway/website#999 without changing any rendering semantics.

I lean toward the lint rather than the auto-discovery, on the grounds that the version-override convention is safe because a version directory is unambiguous about intent, whereas a -dark file sitting next to its light counterpart is not.


Scanned at docs-theme-extras 8058485.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with reuse-image.html, utils/resolve-versioned-image.html, and docs-theme-extras.css:40, then review the listed kgateway and docs content files. Confirm the legacy pairs and the deployment-patterns.md dark-image bug, inspect both rendering modes, and resolve whether the final change should be dark-file auto-discovery or a build-time check after migration.

Written by the indexing model from the issue text.

Assessment

Tech stack
css, html, markdown
Domain
documentation, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.