Compare commits

..

2 Commits

Author SHA1 Message Date
mix 958d07fcdd panel: polish rate-limit form copy and field alignment
test / test (push) Has been cancelled
Drop the app L1 backstop line, move trusted-IP help under the IP field,
shorten the domain rate-limit title, and align field-pair labels with DMARC.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-13 00:26:17 +03:00
mix f0cd804cb3 panel: tighten rate-limit and address-mode copy
Restore muted L1 backstop line, move domain limit help above Save, and drop
the duplicate Address mode field label.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-13 00:13:34 +03:00
3 changed files with 24 additions and 23 deletions
+6 -4
View File
@@ -7,10 +7,12 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version
### Changed ### Changed
- panel: level-1 backstop is shown as a dedicated line (`N messages / Ws`) and - panel: level-1 backstop is shown as muted copy on the domain form
in message-limit labels; Settings uses a code-row for the L1 value. Domain (`N messages / Ws — Settings`) and in message-limit labels; Settings uses a
and application rate-limit status uses the shared `st` badge (`active` / code-row for the L1 value. Domain and application rate-limit status uses the
`inactive — level 1 only`). Trusted-IP override copy is a single paragraph. shared `st` badge. Trusted-IP help sits under the IP field; domain rate-limit
help sits above Save; Address mode drops the duplicate field label; field-pair
top spacing aligns with paired DMARC labels.
## [1.2.4] - 2026-08-12 ## [1.2.4] - 2026-08-12
+9 -1
View File
@@ -565,10 +565,18 @@ meter { width: 5rem; height: 0.7rem; vertical-align: middle; margin-right: 0.4re
one column when the parent is too narrow for both. */ one column when the parent is too narrow for both. */
.field-pair { .field-pair {
display: grid; grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr)); display: grid; grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
gap: 0 1rem; margin-top: 0.45rem; gap: 0 1rem;
} }
/* First control row in a check-col form: match a bare label's top margin so
paired columns (DMARC rate limit) line up their first field labels. */
form > .field-pair { margin-top: 0; }
form > .field-pair > div > label { margin-top: 0.9rem; }
.field-pair > div { min-width: 0; } .field-pair > div { min-width: 0; }
.field-pair label { margin-top: 0.45rem; } .field-pair label { margin-top: 0.45rem; }
/* Hint under a field-pair sits tight above the form's submit button (the
global button margin-top would leave a blank line). */
.field-pair + p.muted { margin: 0.45rem 0 0; }
.field-pair + p.muted + button { margin-top: 0.45rem; }
/* Host / name beside a DNS Type that is always TXT size the type column to /* Host / name beside a DNS Type that is always TXT size the type column to
that token rather than giving it half the row. Vertical padding matches that token rather than giving it half the row. Vertical padding matches
.code-row .code so TXT is the same height as Host when Copy sits beside it. */ .code-row .code so TXT is the same height as Host when Copy sits beside it. */
+9 -18
View File
@@ -330,8 +330,7 @@
<div class="check-col"> <div class="check-col">
<p class="check-col-title">Address mode</p> <p class="check-col-title">Address mode</p>
<form method="post" action="/applications/{{.ID}}/mode"> <form method="post" action="/applications/{{.ID}}/mode">
<label>Address mode</label> <select name="mode" data-list-mode="{{$.List}}" aria-label="Address mode">
<select name="mode" data-list-mode="{{$.List}}">
<option value="{{$.Wildcard}}" {{if eq .AddressMode $.Wildcard}}selected{{end}}>Any address of the domain</option> <option value="{{$.Wildcard}}" {{if eq .AddressMode $.Wildcard}}selected{{end}}>Any address of the domain</option>
<option value="{{$.List}}" {{if eq .AddressMode $.List}}selected{{end}}>Specific addresses (list)</option> <option value="{{$.List}}" {{if eq .AddressMode $.List}}selected{{end}}>Specific addresses (list)</option>
</select> </select>
@@ -346,16 +345,12 @@
<div class="check-col"> <div class="check-col">
<p class="check-col-title">Optional trusted-IP override <p class="check-col-title">Optional trusted-IP override
{{if .HasLimit}}<span class="st st-ok">active</span>{{else}}<span class="st st-unknown">inactive</span>{{end}}</p> {{if .HasLimit}}<span class="st st-ok">active</span>{{else}}<span class="st st-unknown">inactive</span>{{end}}</p>
<p class="muted">These IPs get a higher ceiling than the domain
(≤ level&nbsp;1) and skip the domain check; everyone else uses
{{if $.DomainHasRL}}the domain ceiling ({{$.DomainRLMaxNum}}){{else}}level&nbsp;1 only{{end}}.</p>
<p>Level&nbsp;1 backstop:
<strong>{{$.L1Messages}}</strong> messages /
<strong>{{$.L1Window}}</strong>s
<a href="/settings#rate-limits">Settings</a>.</p>
<form id="rl-{{.ID}}" method="post" action="/applications/{{.ID}}/ratelimit"> <form id="rl-{{.ID}}" method="post" action="/applications/{{.ID}}/ratelimit">
<label>Trusted client IPs (required; one per line or comma-separated)</label> <label>Trusted client IPs (required; one per line or comma-separated)</label>
<textarea name="allowed_ips" rows="2" placeholder="203.0.113.10">{{.IPsText}}</textarea> <textarea name="allowed_ips" rows="2" placeholder="203.0.113.10">{{.IPsText}}</textarea>
<p class="muted">These IPs get a higher ceiling than the domain
(≤ level&nbsp;1) and skip the domain check; everyone else uses
{{if $.DomainHasRL}}the domain ceiling ({{$.DomainRLMaxNum}}){{else}}level&nbsp;1 only{{end}}.</p>
<div class="field-pair"> <div class="field-pair">
<div> <div>
<label>Message limit (max {{$.L1Messages}})</label> <label>Message limit (max {{$.L1Messages}})</label>
@@ -420,14 +415,9 @@
</div> </div>
<div class="check-col"> <div class="check-col">
<p class="check-col-title">Optional level-2 sending rate limit <p class="check-col-title">Level-2 rate limit
{{if .DomainHasRL}}<span class="st st-ok">active</span>{{else}}<span class="st st-unknown">inactive — level 1 only</span>{{end}}</p> {{if .DomainHasRL}}<span class="st st-ok">active</span>{{else}}<span class="st st-unknown">inactive</span>{{end}}</p>
<p class="muted">Applies to every client IP on this domain. Leave the <p class="muted">Level&nbsp;1 backstop: {{.L1Messages}} messages / {{.L1Window}}s — <a href="/settings#rate-limits">Settings</a>.</p>
message limit empty to use level&nbsp;1 only.</p>
<p>Level&nbsp;1 backstop (from <code>.env</code>):
<strong>{{.L1Messages}}</strong> messages /
<strong>{{.L1Window}}</strong>s
— see <a href="/settings#rate-limits">Settings</a>.</p>
<form method="post" action="/domains/{{.Domain.ID}}/ratelimit"> <form method="post" action="/domains/{{.Domain.ID}}/ratelimit">
<div class="field-pair"> <div class="field-pair">
@@ -441,7 +431,8 @@
<input id="d_win" name="window_seconds" type="number" min="1" value="{{.DomainRLWin}}"> <input id="d_win" name="window_seconds" type="number" min="1" value="{{.DomainRLWin}}">
</div> </div>
</div> </div>
<p class="muted">Applies to every client IP on this domain. Leave the
message limit empty to use level&nbsp;1 only.</p>
<button type="submit">Save limit</button> <button type="submit">Save limit</button>
</form> </form>
{{if .DomainHasRL}} {{if .DomainHasRL}}