# Scoring rubric — Swiirl Deck Benchmark

Quality is a **0–100** weighted score over **10 dimensions** (each 0–5).
**Cost and latency are published separately** and do not buy Quality rank.

Score against **evidence** (slide number, measured value, quoted headline) — not vibes.
Default to the lower anchor when a dimension is merely “fine”. A deck of all-4s is already strong.

| key | dimension | weight |
|---|---|---:|
| `narrative` | Narrative & tension | 12 |
| `clarity` | Message clarity / 3-second rule | 12 |
| `typography` | Typography system | 11 |
| `color` | Colour discipline | 11 |
| `layout_flat` | Layout, whitespace & flat-system fidelity | 11 |
| `brand` | Brand fidelity (Swiirl tokens + rules) | 10 |
| `craft` | Craft & polish | 10 |
| `proof` | Data & proof integrity | 9 |
| `variety` | Layout variety | 8 |
| `close` | The close / CTA | 6 |
| | **total** | **100** |

Weighted score = `Σ(weight × score/5)` normalised to 0–100.

## Swiirl brand hard rules (for `brand` / `color` / `layout_flat`)

- Inter (or system-ui stack), **sentence case**, no emoji
- Purple is a **highlight**, not wallpaper
- **Flat** surfaces — no elevation drop shadows
- Alternate light + dark sections; WCAG AA contrast on each section’s own background

## Gates (correctness, not style nits)

Deterministic gates from `harness/judge/deck_metrics.py` (HTML):

| id | meaning |
|---|---|
| G1 | Wall of text (one block >40 words) |
| G2 | Flat-system violation (elevation shadow) |
| G3 | Body text contrast &lt; 4.5:1 |
| G4 | Missing craft essential (print / keyboard / reduced-motion / viewport) |
| G5 | External framework import |

Human judgment gates (set in [review.html](review.html)): orphan hero stat, identical-grid, graveyard outro, layout overflow.

If gated, letter grade is capped at **C** (Quality number still shown). Reviewers may set `"gated": false` in an override when a gate is a known false positive.

## How to correct a score

1. Open [review.html](review.html)?run=&lt;run_id&gt;
2. Score dimensions + impression + notes
3. **Export override JSON** → save as `data/overrides/<run_id>.json`
4. `node harness/aggregate.mjs` → updates `data/leaderboard.json`
5. Commit and redeploy

## Efficiency columns

| field | meaning |
|---|---|
| `cost_usd` | API list / OpenRouter reported cost |
| `latency_s` | Wall time for the single-pass generation |
| `build_ok` | Artifact parsed / PPTX script ran |

Single-pass only. A render→critique loop would cost more and is out of scope for the published board.
