docs: draw three panel-redesign directions on the key screens
Stage 1 of the panel redesign: Overview, an outbound domain and sign-in,
each drawn on a ready-made library instead of hand-tuned CSS — A Pico
("Blank"), B Tabler ("Console"), C Bulma ("Counter") — plus a cover sheet
comparing size, JavaScript, CSP fit and the amount of own CSS.
All three share the new information architecture: navigation grouped by
mail direction (Overview, Outbound, Inbound, Server) with a symmetric Log
and Queue on both sides, one block per DNS record, applications as a
table, rarely changed domain settings behind one click.
Mockups only; internal/web is untouched. Pico and Tabler embed data: SVGs
and would need img-src 'self' data: in the CSP; Bulma does not.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-bs-theme="light">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>example.org · Outbound domains · SelfPost</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/core@1.5.1/dist/css/tabler.min.css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@3/dist/tabler-icons.min.css">
|
||||
<link rel="stylesheet" href="../shared/brand.css">
|
||||
<link rel="stylesheet" href="theme.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="page">
|
||||
|
||||
<aside class="navbar navbar-vertical navbar-expand-lg" data-bs-theme="dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="status.html"><img src="../../selfpost-stamp-compact.svg" alt="SelfPost"></a>
|
||||
<div class="navbar-collapse collapse show">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item"><a class="nav-link" href="status.html"><span class="nav-link-icon"><i class="ti ti-activity-heartbeat"></i></span><span class="nav-link-title">Overview</span></a></li>
|
||||
|
||||
<li class="sp-nav-label">Outbound</li>
|
||||
<li class="nav-item active"><a class="nav-link" href="domain.html"><span class="nav-link-icon"><i class="ti ti-world-upload"></i></span><span class="nav-link-title">Domains</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-list-details"></i></span><span class="nav-link-title">Log</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-stack-2"></i></span><span class="nav-link-title">Queue</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-report-analytics"></i></span><span class="nav-link-title">DMARC reports</span></a></li>
|
||||
|
||||
<li class="sp-nav-label">Inbound</li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-world-download"></i></span><span class="nav-link-title">Domains</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-list-details"></i></span><span class="nav-link-title">Log</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-stack-2"></i></span><span class="nav-link-title">Queue</span></a></li>
|
||||
|
||||
<li class="sp-nav-label">Server</li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-file-text"></i></span><span class="nav-link-title">System log</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-archive"></i></span><span class="nav-link-title">Backup</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-users"></i></span><span class="nav-link-title">Users</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-settings"></i></span><span class="nav-link-title">Settings</span></a></li>
|
||||
</ul>
|
||||
<ul class="navbar-nav sp-nav-foot">
|
||||
<li class="sp-nav-user">Signed in as admin</li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-user-circle"></i></span><span class="nav-link-title">Account</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-help"></i></span><span class="nav-link-title">Help</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="login.html"><span class="nav-link-icon"><i class="ti ti-logout"></i></span><span class="nav-link-title">Sign out</span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<div class="page-wrapper">
|
||||
<div class="page-header">
|
||||
<div class="container-xl">
|
||||
<div class="row g-2 align-items-center">
|
||||
<div class="col">
|
||||
<div class="page-pretitle"><a href="#" class="text-reset">Outbound domains</a> /</div>
|
||||
<h2 class="page-title">example.org <span class="badge bg-red-lt ms-2">DNS: 1 mismatch</span></h2>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="btn-list">
|
||||
<form method="post" action="#"><button type="submit" class="btn"><i class="ti ti-refresh me-1"></i>Re-check DNS</button></form>
|
||||
<a href="#" class="btn btn-primary"><i class="ti ti-plus me-1"></i>Add application</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<div class="container-xl">
|
||||
<div class="row row-cards">
|
||||
|
||||
<div class="col-lg-8">
|
||||
<div class="card">
|
||||
<div class="card-header"><h3 class="card-title">DNS records</h3><div class="card-actions text-secondary small">Checked 3 min ago</div></div>
|
||||
|
||||
<div class="card-body sp-record">
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<h4 class="m-0 me-2">DKIM</h4><span class="badge bg-green-lt">published</span>
|
||||
<span class="ms-auto text-secondary small">Not a secret · selector <code>sp2026</code></span>
|
||||
</div>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-9">
|
||||
<label class="form-label">Host / name</label>
|
||||
<div class="input-group"><input class="form-control" readonly value="sp2026._domainkey.example.org"><button class="btn" type="button"><i class="ti ti-copy me-1"></i>Copy</button></div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Type</label>
|
||||
<input class="form-control" readonly value="TXT">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Value to publish</label>
|
||||
<div class="input-group"><textarea class="form-control" rows="3" readonly>v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx3kqV0mJd8e2f1Yb7Qw5uT9sLr4nHc6pZaXo1vKe0yWm2gBt8RjN5dCq3hUf7lPs9aEi4oMz6xTb1kGv0nYw…IDAQAB</textarea><button class="btn" type="button"><i class="ti ti-copy me-1"></i>Copy</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body sp-record">
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<h4 class="m-0 me-2">SPF</h4><span class="badge bg-red-lt">mismatch</span>
|
||||
<span class="ms-auto text-secondary small">Merge into the existing record — never publish a second one</span>
|
||||
</div>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-9">
|
||||
<label class="form-label">Host / name</label>
|
||||
<div class="input-group"><input class="form-control" readonly value="example.org"><button class="btn" type="button"><i class="ti ti-copy me-1"></i>Copy</button></div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Type</label>
|
||||
<input class="form-control" readonly value="TXT">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Value to publish</label>
|
||||
<div class="input-group"><input class="form-control" readonly value="v=spf1 ip4:203.0.113.25 ~all"><button class="btn" type="button"><i class="ti ti-copy me-1"></i>Copy</button></div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">In DNS now</label>
|
||||
<input class="form-control" readonly value="v=spf1 include:_spf.google.com ~all">
|
||||
<div class="text-danger small mt-2">The published record does not authorize 203.0.113.25. Add <code>ip4:203.0.113.25</code> before <code>~all</code>.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body sp-record">
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<h4 class="m-0 me-2">DMARC</h4><span class="badge bg-green-lt">published</span>
|
||||
<span class="ms-auto text-secondary small">Report address from <a href="#">Settings</a></span>
|
||||
</div>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-9">
|
||||
<label class="form-label">Host / name</label>
|
||||
<div class="input-group"><input class="form-control" readonly value="_dmarc.example.org"><button class="btn" type="button"><i class="ti ti-copy me-1"></i>Copy</button></div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Type</label>
|
||||
<input class="form-control" readonly value="TXT">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Value to publish</label>
|
||||
<div class="input-group"><input class="form-control" readonly value="v=DMARC1; p=none; rua=mailto:dmarc@mail.example.org"><button class="btn" type="button"><i class="ti ti-copy me-1"></i>Copy</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4">
|
||||
<div class="card mb-3">
|
||||
<div class="card-header"><h3 class="card-title">Connection</h3></div>
|
||||
<div class="card-body">
|
||||
<div class="datagrid">
|
||||
<div class="datagrid-item"><div class="datagrid-title">Server</div><div class="datagrid-content font-monospace">mail.example.org</div></div>
|
||||
<div class="datagrid-item"><div class="datagrid-title">Ports</div><div class="datagrid-content font-monospace">465 SSL/TLS<br>587 STARTTLS</div></div>
|
||||
</div>
|
||||
<p class="text-secondary small mt-3 mb-0">The same for every domain. Authenticate with an application login.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-3">
|
||||
<div class="card-header"><h3 class="card-title">Sent, 30 days</h3></div>
|
||||
<div class="card-body">
|
||||
<div class="datagrid">
|
||||
<div class="datagrid-item"><div class="datagrid-title">Messages</div><div class="datagrid-content h2 m-0">1 284</div></div>
|
||||
<div class="datagrid-item"><div class="datagrid-title">Peak</div><div class="datagrid-content h2 m-0">96 <span class="text-secondary fs-5">/h</span></div></div>
|
||||
<div class="datagrid-item"><div class="datagrid-title">Average</div><div class="datagrid-content h2 m-0">1.8 <span class="text-secondary fs-5">/h</span></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header"><h3 class="card-title">Domain settings</h3></div>
|
||||
<div class="list-group list-group-flush">
|
||||
<a href="#" class="list-group-item list-group-item-action d-flex align-items-center"><div><div>DMARC reports</div><div class="text-secondary small">Same as Settings</div></div><i class="ti ti-chevron-right ms-auto text-secondary"></i></a>
|
||||
<a href="#" class="list-group-item list-group-item-action d-flex align-items-center"><div><div>Rate limit <span class="badge bg-green-lt ms-1">active</span></div><div class="text-secondary small">Auto ×3 — 288 messages / hour</div></div><i class="ti ti-chevron-right ms-auto text-secondary"></i></a>
|
||||
<a href="#" class="list-group-item list-group-item-action d-flex align-items-center"><div><div>Export</div><div class="text-secondary small">Key and applications as one file</div></div><i class="ti ti-chevron-right ms-auto text-secondary"></i></a>
|
||||
<a href="#" class="list-group-item list-group-item-action d-flex align-items-center text-danger"><div>Delete domain</div><i class="ti ti-chevron-right ms-auto"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header"><h3 class="card-title">Applications</h3><div class="card-actions text-secondary small">SASL logins that may send as this domain</div></div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-vcenter card-table">
|
||||
<thead><tr><th>Login</th><th>May send as</th><th>30 days</th><th>Limits</th><th class="w-1"></th></tr></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="font-monospace fw-semibold">prod-server</td><td>*@example.org</td><td class="text-secondary">1 102 msg · peak 96/h</td>
|
||||
<td><span class="badge bg-green-lt">200 / h</span></td>
|
||||
<td><div class="btn-list flex-nowrap"><a href="#" class="btn btn-sm">Edit</a><a href="#" class="btn btn-sm">New password</a><a href="#" class="btn btn-sm btn-ghost-danger">Delete</a></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-monospace fw-semibold">alerts</td><td>alerts@example.org, noc@example.org</td><td class="text-secondary">182 msg · peak 14/h</td>
|
||||
<td><span class="badge bg-secondary-lt">domain</span> <span class="badge bg-green-lt">2 IPs</span></td>
|
||||
<td><div class="btn-list flex-nowrap"><a href="#" class="btn btn-sm">Edit</a><a href="#" class="btn btn-sm">New password</a><a href="#" class="btn btn-sm btn-ghost-danger">Delete</a></div></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer footer-transparent">
|
||||
<div class="container-xl sp-foot">SelfPost 1.8.0 · © 2026 Mix · <a href="#">License (AGPL-3.0)</a> · <a href="#">Source</a> · No warranty</div>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-bs-theme="light">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Sign in · SelfPost</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/core@1.5.1/dist/css/tabler.min.css">
|
||||
<link rel="stylesheet" href="../shared/brand.css">
|
||||
<link rel="stylesheet" href="theme.css">
|
||||
</head>
|
||||
<body class="d-flex flex-column">
|
||||
<div class="page page-center">
|
||||
<div class="container container-tight py-4">
|
||||
<div class="text-center mb-4"><img class="sp-signin-mark" src="../../selfpost-stamp.svg" alt="SelfPost"></div>
|
||||
<div class="card card-md">
|
||||
<div class="card-body">
|
||||
<h2 class="h2 text-center mb-4">Sign in</h2>
|
||||
<form method="post" action="status.html">
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="username">Username</label>
|
||||
<input class="form-control" id="username" name="username" autocomplete="username" required>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label" for="password">Password</label>
|
||||
<input class="form-control" id="password" name="password" type="password" autocomplete="current-password" required>
|
||||
</div>
|
||||
<div class="form-footer"><button type="submit" class="btn btn-primary w-100">Sign in</button></div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center sp-tagline mt-4">YOUR SMTP. YOUR RULES.</div>
|
||||
<div class="text-center sp-foot mt-3">© 2026 Mix · <a href="#">License (AGPL-3.0)</a> · <a href="#">Source</a> · No warranty</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,168 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-bs-theme="light">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Overview · SelfPost</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/core@1.5.1/dist/css/tabler.min.css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@3/dist/tabler-icons.min.css">
|
||||
<link rel="stylesheet" href="../shared/brand.css">
|
||||
<link rel="stylesheet" href="theme.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="page">
|
||||
|
||||
<aside class="navbar navbar-vertical navbar-expand-lg" data-bs-theme="dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="status.html"><img src="../../selfpost-stamp-compact.svg" alt="SelfPost"></a>
|
||||
<div class="navbar-collapse collapse show">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item active"><a class="nav-link" href="status.html"><span class="nav-link-icon"><i class="ti ti-activity-heartbeat"></i></span><span class="nav-link-title">Overview</span></a></li>
|
||||
|
||||
<li class="sp-nav-label">Outbound</li>
|
||||
<li class="nav-item"><a class="nav-link" href="domain.html"><span class="nav-link-icon"><i class="ti ti-world-upload"></i></span><span class="nav-link-title">Domains</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-list-details"></i></span><span class="nav-link-title">Log</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-stack-2"></i></span><span class="nav-link-title">Queue</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-report-analytics"></i></span><span class="nav-link-title">DMARC reports</span></a></li>
|
||||
|
||||
<li class="sp-nav-label">Inbound</li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-world-download"></i></span><span class="nav-link-title">Domains</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-list-details"></i></span><span class="nav-link-title">Log</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-stack-2"></i></span><span class="nav-link-title">Queue</span></a></li>
|
||||
|
||||
<li class="sp-nav-label">Server</li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-file-text"></i></span><span class="nav-link-title">System log</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-archive"></i></span><span class="nav-link-title">Backup</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-users"></i></span><span class="nav-link-title">Users</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-settings"></i></span><span class="nav-link-title">Settings</span></a></li>
|
||||
</ul>
|
||||
<ul class="navbar-nav sp-nav-foot">
|
||||
<li class="sp-nav-user">Signed in as admin</li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-user-circle"></i></span><span class="nav-link-title">Account</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#"><span class="nav-link-icon"><i class="ti ti-help"></i></span><span class="nav-link-title">Help</span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="login.html"><span class="nav-link-icon"><i class="ti ti-logout"></i></span><span class="nav-link-title">Sign out</span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<div class="page-wrapper">
|
||||
<div class="page-header">
|
||||
<div class="container-xl">
|
||||
<div class="row g-2 align-items-center">
|
||||
<div class="col">
|
||||
<div class="page-pretitle">mail.example.org</div>
|
||||
<h2 class="page-title">Overview</h2>
|
||||
</div>
|
||||
<div class="col-auto text-secondary small">Updated 14:02:31 UTC · refreshes every 10 s</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<div class="container-xl">
|
||||
|
||||
<div class="alert alert-warning bg-white" role="alert">
|
||||
<div class="d-flex">
|
||||
<div><i class="ti ti-alert-triangle alert-icon"></i></div>
|
||||
<div>
|
||||
<h4 class="alert-title">Mail is flowing. One thing needs attention.</h4>
|
||||
<div class="text-secondary">The TLS certificate expires in 12 days and has not renewed yet.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row row-cards mb-3">
|
||||
<div class="col-sm-6 col-lg-4"><div class="card card-sm sp-tile"><div class="card-body"><i class="ti ti-cpu sp-tile-icon"></i><div><div class="fw-semibold">Machine</div><div class="text-secondary small">CPU 12 % · mem 41 %</div></div><span class="status status-green"><span class="status-dot"></span>OK</span></div></div></div>
|
||||
<div class="col-sm-6 col-lg-4"><div class="card card-sm sp-tile"><div class="card-body"><i class="ti ti-server-cog sp-tile-icon"></i><div><div class="fw-semibold">Processes</div><div class="text-secondary small">5 of 5 running</div></div><span class="status status-green"><span class="status-dot"></span>OK</span></div></div></div>
|
||||
<div class="col-sm-6 col-lg-4"><div class="card card-sm sp-tile"><div class="card-body"><i class="ti ti-stack-2 sp-tile-icon"></i><div><div class="fw-semibold">Queues</div><div class="text-secondary small">Both empty</div></div><span class="status status-green"><span class="status-dot"></span>OK</span></div></div></div>
|
||||
<div class="col-sm-6 col-lg-4"><div class="card card-sm sp-tile"><div class="card-body"><i class="ti ti-certificate sp-tile-icon"></i><div><div class="fw-semibold">TLS certificate</div><div class="text-secondary small">Expires in 12 days</div></div><span class="status status-yellow"><span class="status-dot"></span>Warn</span></div></div></div>
|
||||
<div class="col-sm-6 col-lg-4"><div class="card card-sm sp-tile"><div class="card-body"><i class="ti ti-plug-connected sp-tile-icon"></i><div><div class="fw-semibold">Milter sockets</div><div class="text-secondary small">2 of 2 answering</div></div><span class="status status-green"><span class="status-dot"></span>OK</span></div></div></div>
|
||||
<div class="col-sm-6 col-lg-4"><div class="card card-sm sp-tile"><div class="card-body"><i class="ti ti-arrows-exchange sp-tile-icon"></i><div><div class="fw-semibold">Reverse DNS</div><div class="text-secondary small">Forward = reverse</div></div><span class="status status-green"><span class="status-dot"></span>OK</span></div></div></div>
|
||||
</div>
|
||||
|
||||
<div class="row row-deck row-cards">
|
||||
<div class="col-lg-6">
|
||||
<div class="card">
|
||||
<div class="card-header"><h3 class="card-title">Machine</h3><div class="card-actions"><span class="badge bg-green-lt">ok</span></div></div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-vcenter card-table">
|
||||
<thead><tr><th>Resource</th><th>Usage</th><th>Detail</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>CPU</td><td><progress class="sp-bar" value="12" max="100"></progress>12 %</td><td class="text-secondary">2 cores, load 0.21</td></tr>
|
||||
<tr><td>Memory</td><td><progress class="sp-bar" value="41" max="100"></progress>41 %</td><td class="text-secondary">812 MB of 1.9 GB</td></tr>
|
||||
<tr><td>Network</td><td>↓ 18 kB/s · ↑ 44 kB/s</td><td class="text-secondary">eth0: 2.1 GB in, 6.4 GB out</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-6">
|
||||
<div class="card">
|
||||
<div class="card-header"><h3 class="card-title">Processes</h3><div class="card-actions"><span class="badge bg-green-lt">ok</span></div></div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-vcenter card-table">
|
||||
<thead><tr><th>Program</th><th>State</th><th>Detail</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>postfix</td><td><span class="badge bg-green-lt">running</span></td><td class="text-secondary">pid 41, uptime 18 days</td></tr>
|
||||
<tr><td>opendkim</td><td><span class="badge bg-green-lt">running</span></td><td class="text-secondary">pid 39, uptime 18 days</td></tr>
|
||||
<tr><td>journal-milter</td><td><span class="badge bg-green-lt">running</span></td><td class="text-secondary">pid 40, uptime 18 days</td></tr>
|
||||
<tr><td>panel</td><td><span class="badge bg-green-lt">running</span></td><td class="text-secondary">pid 44, uptime 18 days</td></tr>
|
||||
<tr><td>dmarc-ingest</td><td><span class="badge bg-green-lt">running</span></td><td class="text-secondary">pid 47, uptime 18 days</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4">
|
||||
<div class="card">
|
||||
<div class="card-header"><h3 class="card-title">TLS certificate</h3><div class="card-actions"><span class="badge bg-yellow-lt">warn</span></div></div>
|
||||
<div class="card-body">
|
||||
<div class="datagrid">
|
||||
<div class="datagrid-item"><div class="datagrid-title">Expires</div><div class="datagrid-content font-monospace">2026-10-03 09:14 UTC</div></div>
|
||||
<div class="datagrid-item"><div class="datagrid-title">Names</div><div class="datagrid-content font-monospace">mail.example.org</div></div>
|
||||
</div>
|
||||
<p class="text-secondary mt-3 mb-0">Renewal normally runs 30 days before expiry. Check port 80 and the <a href="#">system log</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4">
|
||||
<div class="card">
|
||||
<div class="card-header"><h3 class="card-title">Milter sockets</h3><div class="card-actions"><span class="badge bg-green-lt">ok</span></div></div>
|
||||
<table class="table table-vcenter card-table">
|
||||
<thead><tr><th>Milter</th><th>State</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>opendkim<div class="text-secondary small font-monospace">inet:127.0.0.1:8891</div></td><td><span class="badge bg-green-lt">ok</span></td></tr>
|
||||
<tr><td>journal-milter<div class="text-secondary small font-monospace">unix:/run/selfpost/journal.sock</div></td><td><span class="badge bg-green-lt">ok</span></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4">
|
||||
<div class="card">
|
||||
<div class="card-header"><h3 class="card-title">Hostname and reverse DNS</h3><div class="card-actions"><span class="badge bg-green-lt">ok</span></div></div>
|
||||
<div class="card-body">
|
||||
<div class="datagrid">
|
||||
<div class="datagrid-item"><div class="datagrid-title">Hostname</div><div class="datagrid-content font-monospace">mail.example.org</div></div>
|
||||
<div class="datagrid-item"><div class="datagrid-title">Lookup</div><div class="datagrid-content font-monospace">→ 203.0.113.25<br>← mail.example.org</div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer"><form method="post" action="#"><button type="submit" class="btn btn-sm"><i class="ti ti-refresh me-1"></i>Re-check DNS</button></form></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer footer-transparent">
|
||||
<div class="container-xl sp-foot">SelfPost 1.8.0 · © 2026 Mix · <a href="#">License (AGPL-3.0)</a> · <a href="#">Source</a> · No warranty</div>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,80 @@
|
||||
/* Direction B — "Console". Tabler (Bootstrap 5 admin kit) carries the shell,
|
||||
cards, tables, badges, input groups and the sign-in page as shipped; this
|
||||
file only re-points Tabler's variables at the brand and adds the two things
|
||||
Tabler has no word for: a sidebar group label and the DNS record block. */
|
||||
|
||||
:root, [data-bs-theme=light] {
|
||||
--tblr-font-sans-serif: var(--sp-sans);
|
||||
--tblr-font-monospace: var(--sp-mono);
|
||||
--tblr-body-bg: var(--sp-paper);
|
||||
--tblr-body-color: var(--sp-ink);
|
||||
--tblr-secondary: var(--sp-muted);
|
||||
--tblr-border-color: var(--sp-rule);
|
||||
--tblr-border-radius: 3px;
|
||||
--tblr-border-radius-lg: 4px;
|
||||
|
||||
--tblr-primary: #7a3b2e;
|
||||
--tblr-primary-rgb: 122, 59, 46;
|
||||
--tblr-link-color: #7a3b2e;
|
||||
--tblr-link-color-rgb: 122, 59, 46;
|
||||
--tblr-link-hover-color: #632f25;
|
||||
--tblr-link-hover-color-rgb: 99, 47, 37;
|
||||
|
||||
--tblr-green: #2c6b43; --tblr-green-rgb: 44, 107, 67;
|
||||
--tblr-yellow: #b5700f; --tblr-yellow-rgb: 181, 112, 15;
|
||||
--tblr-red: #b42318; --tblr-red-rgb: 180, 35, 24;
|
||||
--tblr-success: #2c6b43; --tblr-success-rgb: 44, 107, 67;
|
||||
--tblr-warning: #b5700f; --tblr-warning-rgb: 181, 112, 15;
|
||||
--tblr-danger: #b42318; --tblr-danger-rgb: 180, 35, 24;
|
||||
}
|
||||
body { font-feature-settings: normal; }
|
||||
.btn-primary { --tblr-btn-hover-bg: #632f25; --tblr-btn-active-bg: #632f25; }
|
||||
code, .font-monospace { font-family: var(--sp-mono); }
|
||||
|
||||
/* ---- sidebar: ink, with the stamp on its own paper */
|
||||
.navbar-vertical {
|
||||
--tblr-navbar-bg: var(--sp-ink); background: var(--sp-ink);
|
||||
--tblr-navbar-color: #aab2bd; --tblr-navbar-hover-color: #fff; --tblr-navbar-active-color: #fff;
|
||||
--tblr-navbar-border-color: transparent;
|
||||
}
|
||||
.navbar-vertical .navbar-brand { padding: 1.1rem 0 .9rem; justify-content: flex-start; }
|
||||
.navbar-vertical .navbar-brand img { height: 52px; width: auto; }
|
||||
.navbar-vertical .nav-link { padding-block: .42rem; }
|
||||
.navbar-vertical .nav-link-icon { font-size: 1.15rem; }
|
||||
.navbar-vertical .nav-item.active > .nav-link {
|
||||
background: rgb(255 255 255 / .07); box-shadow: inset 3px 0 0 #c4705e; color: #fff;
|
||||
}
|
||||
.sp-nav-label {
|
||||
font-family: var(--sp-mono); font-size: .66rem; font-weight: 600; letter-spacing: .14em;
|
||||
text-transform: uppercase; color: #6f7a88; padding: 1.1rem 1.5rem .3rem;
|
||||
}
|
||||
.sp-nav-foot { margin-top: auto; padding-bottom: .8rem; border-top: 1px solid rgb(255 255 255 / .08); padding-top: .6rem; }
|
||||
.sp-nav-user { color: #6f7a88; font-size: .8rem; padding: .3rem 1.5rem; }
|
||||
|
||||
/* ---- page */
|
||||
.page-pretitle { font-family: var(--sp-mono); letter-spacing: .1em; }
|
||||
.card-title { font-weight: 600; }
|
||||
.table thead th { font-family: var(--sp-mono); letter-spacing: .08em; }
|
||||
.sp-tile .card-body { display: flex; align-items: center; gap: .8rem; padding: .85rem 1rem; }
|
||||
.sp-tile .sp-tile-icon { font-size: 1.5rem; color: var(--sp-muted); }
|
||||
.sp-tile .fw-semibold { line-height: 1.2; }
|
||||
.sp-tile .status { margin-left: auto; }
|
||||
progress.sp-bar {
|
||||
appearance: none; -webkit-appearance: none; width: 8rem; height: .4rem; border: 0;
|
||||
border-radius: 1rem; overflow: hidden; vertical-align: middle; margin-right: .6rem; background: var(--sp-well);
|
||||
}
|
||||
progress.sp-bar::-webkit-progress-bar { background: var(--sp-well); }
|
||||
progress.sp-bar::-webkit-progress-value { background: var(--tblr-green); }
|
||||
progress.sp-bar::-moz-progress-bar { background: var(--tblr-green); }
|
||||
|
||||
/* ---- the DNS record block: Tabler's read-only input group, plus a status */
|
||||
.sp-record + .sp-record { border-top: 1px solid var(--sp-rule); }
|
||||
.sp-record .form-control[readonly], .sp-record textarea[readonly] {
|
||||
font-family: var(--sp-mono); font-size: .8rem; background: var(--sp-well);
|
||||
}
|
||||
.sp-record textarea { resize: none; }
|
||||
.sp-record .form-label { font-size: .75rem; color: var(--sp-muted); margin-bottom: .25rem; }
|
||||
|
||||
.sp-foot { color: var(--sp-muted); font-size: .8rem; }
|
||||
.sp-signin-mark { width: 15rem; height: auto; }
|
||||
.sp-tagline { font-family: var(--sp-mono); font-size: .72rem; letter-spacing: .16em; color: var(--sp-muted); }
|
||||
Reference in New Issue
Block a user