337c8e8f0e
The side-by-side .split row read badly: main is capped at 48rem, so the applications table had to live in roughly 27rem and its actions column squeezed four controls into it. Put the create form directly above the list instead — the order the domains page already uses for "Add a sending domain" above "Domains" — and delete .split, which nothing else used. The empty-state text follows the same page's wording. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
148 lines
8.5 KiB
CSS
148 lines
8.5 KiB
CSS
/* Panel stylesheet. It lives in a file rather than in a <style> block in the
|
|
layout so the panel's Content-Security-Policy can be a plain
|
|
"default-src 'self'" with no inline-style exemption (phase 14.A). Any rule
|
|
added here must therefore stay here: an inline style="..." attribute in a
|
|
template is blocked by that policy and silently does nothing. */
|
|
|
|
:root { color-scheme: light dark; }
|
|
* { box-sizing: border-box; }
|
|
body {
|
|
font: 15px/1.5 system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
|
|
margin: 0; padding: 2rem 1rem; background: #f6f7f9; color: #1b1f24;
|
|
}
|
|
@media (prefers-color-scheme: dark) {
|
|
body { background: #14171a; color: #e6e8eb; }
|
|
.card { background: #1d2125 !important; border-color: #2b3138 !important; }
|
|
input { background: #14171a !important; color: inherit !important; border-color: #2b3138 !important; }
|
|
}
|
|
main { max-width: 42rem; margin: 0 auto; }
|
|
h1 { font-size: 1.4rem; margin: 0 0 1rem; }
|
|
.card {
|
|
background: #fff; border: 1px solid #e2e5e9; border-radius: 10px;
|
|
padding: 1.5rem; margin: 0 auto;
|
|
}
|
|
.card.narrow { max-width: 24rem; }
|
|
label { display: block; font-weight: 600; margin: 0.9rem 0 0.3rem; }
|
|
input {
|
|
width: 100%; padding: 0.55rem 0.7rem; font-size: 1rem;
|
|
border: 1px solid #cfd4da; border-radius: 6px; background: #fff;
|
|
}
|
|
/* One vocabulary for actions. Anything that performs an action looks like a
|
|
button; an <a> stays a plain link and is only used for navigation. Several
|
|
actions used to render as bold blue text instead — a POST wrapped in
|
|
form.inline, a <details> toggle, the delete links — which read as links and
|
|
left two appearances for the same kind of control. They all get the button
|
|
look now: filled for a card's own action, and the compact outlined variant
|
|
further down where actions cluster (table rows, the nav bar). */
|
|
button, a.danger {
|
|
display: inline-block; margin-top: 1.2rem; padding: 0.6rem 1.1rem;
|
|
font: inherit; font-size: 1rem; font-weight: 600; text-decoration: none;
|
|
color: #fff; background: #2563eb; border: 0; border-radius: 6px; cursor: pointer;
|
|
}
|
|
button:hover { background: #1d4ed8; }
|
|
.error { color: #b42318; margin: 0.6rem 0 0; font-weight: 600; }
|
|
.muted { color: #6b7280; }
|
|
.topbar { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 1.2rem; }
|
|
.topbar .actions { display: flex; gap: 0.9rem; align-items: baseline; }
|
|
/* form.inline only exists so a POST can sit next to other content without a
|
|
form's block layout; its button is styled like any other. */
|
|
form.inline { display: inline; margin: 0; }
|
|
main { max-width: 48rem; }
|
|
.card + .card { margin-top: 1.2rem; }
|
|
.flash { background: #ecfdf3; border: 1px solid #abefc6; color: #067647; padding: 0.7rem 1rem; border-radius: 8px; margin-bottom: 1.2rem; }
|
|
@media (prefers-color-scheme: dark) { .flash { background: #0d2818 !important; border-color: #1a5336 !important; color: #75d99b !important; } }
|
|
table { width: 100%; border-collapse: collapse; }
|
|
th, td { text-align: left; padding: 0.5rem 0.4rem; border-bottom: 1px solid #e2e5e9; }
|
|
@media (prefers-color-scheme: dark) { th, td { border-color: #2b3138 !important; } }
|
|
th { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.03em; color: #6b7280; }
|
|
td.actions { text-align: right; }
|
|
.code { display: block; white-space: pre-wrap; word-break: break-all; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
font-size: 0.85rem; background: #f0f2f4; border: 1px solid #e2e5e9; border-radius: 6px; padding: 0.7rem 0.8rem; margin: 0.3rem 0 0; }
|
|
@media (prefers-color-scheme: dark) { .code { background: #14171a !important; border-color: #2b3138 !important; } }
|
|
h2 { font-size: 1.05rem; margin: 0 0 0.4rem; }
|
|
.back { display: inline-block; margin-bottom: 1rem; }
|
|
select, textarea {
|
|
width: 100%; padding: 0.55rem 0.7rem; font-size: 1rem;
|
|
border: 1px solid #cfd4da; border-radius: 6px; background: #fff; color: inherit;
|
|
font-family: inherit;
|
|
}
|
|
textarea { resize: vertical; }
|
|
@media (prefers-color-scheme: dark) {
|
|
select, textarea { background: #14171a !important; color: inherit !important; border-color: #2b3138 !important; }
|
|
}
|
|
button.danger, a.danger { background: #b42318; }
|
|
button.danger:hover, a.danger:hover { background: #912018; }
|
|
td.actions form.inline, td.actions details { margin: 0.4rem 0 0 0.5rem; }
|
|
/* The disclosure toggle is an action too, so it is drawn as a button (see the
|
|
compact rule below); the marker is dropped because the pressed background
|
|
already shows the open state. */
|
|
td.actions summary { display: inline-block; list-style: none; cursor: pointer; }
|
|
td.actions summary::-webkit-details-marker { display: none; }
|
|
details form { margin-top: 0.6rem; }
|
|
.credential { border-color: #f5c518; background: #fffbeb; }
|
|
@media (prefers-color-scheme: dark) { .credential { background: #2a2408 !important; border-color: #6b5a10 !important; } }
|
|
/* Panel navigation: rendered once from the layout, so it is present on every
|
|
authenticated page without each content template having to include it. */
|
|
.nav {
|
|
display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline;
|
|
gap: 0.4rem 1rem; margin-bottom: 1.2rem; padding-bottom: 0.6rem;
|
|
border-bottom: 1px solid #e2e5e9;
|
|
}
|
|
@media (prefers-color-scheme: dark) { .nav { border-color: #2b3138 !important; } }
|
|
.nav .links, .nav .session { display: flex; flex-wrap: wrap; gap: 0.2rem 0.9rem; align-items: baseline; }
|
|
.nav .links a, .nav .links [aria-current] { padding: 0.2rem 0.5rem; border-radius: 6px; }
|
|
.nav .links [aria-current] {
|
|
font-weight: 600; color: #1b1f24; background: #e6ebf5; box-shadow: inset 0 -2px 0 #2563eb;
|
|
}
|
|
@media (prefers-color-scheme: dark) {
|
|
.nav .links [aria-current] { color: #e6e8eb !important; background: #22303f !important; }
|
|
}
|
|
/* Status badges: one vocabulary (ok/warn/error/unknown) shared by the server
|
|
status page and the per-domain DNS checks, so a colour means the same thing
|
|
everywhere. The class suffix is the check's own status value. */
|
|
.st {
|
|
display: inline-block; padding: 0.05rem 0.45rem; border-radius: 999px;
|
|
font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
|
|
vertical-align: middle; border: 1px solid transparent;
|
|
}
|
|
.st-ok { background: #ecfdf3; color: #067647; border-color: #abefc6; }
|
|
.st-warn { background: #fffaeb; color: #b54708; border-color: #fedf89; }
|
|
.st-error { background: #fef3f2; color: #b42318; border-color: #fecdca; }
|
|
.st-unknown { background: #f0f2f4; color: #6b7280; border-color: #e2e5e9; }
|
|
@media (prefers-color-scheme: dark) {
|
|
.st-ok { background: #0d2818 !important; color: #75d99b !important; border-color: #1a5336 !important; }
|
|
.st-warn { background: #2e2308 !important; color: #f5c86b !important; border-color: #6b5210 !important; }
|
|
.st-error { background: #2d1211 !important; color: #f5a29b !important; border-color: #6b201a !important; }
|
|
.st-unknown { background: #22262b !important; color: #9aa3ad !important; border-color: #2b3138 !important; }
|
|
}
|
|
.code-row { display: flex; align-items: flex-start; gap: 0.5rem; }
|
|
.code-row .code { flex: 1; min-width: 0; }
|
|
/* Compact outlined button: same affordance as the filled one but quiet enough
|
|
that several can sit together without shouting — the Copy buttons beside a
|
|
value, the per-application actions in a table row, Sign out in the nav. */
|
|
button.copy, td.actions button, td.actions summary, td.actions a.danger, .nav button {
|
|
margin: 0; padding: 0.45rem 0.7rem; font-size: 0.8rem; font-weight: 600;
|
|
border-radius: 6px; white-space: nowrap;
|
|
background: #eef1f5; color: #2563eb; border: 1px solid #cfd4da;
|
|
}
|
|
button.copy:hover, td.actions button:hover, td.actions summary:hover,
|
|
td.actions a.danger:hover, .nav button:hover { background: #e2e7ee; }
|
|
button.copy { flex: none; margin-top: 0.3rem; }
|
|
td.actions details[open] > summary { background: #dde3ec; }
|
|
td.actions button.danger, td.actions a.danger {
|
|
color: #b42318; background: #fef3f2; border-color: #fecdca;
|
|
}
|
|
td.actions button.danger:hover, td.actions a.danger:hover { background: #fee4e2; }
|
|
@media (prefers-color-scheme: dark) {
|
|
button.copy, td.actions button, td.actions summary, td.actions a.danger, .nav button {
|
|
background: #22262b !important; border-color: #2b3138 !important;
|
|
}
|
|
button.copy:hover, td.actions button:hover, td.actions summary:hover,
|
|
td.actions a.danger:hover, .nav button:hover { background: #2b3138 !important; }
|
|
td.actions details[open] > summary { background: #313841 !important; }
|
|
td.actions button.danger, td.actions a.danger {
|
|
color: #f5a29b !important; background: #2d1211 !important; border-color: #6b201a !important;
|
|
}
|
|
td.actions button.danger:hover, td.actions a.danger:hover { background: #3d1a18 !important; }
|
|
}
|