Files
jarl/internal/web/static/assets/style.css
T
adamandClaude Opus 5.5 020223d1a5 Show the Name servers check as it happens, and keep its results
The zone's Name servers tab no longer waits for the other servers before
showing: it lists each query as a dig command line with a waiting
counter, fills in the answers as they arrive, then shows the result with
the queries under "Queries sent". Results (serials and delegation) are
kept for 10 minutes so revisiting the tab is instant; "Check again" asks
anew, and a check keeps running when the tab is left.

GET /zones/{zone}/serials?stream=1 streams the queries as
newline-delimited JSON (nscheck.Checker.Watch); without it the endpoint
is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:49:11 +00:00

442 lines
24 KiB
CSS

/* Jarl web UI. Plain CSS, light and dark themes. */
:root {
--bg: #f6f7f9;
--panel: #ffffff;
--text: #1d2330;
--muted: #5f6b7d;
--border: #d9dee6;
--accent: #2f5fb3;
--accent-text: #ffffff;
--accent-soft: #e5edfa;
--ok: #1e7a46;
--ok-soft: #e3f4ea;
--warn: #8a5a00;
--warn-soft: #fdf2d9;
--err: #b3261e;
--err-soft: #fbe7e5;
--info-soft: #eef1f6;
--code-bg: #f0f2f5;
--add: #e6f6ea;
--add-text: #135c2c;
--del: #fde8e7;
--del-text: #8c1d18;
--hunk: #e8eefb;
--shadow: 0 1px 2px rgba(20, 30, 50, 0.08);
--radius: 6px;
--vc-green: #3d8160; --vc-teal: #2f7c80; --vc-purple: #7a5ba8; --vc-pink: #a8557f;
--vc-orange: #a8652f; --vc-yellow: #8a7424; --vc-red: #b0534c; --vc-grey: #6b7280;
--mono: ui-monospace, "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace;
color-scheme: light;
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--bg: #14171c;
--panel: #1c2027;
--text: #e3e7ee;
--muted: #9aa5b5;
--border: #2f3540;
--accent: #6d9be8;
--accent-text: #0f1520;
--accent-soft: #23314a;
--ok: #59c287;
--ok-soft: #173326;
--warn: #e5b450;
--warn-soft: #3a2f15;
--err: #f08077;
--err-soft: #3c1f1d;
--info-soft: #232833;
--code-bg: #242933;
--add: #183a25;
--add-text: #9fe3b5;
--del: #43201e;
--del-text: #f7b2ac;
--hunk: #23314a;
--shadow: none;
--vc-green: #8fcfa9; --vc-teal: #87cdd0; --vc-purple: #bca6e6; --vc-pink: #e6a6c6;
--vc-orange: #ebbb8f; --vc-yellow: #e3d08e; --vc-red: #eba29c; --vc-grey: #aab2bf;
color-scheme: dark;
}
}
:root[data-theme="dark"] {
--bg: #14171c; --panel: #1c2027; --text: #e3e7ee; --muted: #9aa5b5; --border: #2f3540;
--accent: #6d9be8; --accent-text: #0f1520; --accent-soft: #23314a; --ok: #59c287; --ok-soft: #173326;
--warn: #e5b450; --warn-soft: #3a2f15; --err: #f08077; --err-soft: #3c1f1d; --info-soft: #232833;
--code-bg: #242933; --add: #183a25; --add-text: #9fe3b5; --del: #43201e; --del-text: #f7b2ac; --hunk: #23314a;
--shadow: none; color-scheme: dark;
--vc-green: #8fcfa9; --vc-teal: #87cdd0; --vc-purple: #bca6e6; --vc-pink: #e6a6c6;
--vc-orange: #ebbb8f; --vc-yellow: #e3d08e; --vc-red: #eba29c; --vc-grey: #aab2bf;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
background: var(--bg);
color: var(--text);
font: 14px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, sans-serif;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
code, pre, .mono, textarea.mono, input.mono { font-family: var(--mono); font-size: 13px; }
pre { background: var(--code-bg); padding: 10px 12px; border-radius: var(--radius); overflow: auto; margin: 0; white-space: pre; }
h1 { font-size: 20px; margin: 0 0 4px; }
h2 { font-size: 16px; margin: 18px 0 8px; }
h3 { font-size: 14px; margin: 14px 0 6px; }
.muted { color: var(--muted); }
.small { font-size: 12px; }
.nowrap { white-space: nowrap; }
.warn-text { color: var(--warn); }
.right { text-align: right; }
.hidden { display: none !important; }
/* Layout */
header.top {
display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
background: var(--panel); border-bottom: 1px solid var(--border);
padding: 8px 16px; position: sticky; top: 0; z-index: 10;
}
header.top .brand { display: inline-flex; align-items: center; gap: 8px; color: var(--text); text-decoration: none; }
header.top .brand .logo { display: block; transition: transform 0.15s; }
header.top .brand .brand-name { display: block; color: var(--text); }
header.top .brand:hover { text-decoration: none; }
header.top .brand:hover .brand-name { color: var(--accent); }
header.top .brand:hover .logo { transform: scale(1.06); }
nav.main { display: flex; gap: 2px; flex-wrap: wrap; }
nav.main a { padding: 6px 10px; border-radius: var(--radius); color: var(--text); }
nav.main a:hover { background: var(--info-soft); text-decoration: none; }
nav.main a.active { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
header.top .spacer { flex: 1; }
header.top form.search input { width: 220px; }
header.top .user { color: var(--muted); }
main { padding: 16px; max-width: 1400px; margin: 0 auto; }
.pending-bar {
display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
background: var(--warn-soft); color: var(--text); border-bottom: 1px solid var(--border);
padding: 8px 16px;
}
.pending-bar strong { color: var(--warn); }
/* The review/live switch in the header. */
.mode-toggle { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: 999px; font-size: 12px; font-weight: 500; background: transparent; color: var(--muted); border: 1px solid var(--border); }
.mode-toggle:hover { color: var(--text); border-color: var(--accent); }
.mode-toggle .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--muted); }
.mode-toggle.live { color: var(--warn); border-color: var(--warn); background: var(--warn-soft); }
.mode-toggle.live .dot { background: var(--warn); }
.page-head { display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.page-head .grow { flex: 1; min-width: 200px; }
.actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
/* Panels and cards */
.panel { background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius); padding: 14px 16px; box-shadow: var(--shadow); margin-bottom: 14px; }
.panel > h2:first-child, .panel > h3:first-child { margin-top: 0; }
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; margin-bottom: 14px; }
.card { background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius); padding: 12px 14px; box-shadow: var(--shadow); }
.card .label { color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: 0.4px; }
.card .value { font-size: 18px; font-weight: 600; margin-top: 2px; }
.card .sub { color: var(--muted); font-size: 12px; margin-top: 4px; }
/* Tables */
.table-wrap { overflow-x: auto; }
table { border-collapse: collapse; width: 100%; background: var(--panel); }
th, td { text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--border); vertical-align: top; }
th { font-size: 12px; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: 0.3px; white-space: nowrap; }
tr:hover td { background: var(--info-soft); }
td.data { font-family: var(--mono); font-size: 13px; word-break: break-all; }
td.name { font-family: var(--mono); font-size: 13px; white-space: nowrap; }
td.name.repeat { color: var(--muted); }
td.actions-cell { white-space: nowrap; text-align: right; width: 1%; }
tr.editing td { background: var(--accent-soft); }
tr.pending-add td { background: var(--add); }
tr.pending-change td { background: var(--warn-soft); }
tr.pending-delete td { background: var(--del); text-decoration: line-through; color: var(--muted); }
.empty { color: var(--muted); padding: 18px; text-align: center; }
/* Forms */
input, select, textarea, button {
font: inherit; color: var(--text);
}
input[type=text], input[type=password], input[type=number], input[type=search], input:not([type]), select, textarea {
background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius); padding: 5px 8px; min-width: 0;
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--accent-soft); border-color: var(--accent); }
textarea { width: 100%; min-height: 80px; resize: vertical; }
.form-grid { display: grid; grid-template-columns: minmax(140px, 200px) 1fr; gap: 8px 14px; align-items: start; }
.form-grid > label { padding-top: 6px; color: var(--muted); }
.form-grid .help { grid-column: 2; margin-top: -4px; color: var(--muted); font-size: 12px; }
.form-grid input, .form-grid select { width: 100%; max-width: 560px; }
.inline-form { display: flex; gap: 6px; flex-wrap: wrap; align-items: flex-end; }
.inline-form .f { display: flex; flex-direction: column; gap: 2px; }
.inline-form .f label { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.3px; }
.inline-form .grow { flex: 1; min-width: 220px; }
.inline-form .grow input { width: 100%; }
.hint { color: var(--muted); font-size: 12px; margin-top: 4px; }
.check { display: inline-flex; gap: 6px; align-items: center; cursor: pointer; }
button, .button {
display: inline-flex; align-items: center; gap: 6px;
background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius);
padding: 5px 12px; cursor: pointer; white-space: nowrap; color: var(--text);
}
button:hover, .button:hover { background: var(--info-soft); text-decoration: none; }
button.primary, .button.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-text); font-weight: 600; }
button.primary:hover { filter: brightness(1.08); background: var(--accent); }
button.danger { color: var(--err); border-color: var(--err); }
button.danger:hover { background: var(--err-soft); }
button.small, .button.small { padding: 2px 8px; font-size: 12px; }
button.link { border: none; background: none; color: var(--accent); padding: 0 4px; }
button:disabled { opacity: 0.5; cursor: not-allowed; }
/* Badges and messages */
.badge { display: inline-block; padding: 1px 7px; border-radius: 10px; font-size: 11px; font-weight: 600; background: var(--info-soft); color: var(--muted); white-space: nowrap; }
.badge.ok { background: var(--ok-soft); color: var(--ok); }
.badge.warn { background: var(--warn-soft); color: var(--warn); }
.badge.err { background: var(--err-soft); color: var(--err); }
.badge.accent { background: var(--accent-soft); color: var(--accent); }
.msg { border-radius: var(--radius); padding: 8px 12px; margin: 8px 0; border: 1px solid transparent; }
.msg.err { background: var(--err-soft); color: var(--err); border-color: var(--err); }
.msg.warn { background: var(--warn-soft); color: var(--warn); }
.msg.ok { background: var(--ok-soft); color: var(--ok); }
.msg.info { background: var(--info-soft); }
.msg ul { margin: 4px 0 0; padding-left: 18px; }
.problems { list-style: none; padding: 0; margin: 6px 0; }
.problems li { padding: 4px 8px; border-left: 3px solid var(--border); margin-bottom: 3px; background: var(--info-soft); border-radius: 0 var(--radius) var(--radius) 0; }
.problems li.error { border-color: var(--err); background: var(--err-soft); }
.problems li.warning { border-color: var(--warn); background: var(--warn-soft); }
.problems li .where { color: var(--muted); font-size: 12px; margin-left: 6px; }
/* Diff */
.diff { background: var(--code-bg); border-radius: var(--radius); overflow: auto; font-family: var(--mono); font-size: 12.5px; line-height: 1.4; }
.diff div { white-space: pre; padding: 0 10px; }
.diff .add { background: var(--add); color: var(--add-text); }
.diff .del { background: var(--del); color: var(--del-text); }
.diff .hunk { background: var(--hunk); color: var(--accent); }
.diff .file { font-weight: 700; padding-top: 6px; }
/* Tabs */
.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--border); margin-bottom: 12px; flex-wrap: wrap; }
.tabs a { padding: 7px 12px; border: 1px solid transparent; border-bottom: none; border-radius: var(--radius) var(--radius) 0 0; color: var(--muted); }
.tabs a.active { background: var(--panel); border-color: var(--border); color: var(--text); font-weight: 600; margin-bottom: -1px; }
/* Modal */
.modal-back { position: fixed; inset: 0; background: rgba(10, 15, 25, 0.45); display: flex; align-items: flex-start; justify-content: center; padding: 60px 16px; z-index: 50; overflow: auto; }
.modal { background: var(--panel); border-radius: 8px; border: 1px solid var(--border); width: min(760px, 100%); padding: 18px 20px; box-shadow: 0 10px 40px rgba(0,0,0,0.25); }
.modal.wide { width: min(1100px, 100%); }
.modal h2 { margin-top: 0; }
.modal .buttons { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }
/* Toasts */
#toasts { position: fixed; bottom: 16px; right: 16px; display: flex; flex-direction: column; gap: 8px; z-index: 100; max-width: min(480px, calc(100% - 32px)); }
.toast { background: var(--panel); border: 1px solid var(--border); border-left: 4px solid var(--accent); padding: 10px 14px; border-radius: var(--radius); box-shadow: 0 4px 16px rgba(0,0,0,0.18); }
.toast.ok { border-left-color: var(--ok); }
.toast.err { border-left-color: var(--err); }
.toast.warn { border-left-color: var(--warn); }
/* Login */
.login { max-width: 360px; margin: 10vh auto; }
.login-logo { display: block; margin: 8px auto 10px; }
.login h1 { text-align: center; margin: 0 0 8px; }
.wordmark { display: block; width: 220px; height: auto; margin: 0 auto; color: var(--text); }
.wordmark-rule .fill { fill: var(--accent); }
.wordmark-rule .line { fill: none; stroke: var(--accent); stroke-width: 2.6; }
.wordmark-rule .dns { fill: var(--accent); font: 700 12.5px system-ui, sans-serif; letter-spacing: 0.5px; }
.login .tag { text-align: center; color: var(--muted); margin-bottom: 18px; }
.login form { display: flex; flex-direction: column; gap: 10px; }
.login input { width: 100%; padding: 8px 10px; }
.login button { justify-content: center; padding: 8px; }
.kv { display: grid; grid-template-columns: max-content 1fr; gap: 4px 16px; }
.kv dt { color: var(--muted); }
.kv dd { margin: 0; }
.grants { font-family: var(--mono); font-size: 12px; }
.copy-box { display: flex; gap: 6px; align-items: center; }
.login.wide { max-width: 520px; }
.totp-steps { padding-left: 20px; }
.totp-steps li { margin-bottom: 12px; }
.totp-qr { margin: 10px 0; }
.totp-qr img { display: block; width: 200px; height: 200px; background: #fff; border-radius: var(--radius); }
.totp-confirm { display: flex; gap: 8px; margin-top: 6px; flex-wrap: wrap; }
input.totp-code { font-family: var(--mono); font-size: 18px; letter-spacing: 0.15em; max-width: 14em; }
.recovery-codes { font-family: var(--mono); font-size: 15px; columns: 2; max-width: 360px; }
.copy-box input { flex: 1; font-family: var(--mono); }
.ds-record { margin: 12px 0 16px; }
.ds-record > .copy-box { max-width: 900px; }
.ds-record .kv { margin-top: 8px; align-items: center; grid-template-columns: max-content minmax(0, 1fr); }
.ds-record .kv dd { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-width: 0; }
.ds-record .kv dd .copy-box { flex: 1 1 200px; max-width: 640px; min-width: 0; }
.copy-box input { min-width: 0; }
td.break { word-break: break-all; }
.sortable-row { display: flex; align-items: center; gap: 8px; }
@media (max-width: 700px) {
.form-grid { grid-template-columns: 1fr; }
.form-grid .help { grid-column: 1; }
header.top form.search input { width: 140px; }
}
/* ---- Statistics charts. Colors from the validated reference palette
(categorical slots 1-3, sequential blue), checked against this UI's
panel surfaces in both themes. */
:root {
--series-1: #2a78d6;
--series-2: #eb6834;
--series-3: #1baf7a;
--chart-grid: #eceef2;
--chart-axis: #c9cfd8;
/* Sequential ramp, low to high (blue 100 -> 700). */
--heat-0: #cde2fb; --heat-1: #9ec5f4; --heat-2: #6da7ec; --heat-3: #3987e5;
--heat-4: #256abf; --heat-5: #184f95; --heat-6: #0d366b;
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--series-1: #3987e5;
--series-2: #d95926;
--series-3: #199e70;
--chart-grid: #272c34;
--chart-axis: #3a414d;
/* In dark, low values recede into the surface: the ramp runs dark -> light. */
--heat-0: #0d366b; --heat-1: #184f95; --heat-2: #256abf; --heat-3: #3987e5;
--heat-4: #6da7ec; --heat-5: #9ec5f4; --heat-6: #cde2fb;
}
}
:root[data-theme="dark"] {
--series-1: #3987e5;
--series-2: #d95926;
--series-3: #199e70;
--chart-grid: #272c34;
--chart-axis: #3a414d;
--heat-0: #0d366b; --heat-1: #184f95; --heat-2: #256abf; --heat-3: #3987e5;
--heat-4: #6da7ec; --heat-5: #9ec5f4; --heat-6: #cde2fb;
}
.refreshing { opacity: 0.6; transition: opacity 0.2s; }
.filter-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.segmented { display: inline-flex; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--panel); }
.segmented a { padding: 4px 12px; color: var(--text); border-right: 1px solid var(--border); text-decoration: none; font-variant-numeric: tabular-nums; }
.segmented a:last-child { border-right: none; }
.segmented a:hover { background: var(--info-soft); }
.segmented a.active { background: var(--accent); color: var(--accent-text); font-weight: 600; }
.card.stat .value.big { font-size: 26px; font-weight: 600; line-height: 1.2; }
.chart-card { margin: 0 0 14px; }
.chart-head { display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap; margin-bottom: 8px; }
.chart-head .grow { flex: 1; min-width: 200px; }
.chart-head h2 { margin: 0; font-size: 16px; }
.chart-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 0 14px; }
.chart-grid > .panel h2 { margin: 0; font-size: 16px; }
.list-sub { margin: 2px 0 8px; }
.chart { position: relative; outline: none; }
.chart:focus-visible { box-shadow: 0 0 0 2px var(--accent); border-radius: var(--radius); }
.chart svg { display: block; overflow: visible; }
.chart .grid { stroke: var(--chart-grid); stroke-width: 1; }
.chart .axis { stroke: var(--chart-axis); stroke-width: 1; }
.chart .tick, .chart .end-label { fill: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums; }
.chart .end-label { fill: var(--text); }
.chart .line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart .area { stroke: none; fill-opacity: 0.1; }
.chart .dot { stroke: var(--panel); stroke-width: 2; }
.chart .crosshair { stroke: var(--muted); stroke-width: 1; }
.chart .hit { fill: transparent; cursor: crosshair; }
.chart .s1, .key.s1 { stroke: var(--series-1); }
.chart .s2, .key.s2 { stroke: var(--series-2); }
.chart .s3, .key.s3 { stroke: var(--series-3); }
.chart .area.s1, .chart .dot.s1 { fill: var(--series-1); }
.chart .area.s2, .chart .dot.s2 { fill: var(--series-2); }
.chart .area.s3, .chart .dot.s3 { fill: var(--series-3); }
.key.line { display: inline-block; width: 14px; height: 0; border-top: 2px solid; vertical-align: middle; margin-right: 6px; }
.key.line.s1 { border-color: var(--series-1); }
.key.line.s2 { border-color: var(--series-2); }
.key.line.s3 { border-color: var(--series-3); }
.chart-legend { list-style: none; display: flex; gap: 14px; margin: 2px 0 0; padding: 0; font-size: 13px; color: var(--text); flex-wrap: wrap; }
.chart-tip { position: absolute; z-index: 5; pointer-events: none; background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.16); padding: 6px 10px; font-size: 13px; white-space: nowrap; }
.chart-tip .tip-head { color: var(--muted); font-size: 12px; margin-bottom: 2px; }
.chart-tip .tip-row strong { font-variant-numeric: tabular-nums; }
.chart-table .scroll, .chart-table .table-wrap { max-height: 360px; overflow: auto; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
.heatmap-wrap { position: relative; }
.heatmap { display: grid; grid-template-columns: 36px repeat(24, minmax(10px, 1fr)); gap: 2px; outline: none; }
.heatmap:focus-visible { box-shadow: 0 0 0 2px var(--accent); }
.hm-corner, .hm-col, .hm-row { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.hm-row { display: flex; align-items: center; }
.hm-cell { height: 22px; border-radius: 3px; }
.hm-cell:hover, .hm-cell:focus { outline: 2px solid var(--text); outline-offset: -1px; }
.hm-cell.empty, .hm-swatch.empty { background: transparent; box-shadow: inset 0 0 0 1px var(--chart-grid); }
.heat-0 { background: var(--heat-0); } .heat-1 { background: var(--heat-1); } .heat-2 { background: var(--heat-2); }
.heat-3 { background: var(--heat-3); } .heat-4 { background: var(--heat-4); } .heat-5 { background: var(--heat-5); }
.heat-6 { background: var(--heat-6); }
.hm-scale { display: flex; align-items: center; gap: 2px; margin-top: 10px; flex-wrap: wrap; }
.hm-scale .muted { margin: 0 6px; }
.hm-swatch { display: inline-block; width: 18px; height: 10px; border-radius: 2px; }
.bar-list { list-style: none; margin: 0; padding: 0; }
.bar-list li { padding: 4px 0; }
.bar-text { display: flex; gap: 8px; justify-content: space-between; font-size: 13px; }
.bar-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--mono); font-size: 12.5px; min-width: 0; }
.bar-value { white-space: nowrap; font-variant-numeric: tabular-nums; }
.bar-track { height: 6px; margin-top: 3px; }
.bar-fill { height: 6px; background: var(--series-1); border-radius: 0 3px 3px 0; min-width: 2px; }
@media (max-width: 700px) {
.heatmap { grid-template-columns: 30px repeat(24, minmax(6px, 1fr)); gap: 1px; }
.hm-cell { height: 16px; }
.chart-grid { grid-template-columns: 1fr; }
}
/* Address match list suggestions. */
.aml-suggest { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin-top: 6px; }
.aml-suggest .muted { margin-left: 4px; }
.aml-suggest .muted:first-child { margin-left: 0; }
button.chip { padding: 1px 8px; font-size: 12px; font-family: var(--mono); border-radius: 999px; background: var(--info-soft); border: 1px solid var(--border); color: var(--text); }
button.chip:hover { background: var(--accent-soft); border-color: var(--accent); }
.aml-problems .msg { margin: 4px 0 0; padding: 3px 8px; }
/* Zone name and record previews. */
.segmented button { border: none; border-right: 1px solid var(--border); border-radius: 0; background: transparent; padding: 4px 12px; color: var(--text); }
.segmented button:last-child { border-right: none; }
.segmented button:hover { background: var(--info-soft); }
.segmented button.active { background: var(--accent); color: var(--accent-text); font-weight: 600; }
.name-preview { margin-top: 6px; font-size: 13px; }
.name-preview .msg, .will-add .msg { margin: 4px 0 0; padding: 3px 8px; }
.will-add { margin-top: 8px; font-size: 13px; }
.will-add code { font-family: var(--mono); background: var(--code-bg); padding: 1px 6px; border-radius: 4px; word-break: break-all; }
@media (prefers-reduced-motion: reduce) {
header.top .brand .logo { transition: none; }
header.top .brand:hover .logo { transform: none; }
}
/* a zone tab's previous content while the next tab loads */
.zone-body.stale { opacity: 0.5; transition: opacity 0.15s 0.1s; pointer-events: none; }
/* the "← Zones" link above a page's heading */
.back-link { font-size: 13px; margin-bottom: 2px; }
/* view colours (the default is the link colour) */
.vc-green { color: var(--vc-green); } .vc-teal { color: var(--vc-teal); } .vc-purple { color: var(--vc-purple); }
.vc-pink { color: var(--vc-pink); } .vc-orange { color: var(--vc-orange); } .vc-yellow { color: var(--vc-yellow); }
.vc-red { color: var(--vc-red); } .vc-grey { color: var(--vc-grey); } .vc-default { color: var(--accent); }
.swatches { display: flex; flex-wrap: wrap; gap: 8px; padding: 2px 0; }
.swatch { width: 24px; height: 24px; min-width: 0; padding: 0; border-radius: 50%; background: currentColor; border: 2px solid var(--panel); box-shadow: 0 0 0 1px var(--border); cursor: pointer; }
.swatch:hover { background: currentColor; }
.swatch.selected { box-shadow: 0 0 0 2px currentColor; }
.swatch:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }
tr.selected td { background: var(--accent-soft); }
/* the page footer with the Jarl build */
.shell { min-height: 100vh; display: flex; flex-direction: column; }
.shell > main { flex: 1; width: 100%; }
footer.site { padding: 12px 16px 16px; text-align: center; font-size: 12px; color: var(--muted); }
footer.site a { color: var(--muted); text-decoration: underline; text-decoration-color: var(--border); text-underline-offset: 2px; }
footer.site a:hover { color: var(--accent); text-decoration-color: currentColor; }
/* a request in progress */
.spinner { display: inline-block; width: 11px; height: 11px; margin-right: 6px; vertical-align: -1px; border: 2px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: spin 0.8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation: none; border-top-color: var(--border); background: var(--accent-soft); } }
/* the queries a name server check sends */
.query-log { list-style: none; margin: 6px 0; padding: 0; font-size: 13px; }
.query-log li { padding: 3px 0; display: flex; flex-wrap: wrap; gap: 6px; align-items: baseline; }
.query-log code { background: var(--code-bg); padding: 1px 6px; border-radius: 4px; overflow-wrap: anywhere; }
.query-log li.pending code { opacity: 0.85; }
.err-text { color: var(--err); }
.query-details { margin: 8px 0; }