Compliance gates
Every frontend change is read by the compliance script before merge. A failure names the gate, the file and the line.
Running the gate
Pass the files you changed; with no arguments it checks the whole frontend.
python scripts/check_frontend_compliance.py path/to/Changed.module.cssThe gates
Hard failures block the merge outright. The rest fail the check and are reviewed.
| Gate | Rule | Severity |
|---|---|---|
C1 | Pressable controls sit on a height tier (28, 32 or 36px) | Hard failure |
C2 | Sticky headers and footers inherit the container, never chrome | Check |
C3 | No native select on a design-system surface | Check |
C4 | Field containers and section lists use gap, not margins | Check |
C5 | Icon-bearing section headers are flex rows | Hard failure |
C6 | Action buttons size to their content, not 100% | Check |
C7 | Drawer root, body and footer keep the flex column | Check |
C8 | No dashed or dotted borders | Hard failure |
C9 | Textareas share the input contract | Check |
C10 | 10px text only on data-grid column heads | Check |
C12 | Spotlight tour anchors still exist | Check |
C13 | v1-only tokens need the data-ds opt-in | Hard failure |
C14 | Infinite loops never distort geometry | Hard failure |
C15 | No status hue on a pressable control | Check |
C16 | No pill radius on a pressable control | Hard failure |
C17 | No all-caps headings | Hard failure |
C19 | Surfaces take the surface radius tier | Check |
C20 | Dynamic pills in a header are bounded | Hard failure |
C21 | No zero padding on a pressable control | Check |
C24 | Fixed side panels sit under the app header | Check |
Marking an exception
A deliberate exception carries a marker with a reason. The marker never passes on its own: the gate still checks the condition it trades for, such as the 44px boundary on a compact chip.
.filterChip { /* ds-chip: tappable filter, 20px */
height: 20px;
}
.filterChip::after { inset: -12px; }.filterChip { /* ds-chip */
height: 20px;
}ds-chipandds-glyph-badge: compact pressables, verified 44px boundary.ds-reset: a control whose zero padding is the point.ds-full-bleed: a control that genuinely is a full-width container.ds-exempt: anything else, always with a reason a reviewer can check.