docs: add DMARC report mockups and fold add-domain into lists
test / test (push) Waiting to run

Domains and Inbound keep the add field in the list card. The DMARC candidate hub drills into a domain roll-up and a parsed aggregate report, including a third-party fail. The running panel is unchanged.

Co-Authored-By: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-16 21:44:20 +03:00
parent f47cf39802
commit c6a75ce775
14 changed files with 361 additions and 50 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ Do not copy `internal/web/view/templates` into mockups. Do not mark `<main>` as
Compose screens from `stack`, `pair`, `measure`, `fill`, `field-row`, `actions-row`: Compose screens from `stack`, `pair`, `measure`, `fill`, `field-row`, `actions-row`:
- Two peer jobs → `pair` (one child shrinks to `measure`). - Two peer jobs → `pair` (one child shrinks to `measure`).
- Tables/logs/DNS → `fill` (nowrap + overflow-x on the card). - Tables/logs/DNS → `fill` (nowrap + overflow-x on the card). Add-to-list is a `measure` row inside that card, not a second card above it.
- Confirm/login/user form → `measure`. - Confirm/login/user form → `measure`.
- Host ‖ Type and two equal inputs → `field-row` (shared grid row, not two `.code` paddings). - Host ‖ Type and two equal inputs → `field-row` (shared grid row, not two `.code` paddings).
- Save + Delete → `actions-row` inside the card; never submit inside `<form>` and danger after `</form>`. - Save + Delete → `actions-row` inside the card; never submit inside `<form>` and danger after `</form>`.
+5
View File
@@ -29,6 +29,11 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version
Regions are `stack` / `pair` / `measure` / `fill`; Host ‖ Type is Regions are `stack` / `pair` / `measure` / `fill`; Host ‖ Type is
`field-row`; Save + Delete is `actions-row`. Shared chrome is `shell.js`. `field-row`; Save + Delete is `actions-row`. Shared chrome is `shell.js`.
- docs: panel UI mockups — add-domain sits in the list card (Domains and
Inbound); DMARC candidate screens drill into a domain roll-up and a
parsed aggregate report (aligned vs third-party fail), not a hub-only
summary.
## [1.3.0] - 2026-08-14 ## [1.3.0] - 2026-08-14
Security and quality after 1.2.5: domain-admin send-log authorization, Security and quality after 1.2.5: domain-admin send-log authorization,
+3
View File
@@ -28,6 +28,9 @@
"inbound-backup": "inbound-backup.html", "inbound-backup": "inbound-backup.html",
"inbound-delete": "inbound-delete.html", "inbound-delete": "inbound-delete.html",
dmarc: "dmarc.html", dmarc: "dmarc.html",
"dmarc-domain": "dmarc-domain.html",
"dmarc-report": "dmarc-report.html",
"dmarc-report-fail": "dmarc-report-fail.html",
help: "help.html" help: "help.html"
}; };
var h = location.hash.replace(/^#/, ""); var h = location.hash.replace(/^#/, "");
+88
View File
@@ -0,0 +1,88 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>example.com — DMARC — SelfPost mockups</title>
<link rel="icon" href="../selfpost-icon-16.svg" type="image/svg+xml">
<link rel="stylesheet" href="mock.css">
<link rel="stylesheet" href="system.css">
</head>
<body class="page-dmarc-domain" data-page="dmarc-domain" data-nav="dmarc" data-title="example.com DMARC">
<main class="stack">
<div>
<h1>example.com <span class="tag future">candidate</span></h1>
<a class="back g-only" href="dmarc.html">&larr; All DMARC reports</a>
<a class="back" href="domain.html">&larr; Back to example.com</a>
</div>
<div class="pair">
<div class="card">
<h2>Last 7 days <span class="st st-ok">pass</span></h2>
<p>98% aligned. Tightening <code>p=</code> looks reasonable.</p>
<p class="muted"><a href="domain.html">Domain DNS and rua=</a></p>
</div>
<div class="card">
<h2>Third-party senders</h2>
<p>google.com / 66.102.0.0/20 failed SPF and DKIM 6 times. Everyone else is this relay.</p>
</div>
</div>
<div class="fill">
<div class="card">
<h2>Reports</h2>
<table class="desk-only">
<thead><tr><th>Received</th><th>Reporter</th><th>Window</th><th>Pass</th><th>Fail</th><th></th></tr></thead>
<tbody>
<tr>
<td class="time muted">2026-08-15 06:12</td>
<td class="muted">google.com</td>
<td>14 Aug</td>
<td>412</td>
<td>6</td>
<td class="actions"><a href="dmarc-report.html">View</a></td>
</tr>
<tr>
<td class="time muted">2026-08-14 06:08</td>
<td class="muted">google.com</td>
<td>13 Aug</td>
<td>390</td>
<td>2</td>
<td class="actions"><a href="dmarc-report.html">View</a></td>
</tr>
</tbody>
</table>
<ul class="phone-list phone-only">
<li>
<a href="dmarc-report.html">
<span class="st st-ok">412 pass</span><span class="when">14 Aug</span>
<span class="meta">google.com · 6 fail</span>
</a>
</li>
<li>
<a href="dmarc-report.html">
<span class="st st-ok">390 pass</span><span class="when">13 Aug</span>
<span class="meta">google.com · 2 fail</span>
</a>
</li>
</ul>
</div>
</div>
<div class="fill">
<div class="card">
<h2>Sources · last 7 days</h2>
<table class="desk-only">
<thead><tr><th>Source</th><th>Pass</th><th>Fail</th><th>Disposition</th></tr></thead>
<tbody>
<tr><td class="muted">203.0.113.10 (this relay)</td><td>802</td><td>0</td><td><span class="st st-ok">none</span></td></tr>
<tr><td class="muted">google.com / 66.102.0.0/20</td><td>0</td><td>8</td><td><span class="st st-warn">none</span></td></tr>
</tbody>
</table>
<ul class="phone-list phone-only">
<li><a href="dmarc-report.html"><span>this relay</span><span class="st st-ok">802 pass</span></a></li>
<li><a href="dmarc-report.html"><span>google.com / 66.102.0.0/20</span><span class="st st-warn">8 fail</span></a></li>
</ul>
</div>
</div>
</main>
<script src="shell.js"></script>
</body>
</html>
@@ -0,0 +1,88 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>google.com report — alerts.example.com — SelfPost mockups</title>
<link rel="icon" href="../selfpost-icon-16.svg" type="image/svg+xml">
<link rel="stylesheet" href="mock.css">
<link rel="stylesheet" href="system.css">
</head>
<body class="page-dmarc-report-fail" data-page="dmarc-report-fail" data-nav="dmarc" data-title="DMARC report">
<main class="stack">
<div>
<h1 class="subject">google.com · 14 Aug</h1>
<p class="route">
<span class="addr">alerts.example.com</span>
<span class="st st-ok">88 pass</span>
<span class="st st-error">19 fail</span>
</p>
<a class="back" href="dmarc.html">&larr; All DMARC reports</a>
</div>
<div class="pair">
<div class="card">
<h2>Report</h2>
<div class="facts">
<div class="fact"><span class="fact-label">Reporter</span><span class="fact-value">google.com</span></div>
<div class="fact"><span class="fact-label">Report id</span><span class="fact-value mono">3178944098765432109</span></div>
<div class="fact"><span class="fact-label">Window</span><span class="fact-value">2026-08-14 00:00 2026-08-15 00:00 UTC</span></div>
<div class="fact"><span class="fact-label">Received</span><span class="fact-value">2026-08-15 04:40 UTC</span></div>
<div class="fact"><span class="fact-label">Contact</span><span class="fact-value">noreply-dmarc-support@google.com</span></div>
</div>
</div>
<div class="card attn">
<h2>Published policy</h2>
<div class="facts">
<div class="fact"><span class="fact-label">Domain</span><span class="fact-value">alerts.example.com</span></div>
<div class="fact"><span class="fact-label">p / sp / pct</span><span class="fact-value mono">none / none / 100</span></div>
<div class="fact"><span class="fact-label">adkim / aspf</span><span class="fact-value mono">r / r</span></div>
<div class="fact"><span class="fact-label">rua</span><span class="fact-value">dmarc@mail.example.org</span></div>
</div>
<p class="muted">A third-party source is not in SPF or DKIM. Do not tighten <code>p=</code> until that sender is gone or aligned.</p>
</div>
</div>
<div class="fill">
<div class="card">
<h2>Records</h2>
<table class="desk-only">
<thead><tr><th>Source</th><th>Count</th><th>Disposition</th><th>SPF</th><th>DKIM</th><th>Header from</th></tr></thead>
<tbody>
<tr>
<td class="muted">203.0.113.10 (this relay)</td>
<td>88</td>
<td><span class="st st-ok">none</span></td>
<td><span class="st st-ok">pass</span></td>
<td><span class="st st-ok">pass</span></td>
<td>alerts.example.com</td>
</tr>
<tr>
<td class="muted">198.51.100.80 (unknown)</td>
<td>19</td>
<td><span class="st st-error">none</span></td>
<td><span class="st st-error">fail</span></td>
<td><span class="st st-error">fail</span></td>
<td>alerts.example.com</td>
</tr>
</tbody>
</table>
<ul class="phone-list phone-only">
<li>
<div class="item">
<span>this relay · 88</span><span class="st st-ok">pass</span>
<span class="meta">203.0.113.10 · SPF pass · DKIM pass</span>
</div>
</li>
<li>
<div class="item">
<span>unknown · 19</span><span class="st st-error">fail</span>
<span class="meta">198.51.100.80 · SPF fail · DKIM fail</span>
</div>
</li>
</ul>
<p class="muted">Parsed from the aggregate XML. Forensic (<code>ruf=</code>) samples are not stored.</p>
</div>
</div>
</main>
<script src="shell.js"></script>
</body>
</html>
+88
View File
@@ -0,0 +1,88 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>google.com report — example.com — SelfPost mockups</title>
<link rel="icon" href="../selfpost-icon-16.svg" type="image/svg+xml">
<link rel="stylesheet" href="mock.css">
<link rel="stylesheet" href="system.css">
</head>
<body class="page-dmarc-report" data-page="dmarc-report" data-nav="dmarc" data-title="DMARC report">
<main class="stack">
<div>
<h1 class="subject">google.com · 14 Aug</h1>
<p class="route">
<span class="addr">example.com</span>
<span class="st st-ok">412 pass</span>
<span class="st st-warn">6 fail</span>
</p>
<a class="back" href="dmarc-domain.html">&larr; Back to example.com</a>
</div>
<div class="pair">
<div class="card">
<h2>Report</h2>
<div class="facts">
<div class="fact"><span class="fact-label">Reporter</span><span class="fact-value">google.com</span></div>
<div class="fact"><span class="fact-label">Report id</span><span class="fact-value mono">3178944012345678901</span></div>
<div class="fact"><span class="fact-label">Window</span><span class="fact-value">2026-08-14 00:00 2026-08-15 00:00 UTC</span></div>
<div class="fact"><span class="fact-label">Received</span><span class="fact-value">2026-08-15 06:12 UTC</span></div>
<div class="fact"><span class="fact-label">Contact</span><span class="fact-value">noreply-dmarc-support@google.com</span></div>
</div>
</div>
<div class="card">
<h2>Published policy</h2>
<div class="facts">
<div class="fact"><span class="fact-label">Domain</span><span class="fact-value">example.com</span></div>
<div class="fact"><span class="fact-label">p / sp / pct</span><span class="fact-value mono">none / none / 100</span></div>
<div class="fact"><span class="fact-label">adkim / aspf</span><span class="fact-value mono">r / r</span></div>
<div class="fact"><span class="fact-label">rua</span><span class="fact-value">dmarc@mail.example.org</span></div>
</div>
<p class="muted"><code>p=none</code> does not affect delivery. Failures here are forwarding through Google, not this relay.</p>
</div>
</div>
<div class="fill">
<div class="card">
<h2>Records</h2>
<table class="desk-only">
<thead><tr><th>Source</th><th>Count</th><th>Disposition</th><th>SPF</th><th>DKIM</th><th>Header from</th></tr></thead>
<tbody>
<tr>
<td class="muted">203.0.113.10 (this relay)</td>
<td>412</td>
<td><span class="st st-ok">none</span></td>
<td><span class="st st-ok">pass</span></td>
<td><span class="st st-ok">pass</span></td>
<td>example.com</td>
</tr>
<tr>
<td class="muted">66.102.1.44 (google.com)</td>
<td>6</td>
<td><span class="st st-warn">none</span></td>
<td><span class="st st-error">fail</span></td>
<td><span class="st st-error">fail</span></td>
<td>example.com</td>
</tr>
</tbody>
</table>
<ul class="phone-list phone-only">
<li>
<div class="item">
<span>this relay · 412</span><span class="st st-ok">pass</span>
<span class="meta">203.0.113.10 · SPF pass · DKIM pass</span>
</div>
</li>
<li>
<div class="item">
<span>google.com · 6</span><span class="st st-error">fail</span>
<span class="meta">66.102.1.44 · SPF fail · DKIM fail</span>
</div>
</li>
</ul>
<p class="muted">Parsed from the aggregate XML. Forensic (<code>ruf=</code>) samples are not stored.</p>
</div>
</div>
</main>
<script src="shell.js"></script>
</body>
</html>
+59 -22
View File
@@ -13,39 +13,76 @@
<div class="page-head"> <div class="page-head">
<h1>DMARC reports <span class="tag future">candidate</span></h1> <h1>DMARC reports <span class="tag future">candidate</span></h1>
</div> </div>
<p class="muted">Aggregate reports SelfPost accepted for <code>rua=</code>. Forensic (<code>ruf=</code>) is out of scope.</p> <p class="muted">Aggregate reports SelfPost accepted for <code>rua=</code>. Forensic (<code>ruf=</code>) is out of scope. Open a report for the parsed XML — not a dashboard.</p>
<div class="pair"> <div class="pair">
<article class="card"> <div class="card">
<h2>Ingest <span class="st st-ok">ok</span></h2> <h2>Ingest <span class="st st-ok">ok</span></h2>
<p>Last report 6 hours ago. 14 kept, 0 parse failures this week.</p> <p>Last report 6 hours ago. Port 25 accepts only the configured report address.</p>
</article> </div>
<article class="card"> <div class="card">
<h2>example.com <span class="st st-ok">pass</span></h2> <h2>This week</h2>
<p>98% aligned last 7 days. Tightening <code>p=</code> looks reasonable.</p> <p>14 kept, 0 parse failures. Older summaries are pruned.</p>
</article> </div>
</div>
<div class="fill">
<article class="card attn">
<h2>alerts.example.com <span class="st st-warn">fail</span></h2>
<p>A third-party sender is not in SPF/DKIM. See sources.</p>
</article>
</div> </div>
<div class="fill"> <div class="fill">
<div class="card"> <div class="card">
<h2>Sources · last 7 days</h2> <h2>Recent reports</h2>
<table class="desk-only"> <table class="desk-only">
<thead><tr><th>Domain</th><th>Source</th><th>Pass</th><th>Fail</th><th>Disposition</th></tr></thead> <thead><tr><th>Received</th><th>Domain</th><th>Reporter</th><th>Window</th><th>Pass</th><th>Fail</th><th></th></tr></thead>
<tbody> <tbody>
<tr><td>example.com</td><td class="muted">203.0.113.10 (this relay)</td><td>412</td><td>2</td><td><span class="st st-ok">none</span></td></tr> <tr>
<tr><td>example.com</td><td class="muted">google.com / 66.102.0.0/20</td><td>0</td><td>6</td><td><span class="st st-warn">none</span></td></tr> <td class="time muted">2026-08-15 06:12</td>
<tr><td>alerts.example.com</td><td class="muted">203.0.113.10 (this relay)</td><td>88</td><td>0</td><td><span class="st st-ok">none</span></td></tr> <td><a href="dmarc-domain.html">example.com</a></td>
<tr><td>alerts.example.com</td><td class="muted">unknown / 198.51.100.80</td><td>0</td><td>19</td><td><span class="st st-error">none</span></td></tr> <td class="muted">google.com</td>
<td>14 Aug</td>
<td>412</td>
<td>6</td>
<td class="actions"><a href="dmarc-report.html">View</a></td>
</tr>
<tr>
<td class="time muted">2026-08-15 04:40</td>
<td>alerts.example.com</td>
<td class="muted">google.com</td>
<td>14 Aug</td>
<td>88</td>
<td>19</td>
<td class="actions"><a href="dmarc-report-fail.html">View</a></td>
</tr>
<tr>
<td class="time muted">2026-08-14 06:08</td>
<td><a href="dmarc-domain.html">example.com</a></td>
<td class="muted">google.com</td>
<td>13 Aug</td>
<td>390</td>
<td>2</td>
<td class="actions"><a href="dmarc-report.html">View</a></td>
</tr>
</tbody> </tbody>
</table> </table>
<ul class="phone-list phone-only"> <ul class="phone-list phone-only">
<li><a href="domain.html"><span>example.com · this relay</span><span class="st st-ok">412 pass</span></a></li> <li>
<li><a href="domain.html"><span>alerts.example.com · 198.51.100.80</span><span class="st st-error">19 fail</span></a></li> <a href="dmarc-report.html">
<span class="st st-ok">412 pass</span><span class="when">06:12</span>
<span class="meta">example.com · google.com · 14 Aug</span>
<span class="subj">6 fail</span>
</a>
</li>
<li>
<a href="dmarc-report-fail.html">
<span class="st st-error">19 fail</span><span class="when">04:40</span>
<span class="meta">alerts.example.com · google.com · 14 Aug</span>
<span class="subj">88 pass</span>
</a>
</li>
<li>
<a href="dmarc-report.html">
<span class="st st-ok">390 pass</span><span class="when">14 Aug</span>
<span class="meta">example.com · google.com · 13 Aug</span>
<span class="subj">2 fail</span>
</a>
</li>
</ul> </ul>
<p class="muted">Each row is one aggregate XML SelfPost parsed. Domain names open the roll-up for that sending domain.</p>
</div> </div>
</div> </div>
</main> </main>
+1 -1
View File
@@ -125,7 +125,7 @@
</div> </div>
<label>Value <span class="muted">(from Settings)</span></label> <label>Value <span class="muted">(from Settings)</span></label>
<div class="code-row"><span class="code">v=DMARC1; p=none; rua=mailto:dmarc@mail.example.org</span><button type="button" class="copy">Copy</button></div> <div class="code-row"><span class="code">v=DMARC1; p=none; rua=mailto:dmarc@mail.example.org</span><button type="button" class="copy">Copy</button></div>
<p class="muted"><a href="dmarc.html">Open DMARC reports</a> for this domain.</p> <p class="muted"><a href="dmarc-domain.html">Open DMARC reports</a> for this domain.</p>
</div> </div>
</div> </div>
<div class="pair"> <div class="pair">
+4 -9
View File
@@ -11,21 +11,16 @@
<body class="page-domains" data-page="domains" data-nav="domains" data-title="Domains"> <body class="page-domains" data-page="domains" data-nav="domains" data-title="Domains">
<main class="stack"> <main class="stack">
<div class="page-head"><h1>Domains</h1></div> <div class="page-head"><h1>Domains</h1></div>
<div class="measure g-only"> <div class="fill">
<div class="card"> <div class="card">
<h2>Add a sending domain</h2> <h2>Domains</h2>
<form action="#" onsubmit="return false;"> <form class="measure g-only" action="#" onsubmit="return false;">
<label for="dname">Domain</label> <label for="dname">Add a sending domain</label>
<div class="input-row"> <div class="input-row">
<input id="dname" placeholder="example.com" autocomplete="off"> <input id="dname" placeholder="example.com" autocomplete="off">
<button type="button">Add domain</button> <button type="button">Add domain</button>
</div> </div>
</form> </form>
</div>
</div>
<div class="fill">
<div class="card">
<h2>Domains</h2>
<table class="desk-only"> <table class="desk-only">
<thead><tr><th>Domain</th><th>DNS</th><th>Selector</th><th>Apps</th><th></th></tr></thead> <thead><tr><th>Domain</th><th>DNS</th><th>Selector</th><th>Apps</th><th></th></tr></thead>
<tbody> <tbody>
+7 -12
View File
@@ -14,21 +14,16 @@
<h1>Inbound <span class="tag">1.x</span></h1> <h1>Inbound <span class="tag">1.x</span></h1>
</div> </div>
<p class="muted">Backup-MX / forwarder. Accepts on port 25 only for listed domains. Recipients are either an allow-list or any address at that domain. Off by default in Compose.</p> <p class="muted">Backup-MX / forwarder. Accepts on port 25 only for listed domains. Recipients are either an allow-list or any address at that domain. Off by default in Compose.</p>
<div class="measure">
<div class="card">
<h2>Add inbound domain</h2>
<form action="#" onsubmit="return false">
<label>Domain</label>
<div class="input-row">
<input placeholder="lists.example.com">
<button type="button">Add domain</button>
</div>
</form>
</div>
</div>
<div class="fill"> <div class="fill">
<div class="card"> <div class="card">
<h2>Forwarding</h2> <h2>Forwarding</h2>
<form class="measure" action="#" onsubmit="return false">
<label for="iname">Add inbound domain</label>
<div class="input-row">
<input id="iname" placeholder="lists.example.com">
<button type="button">Add domain</button>
</div>
</form>
<table class="desk-only"> <table class="desk-only">
<thead><tr><th>Domain</th><th>DNS</th><th>Upstream</th><th>Recipients</th><th>TLS</th><th></th></tr></thead> <thead><tr><th>Domain</th><th>DNS</th><th>Upstream</th><th>Recipients</th><th>TLS</th><th></th></tr></thead>
<tbody> <tbody>
+5 -2
View File
@@ -80,7 +80,7 @@
<div> <div>
<h3>Domain-admin</h3> <h3>Domain-admin</h3>
<ul> <ul>
<li>Domains (только назначенные) → domain</li> <li>Domains (только назначенные) → domain → DMARC reports этого домена</li>
<li>Deliveries → message, включая пояснение retry</li> <li>Deliveries → message, включая пояснение retry</li>
<li>Settings — только учётные данные панели</li> <li>Settings — только учётные данные панели</li>
<li>Help drawer</li> <li>Help drawer</li>
@@ -162,7 +162,10 @@
<a href="inbound-backup.html">Inbound domain — DNS error</a> <a href="inbound-backup.html">Inbound domain — DNS error</a>
<a href="inbound-delete.html">Delete inbound domain</a> <a href="inbound-delete.html">Delete inbound domain</a>
<a href="status.html?inbound=0">Inbound выключен (пункта нет)</a> <a href="status.html?inbound=0">Inbound выключен (пункта нет)</a>
<a href="dmarc.html">DMARC reports <span class="tag future">candidate</span></a> <a href="dmarc.html">DMARC reports hub <span class="tag future">candidate</span></a>
<a href="dmarc-domain.html">DMARC — domain roll-up</a>
<a href="dmarc-report.html">DMARC report — aligned</a>
<a href="dmarc-report-fail.html">DMARC report — third-party fail</a>
<a href="help.html">Help <span class="tag future">candidate</span></a> <a href="help.html">Help <span class="tag future">candidate</span></a>
</div> </div>
<h3>Аварийный телефон</h3> <h3>Аварийный телефон</h3>
+5 -1
View File
@@ -184,6 +184,9 @@ body.page-inbound-domain .n-inbound,
body.page-inbound-backup .n-inbound, body.page-inbound-backup .n-inbound,
body.page-inbound-delete .n-inbound, body.page-inbound-delete .n-inbound,
body.page-dmarc .n-dmarc, body.page-dmarc .n-dmarc,
body.page-dmarc-domain .n-dmarc,
body.page-dmarc-report .n-dmarc,
body.page-dmarc-report-fail .n-dmarc,
body.page-backup .n-backup, body.page-backup .n-backup,
body.page-users .n-users, body.page-users .n-users,
body.page-user-form .n-users, body.page-user-form .n-users,
@@ -515,7 +518,8 @@ meter { width: 5rem; height: 0.7rem; vertical-align: middle; margin-right: 0.4re
.phone-list { display: none; list-style: none; margin: 0; padding: 0; } .phone-list { display: none; list-style: none; margin: 0; padding: 0; }
.phone-list li { border-bottom: 1px solid var(--border); } .phone-list li { border-bottom: 1px solid var(--border); }
.phone-list a { .phone-list a,
.phone-list .item {
display: grid; grid-template-columns: 1fr auto; gap: 0.15rem 0.7rem; display: grid; grid-template-columns: 1fr auto; gap: 0.15rem 0.7rem;
padding: 0.75rem 0.1rem; text-decoration: none; color: var(--fg); padding: 0.75rem 0.1rem; text-decoration: none; color: var(--fg);
} }
+1
View File
@@ -18,6 +18,7 @@
.fill { width: 100%; max-width: var(--ops-max); min-width: 0; } .fill { width: 100%; max-width: var(--ops-max); min-width: 0; }
.fill > .card { margin-top: 0; } .fill > .card { margin-top: 0; }
.fill .card:has(table) { overflow-x: auto; } .fill .card:has(table) { overflow-x: auto; }
.card > .measure { margin-bottom: 1rem; }
/* Two peer jobs. One child reading measure (domain-admin Settings). /* Two peer jobs. One child reading measure (domain-admin Settings).
Never a full-width lonely card on an ops page. */ Never a full-width lonely card on an ops page. */
+6 -2
View File
@@ -242,8 +242,8 @@
<td><code>stack</code>: overall → <code>pair</code> очередь‖TLS → <code>pair</code> milters‖PTR → inbound если есть → <code>pair</code> machine‖processes → configuration. На карточках остаются числа и Detail.</td> <td><code>stack</code>: overall → <code>pair</code> очередь‖TLS → <code>pair</code> milters‖PTR → inbound если есть → <code>pair</code> machine‖processes → configuration. На карточках остаются числа и Detail.</td>
</tr> </tr>
<tr> <tr>
<td><a href="domains.html">Domains</a> / <a href="deliveries.html">Deliveries</a> / <a href="system-log.html">log</a> / <a href="mail-queue.html">queue</a></td> <td><a href="domains.html">Domains</a> / <a href="inbound.html">Inbound</a> / <a href="deliveries.html">Deliveries</a> / <a href="system-log.html">log</a> / <a href="mail-queue.html">queue</a></td>
<td><code>fill</code> таблица. Добавление домена — <code>measure</code> или узкая карточка над таблицей, не растянутый инпут.</td> <td><code>fill</code> таблица. Добавление домена — поле в той же карточке списка (<code>measure</code> внутри, не вторая карточка и не инпут на 90rem).</td>
</tr> </tr>
<tr> <tr>
<td><a href="domain.html">Domain</a></td> <td><a href="domain.html">Domain</a></td>
@@ -253,6 +253,10 @@
<td><a href="inbound-domain.html">Inbound domain</a></td> <td><a href="inbound-domain.html">Inbound domain</a></td>
<td><code>fill</code> MX DNS → <code>pair</code> upstream ‖ MX to publish → <code>pair</code> recipients ‖ danger</td> <td><code>fill</code> MX DNS → <code>pair</code> upstream ‖ MX to publish → <code>pair</code> recipients ‖ danger</td>
</tr> </tr>
<tr>
<td><a href="dmarc.html">DMARC</a></td>
<td>hub: <code>pair</code> ingest ‖ this week, затем <code>fill</code> список отчётов. Домен: <a href="dmarc-domain.html">roll-up</a> (<code>pair</code> 7 days ‖ third-party, <code>fill</code> reports + sources). Один XML: <a href="dmarc-report.html">просмотр</a><code>pair</code> report ‖ policy, <code>fill</code> records. Не дашборд, не <code>ruf=</code>.</td>
</tr>
<tr> <tr>
<td><a href="backup.html">Backup</a></td> <td><a href="backup.html">Backup</a></td>
<td><code>pair</code> full backup ‖ import</td> <td><code>pair</code> full backup ‖ import</td>