A stone importer's trade catalog: ten slabs on the racks at two New Jersey yards, browsed by facet, and then one slab's specification page.
Direction
| Lever | Decision |
|---|---|
| Archetype | Index, faceted. A sticky rail of native checkbox facets against one list that takes the rest of the width. |
| Data stance | Table-first. The slab inventory table is the product, and the photograph is a column in it rather than an illustration beside it. |
| Density | Default. --mc-space-md inside a row, --mc-space-xl between groups, --mc-space-3xl between sections. |
| The one bold thing | Stock carries the minute it was counted, and the minutes differ by row. No specimen frame holds anything but the material. A sold slab keeps its page and routes to the two sequential cuts behind it. |
Why this product suits this system
material-catalog is the only system here written for a business whose product is a physical object photographed under one lighting setup, and whose photograph is a claim somebody can send back on a truck. Its non-negotiables are all about not getting in the way of that: a fixed neutral surround identical in both themes, no radius on a specimen, no tint over a material, and a scale solver that decides how wide an image has to be before a 4 mm vein exists in it.
A slab yard pushes every one of those. Each slab is unique, so the index cannot be a grid of one hero shot per material; stock goes stale in hours, so a figure with no timestamp is a lie; and the buyer's four questions — finish, thickness, slab dimensions, lot — are exactly what a table answers and a card does not.
Generator
mat_tokens.py --both > tokens.css
The brief recorded mat_tokens.py with no flag, which emits light only. --both was run instead so the page can meet CONTRACT.md §5 on themes; its :root block is byte-identical to the flagless output, and the flag adds [data-theme="light"], [data-theme="dark"] and a prefers-color-scheme block. The generator's own --self-test holds the specimen tokens identical across the two themes, which is the reason a dark rail beside a light specimen grid is legitimate here.
The scale, solved rather than chosen
mat_tokens.py --scale
- A row's detail plate is 168 px of a declared 300 mm field of view — 1.79 mm per pixel, which puts a 4 mm feature across 2.2 px and clears the system's
--mc-px-per-feature: 2floor. It is what makes slab 01 tell itself apart from slab 02 in the index. - A whole slab at that width would be 18 mm per pixel, so the full-piece view is not in the table at all. It is on the slab's own page at 1600 px, which is the width
--scalegives for fine veining on a jumbo slab: 1.85 mm per pixel.
Deviations from CONTRACT.md
- §2, images. Photographs are WebP files under
img/rather than inlinedata:URIs. Base64 inside the document would add roughly a third to 549 KB of imagery and put it all in front of the first paint on a page whose subject is a photograph. Every<img>still carries explicitwidth,heightand a realalt. - §1, tokens.
tokens.csswas regenerated with--bothrather than patched. See the Generator section.
Gates
catalog_lint.py, audit_page.py, slop_scan.py, craft_lint.py, motion_lint.py, layout_lint.py, copy_lint.py, direction_check.py, contrast.py and aria_lint.py. Output is in the handover.