docs: turn the accepted panel design into an enforceable contract

panel-redesign.md is rewritten for the accepted direction: three layers
(Bulma as shipped, adapters, own sp- components), the page layouts, what
an implementer must not do, and how that is enforced — guard tests that
land before any template, a design-first CI step, and acceptance by
evidence (test output plus a screenshot of every page beside its mockup,
reviewed by a model that did not write the step).

A components page shows every building block in every state; a screen
may be built from nothing else. panel/check.py lints the mockups against
the contract (class vocabulary, CSS bans on !important, id and page
selectors and stray widths, page structure) and writes
panel/outlines.json, the per-screen component skeleton an implementation
is compared with, so a different design cannot pass as this one.

Own modifier classes now carry the sp- prefix (sp-warn, sp-fail, sp-big,
sp-danger-zone, ...) so the vocabulary is machine-checkable; the lint
also caught a width set outside the layout in the mockup's own CSS.

Agent rule .cursor/rules/panel-design.mdc; roadmap row and section
updated (0/15, still candidate).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
mix
2026-09-21 20:55:18 +03:00
co-authored by Claude Fable 5.1
parent d1f22fbcc8
commit 1bcfca1586
38 changed files with 1402 additions and 256 deletions
@@ -0,0 +1,401 @@
{
"account": [
"head",
{
"columns": [
{
"is-6": [
"box[Panel credentials]:body"
]
},
{
"is-6": [
"box[What happens]:body"
]
}
]
}
],
"backup": [
"head",
{
"columns": [
{
"is-6": [
"box[Full backup]:body"
]
},
{
"is-6": [
"box[Import a domain]:body"
]
}
]
}
],
"dmarc-domain": [
"head+postmark+actions",
{
"columns": [
{
"is-5": [
"box[Sources · 7 days]:table"
]
},
{
"is-7": [
"box[Reports]:table"
]
}
]
}
],
"dmarc-report": [
"head",
{
"columns": [
{
"is-6": [
"box[Report]:body"
]
},
{
"is-6": [
"box[Published policy]:body"
]
}
]
},
"box[Records]:table"
],
"dmarc": [
"head",
"box[Ingest]:body",
"box[Recent reports]:table"
],
"health": [
"head+actions",
{
"columns": [
{
"is-6": [
"box[Machine]:table"
]
},
{
"is-6": [
"box[Processes]:table"
]
}
]
},
{
"columns": [
{
"is-4": [
"box[TLS certificate]:body"
]
},
{
"is-4": [
"box[Milter sockets]:table"
]
},
{
"is-4": [
"box[Hostname and reverse DNS]:body"
]
}
]
}
],
"help": [
"head",
{
"columns": [
{
"is-3": [
"side_menu"
]
},
{
"is-9": [
"box[Overview]:help×3",
"box[Outbound]:help×3"
]
}
]
}
],
"in-domain-delete": [
"head",
{
"columns": [
{
"is-7": [
"box.sp-danger-zone[This cannot be undone]:body"
]
}
]
}
],
"in-domain": [
"head+postmark+actions",
{
"columns": [
{
"is-3": [
"side_menu"
]
},
{
"is-9": [
"box[MX record]:record",
{
"columns": [
{
"is-6": [
"box[Upstream]:body"
]
},
{
"is-6": [
"box[Valid recipients]:body"
]
}
]
}
]
}
]
}
],
"in-domains": [
"head",
"box[Add a domain]:body",
"box[Domains]:table"
],
"in-log": [
"head",
"box[Messages]:table"
],
"in-queue": [
"head",
"box[Waiting]:empty",
"box[How retries work]:body"
],
"out-app-created": [
"head",
{
"columns": [
{
"is-7": [
"box.sp-credential[Shown once]:record"
]
},
{
"is-5": [
"box[Connect with]:body"
]
}
]
}
],
"out-app": [
"head+actions",
{
"form": [
{
"columns": [
{
"is-4": [
"box[Sender]:body"
]
},
{
"is-4": [
"box[Client IP allow-list]:body"
]
},
{
"is-4": [
"box[Rate limit]:body"
]
}
]
},
"submit_row"
]
}
],
"out-domain-delete": [
"head",
{
"columns": [
{
"is-7": [
"box.sp-danger-zone[This cannot be undone]:body"
]
},
{
"is-5": [
"box[Moving it instead?]:body"
]
}
]
}
],
"out-domain-settings": [
"head",
{
"columns": [
{
"is-6": [
"box[DMARC report address]:body",
"box[Export domain]:body"
]
},
{
"is-6": [
"box[Rate limit]:body",
"box.sp-danger-zone[Delete domain]:body"
]
}
]
}
],
"out-domain": [
"head+postmark+actions",
{
"columns": [
{
"is-3": [
"side_menu"
]
},
{
"is-9": [
"box[DNS records]:record×3",
"box[Applications]:table",
"box[Connection]:body"
]
}
]
}
],
"out-domains": [
"head",
"box[Add a domain]:body",
"box[Domains]:table"
],
"out-log": [
"head",
"box[Messages]:table"
],
"out-message": [
"head",
{
"columns": [
{
"is-7": [
"box[Message]:body"
]
},
{
"is-5": [
"box[History]:body"
]
}
]
},
"box[Delivery log]:log"
],
"out-queue": [
"head",
"box[Waiting]:table",
"box[How retries work]:body"
],
"overview": [
"head+postmark",
"box[Server health]:health",
{
"columns": [
{
"is-7": [
"box[Outbound domains]:table"
]
},
{
"is-5": [
"box[Inbound domains]:table"
]
}
]
}
],
"settings": [
"head",
{
"form": [
{
"columns": [
{
"is-7": [
"box[DMARC aggregate reports]:record×2"
]
},
{
"is-5": [
"box[Log retention]:body",
"box[Sending rate limits]:body"
]
}
]
},
"submit_row"
]
}
],
"system-log": [
"head",
"box[Recent lines]:log"
],
"user-delete": [
"head",
{
"columns": [
{
"is-7": [
"box.sp-danger-zone[This cannot be undone]:body"
]
}
]
}
],
"user": [
"head+actions",
{
"form": [
{
"columns": [
{
"is-6": [
"box[Sign-in]:body"
]
},
{
"is-6": [
"box[Assigned domains]:body"
]
}
]
},
"submit_row"
]
}
],
"users": [
"head+actions",
"box[Panel users]:table"
]
}