Modernises the pystache-rendered IDS audit report while keeping every
existing Mustache variable and behaviour working, and without touching
reporter.py's data shape.
- Replace the Google Fonts link with a system font stack, since these
reports are emailed and archived offline.
- Give the summary a proper header: three distinct stat cards for
specifications, requirements and checks, each with its own percent
and pass/total, plus a short note that a spec is pass/fail as a unit
(so "99% of checks pass" can coexist with far fewer specs passing).
- Add a "jump to first failure" link and a "show failures only" toggle,
implemented as plain inline JS with no dependency; the report stays
fully readable with JavaScript disabled.
- Rework entity lists from monospace blobs into scannable tables.
- Add prefers-color-scheme dark mode and a print stylesheet with
sensible page breaks and colour-independent pass/fail cues.
- Fix the `{{#total_ckecks}}` typo: that block referenced a field that
never existed on a requirement (only specifications have
total_checks) and, even fixed, only ever rendered an empty
<table><thead></thead></table> with no content. Replaced it with
`{{^total_applicable}}`, a field that does exist on every
ResultsRequirement, driving a real "no applicable elements, so this
requirement was not checked" note instead of dead markup.
A redesign of the IfcTester HTML report. Opening as a draft because this is a design proposal rather than a bug fix, and design is a matter of taste that belongs to whoever maintains it. Happy to change direction, split it up, or close it if it is not wanted.
Why
The report is the artefact people actually send to clients and consultants, so it is worth it looking good. The current template is Arial on white with flat colour blocks, and on a large audit everything carries the same visual weight, so finding the failures means scrolling.
What changed
Only templates/report.html. reporter.py is untouched, so the JSON, ODS, OdsSummary and BCF reporters are unaffected and the data contract is unchanged. Every Mustache variable used already exists in Html.report(); nothing new is computed and nothing was added to the template's logic, since pystache is logic-less.
#97cc64 and #fb5a3e are kept as the identity colours. They now drive accents and borders rather than carrying text, and pills use darker solid shades so white text meets WCAG AA on them (5.53:1 for pass, 7.03:1 for fail).
A real bug fixed along the way
Line 170 of the current template has {{#total_ckecks}}, a typo for total_checks, so the block has never rendered. Correcting the spelling would not have helped either: total_checks exists on a specification, not on a requirement, so it would have produced an empty table. It is replaced with {{^total_applicable}}, which does exist per requirement, driving a real message when a requirement was never checked because nothing applicable was found.
Verification, and its limits
Rendered against a generated IDS and IFC covering a passing spec, a failing spec, a skipped spec, a prohibited spec, a spec with no requirements, and one with 150 entities so the omitted-entity and extra_of_type grouping paths actually render. Confirmed no unresolved tags, the HTML parses, and the inline JS parses. Contrast ratios were computed rather than eyeballed.
Stated plainly: this has not been checked in a browser against a real project audit. The verification above is structural. Before this is worth merging, someone should open it on a real report, in both themes, and print it. I am happy to do that and post screenshots, or to hand over a rendered sample.
@Moult this one is yours to judge rather than mine. If the direction is wrong, say so and I will drop it. If the direction is right but the details are off, tell me which parts and I will rework them. And if you would rather the report stayed as it is, that is a perfectly good answer too.
Produced with AI assistance.