feat(screens): phase 9 — real screenshots, from a real shard
All checks were successful
PR checks / checks (pull_request) Successful in 1m25s

D4 asked for screenshots of the review stack rather than placeholders. Seventeen
of them: eleven of the site in a browser, six of the app on a phone, all from one
demo deployment wired to a running ServUO shard over a real sidecar, captured on
one day (D42).

The deployment is branded "Runic Gateway Demo" rather than a real community (D43),
and the captures sit beside the claims they support — the homepage, /features/, and
five of the administration pages phase 7 could describe but not show (D44).

The rig is committed rather than remembered (D45):

  scripts/seedDemo.mjs        content, by driving the site's own API — never SQL,
                              because a row the product could not have produced is
                              a screenshot of a product that does not exist
  src/data/screens.mjs        every capture: route, viewport, scroll, alt, caption
  scripts/captureScreens.mjs  npm run screens:capture
  scripts/checkScreens.mjs    the ninth check script, in CI

Shard-side dressing is servuo-plugins' scaffolding (D46), never deployed.

The rig found five things nothing else had. One is fixed upstream — a fresh
module-uo install pinned wire protocol 3 against a sidecar speaking 4, released as
v1.0.2, which this repo's own facts check then caught in platform.json. Four are
raised as product observations and worked around in the rig: a renamed guild
member never reaches the site, a guild deleted while the shard is down is a ghost
row forever, "Houses in danger" cannot show a house that was already collapsing,
and the app's news list prints raw ISO timestamps.

Players online reads 0. Logging a character in needs a UO client driven by hand,
and that is where this stopped — PLAN.md §10 says exactly why, and how to retake
the two frames that would change.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-25 09:55:55 -05:00
parent 31d914ba44
commit c29ec94f46
36 changed files with 2253 additions and 59 deletions

View File

@@ -2,6 +2,7 @@
import Base from '../layouts/Base.astro';
import PageHeader from '../components/PageHeader.astro';
import NotBuilt from '../components/NotBuilt.astro';
import Screenshot from '../components/Screenshot.astro';
import platform from '../data/platform.json';
import {
@@ -55,6 +56,26 @@ import {
assertCapabilityCoverage(platform.moduleUoCapabilities);
assertDetailCoverage();
/**
* Which screenshots sit under which group (PLAN.md §13 phase 9, D44).
*
* Deliberately here and not in `capabilities.mjs`. That file is a contract — two build-time
* assertions read it and `/modules/` and the homepage render from it — and a group is
* defined by what the software does, not by what somebody has got round to photographing.
* A group with no figure is the normal case, not an omission: Infrastructure is about where
* the container runs and who owns the database, and a picture of a web page says nothing
* true about either.
*
* `Screenshot` throws on an id that `screens.mjs` does not declare, so a typo here fails the
* build rather than rendering a broken image.
*/
const groupScreens: Record<string, string[]> = {
community: ['news'],
'game-intelligence': ['marketplace', 'spawn-atlas', 'guilds', 'houses'],
administration: ['admin-dashboard', 'admin-users'],
integration: ['admin-modules'],
};
const title = 'Features';
const description =
'What a Runic Gateway deployment does — core, and what the installed game module adds.';
@@ -110,6 +131,14 @@ const description =
</li>
))}
</ul>
{groupScreens[group.id] && (
<div class="group__shots">
{groupScreens[group.id].map((id: string) => (
<Screenshot id={id} />
))}
</div>
)}
</section>
))
}
@@ -118,6 +147,16 @@ const description =
</Base>
<style>
/* One up, at the column's full width, even where a group has four of them.
Two-up was tried first and is the obvious layout for a set of figures — but these are
screenshots of a dense interface, and halving the width puts the product's own type at
around a third of its real size, which reads as a thumbnail of something rather than a
picture of it. A long section of legible evidence beats a tidy grid of unreadable
tiles. */
.group__shots {
margin-top: 1.75rem;
}
.group__head {
display: flex;
flex-wrap: wrap;