Skip to content
Back to skills

Rule Report Shell

ASecurity

The house shell for any HTML report, audit, or findings page an agent publishes: summary-first cards that expand on click with staggered detail, themed scrollbars, and a token system that survives both themes. Load before writing or editing an HTML page a person will read.

  • 6 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 3, 2026
ai-agentsshell

Works with

  • cursor
  • cli

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 20, 2026

npx -y skills add djnsty23/claude-auto-dev --skill rule-report-shell --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Rule Report Shell?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Rule Report Shell
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/djnsty23-rule-report-shell/badge)](https://www.skillsdirectory.com/skills/djnsty23-rule-report-shell)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: rule-report-shell
description: "The house shell for any HTML report, audit, or findings page an agent publishes: summary-first cards that expand on click with staggered detail, themed scrollbars, and a token system that survives both themes. Load before writing or editing an HTML page a person will read."
when_to_use: "Before writing or editing an HTML report, audit, findings page, or any artifact a human will read rather than a machine."
user-invocable: false
allowed-tools: Read, Grep, Glob
paths:
  - "**/*.html"
---

# The report shell

Copy `references/report-shell.html` and replace the content. Do not rebuild the
CSS from memory — four of the rules below were found by measuring a live page,
and each one looks correct in source right up until it is rendered.

## Why this exists

`[measured 2026-08-25]` A report built without it scored **5/10** on review, and
the two complaints were the two things this file fixes: *"text is too stacked,
not clean enough"* and *"scroll is another color"*.

## The four things that are not obvious

**Scrollbars do not inherit your theme.** A dark page with an unstyled `overflow`
container gets the operating system's light scrollbar — a white rail down a
near-black code well. Nothing in the page hints at it, and no repo checked had
any scrollbar styling at all. Set `scrollbar-color` and `scrollbar-width` *and*
the `::-webkit-scrollbar` block; browsers split across the two.

**The tested `0fr` → `1fr` disclosure failed in this shell's flex-card layout.**
The following measurements describe that specific configuration, not every
grid/flex disclosure:

| child `overflow` | expand | collapse |
|---|---|---|
| `hidden` | **0px** — broken | works |
| `visible` | 500.422px — works | **stuck open** — broken |

`overflow:hidden` is what the collapse needs, and it zeroes the child's automatic
minimum, so `minmax(auto, 1fr)` resolves to zero on the way open. You get one
direction or the other, never both. `minmax(0,1fr)` does not rescue it.

Use `max-height` with the value read from `scrollHeight` **at click time**. Never
a constant: a guessed cap silently truncates the longest card, which is always
the card worth reading. Re-measure on `resize`, because reflowed text is taller.

**Rhythm is a ratio, not a value.** Space *between* sections is 3× the space
*within* them (68px against ~18px). Uniform spacing is what reads as "stacked" —
every element the same distance from its neighbour gives the eye nothing to
group on.

**Summary first, detail earned.** Every card shows one or two lines. Detail lives
behind the disclosure and arrives as bullets that fade in one at a time, ~70ms
apart. The stagger is the whole delight; keep it under six bullets or the last
one arrives after the reader has moved on.

## Interaction

**The whole card is the hit area.** One click handler on `.card`; the button
inside it is the visible affordance, not the only target. Two handlers is how
`data-open` and `max-height` drift out of sync.

Two guards in this template:

```js
if (e.target.closest('.btn, .well, a')) return;      // never hijack a control
if (window.getSelection().toString()) return;         // they are reading, not toggling
```

Without the second, selecting a sentence collapses the card under the cursor.

## What not to change

The token block defines the **complete** palette on bare `:root` (dark, since
this shell commits to dark) and re-declares it in *both* directions — under
`prefers-color-scheme: light` guarded by `:not([data-theme="dark"])`, and under
`[data-theme="light"]`. A colour declared only inside a media block never applies
in the default un-stamped state, which renders one theme's text on the other
theme's ground.

`body` sets an explicit background from a token. A transparent body borrows the
host's ground and the page inverts.

## Verify it, do not assume it

Retain a native keyboard-operable disclosure button, keep `aria-expanded` in
sync, and verify Enter/Space, focus, text selection and embedded controls after
content changes. Test long content, zoom, both themes and reduced motion;
recompute expanded height after asynchronous content changes as well as resize.
Copying the shell is a starting point, not proof the resulting report works.


Assert `innerWidth`/`innerHeight` in the same call that measures anything. A
zero-height viewport reports a working disclosure as broken and an open card as
collapsed — both readings were produced while building this, and the zero-viewport
one looked like a pass.

Files in this skill

  • SKILL.md4.1 KB
  • references/report-shell.html25.9 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…