Shell: collapsible rail, DNS/Server groups with pins, always-on header with breadcrumbs and server status, Ctrl/Cmd+K command palette. Cache: left column is a lazily expanded tree of every zone, right column the selected node's records; both columns are ReUI Frames. Styles: dark variant follows data-theme (field and outline fills), 32 px selects, 36 px segmented strip, 40 px caption table heads, 56 px rows, 20/24/32 page padding. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
85 lines
4.6 KiB
CSS
85 lines
4.6 KiB
CSS
/* The status block: a mark, two lines, the control. */
|
|
.status { display: flex; align-items: center; gap: var(--s-9); }
|
|
.mark { display: grid; place-items: center; width: var(--s-12); height: var(--s-12); border-radius: var(--r-3); flex: none; }
|
|
.on { background: var(--ok-bg); border: 1px solid var(--ok-bd); color: var(--ok); }
|
|
.paused { background: var(--acc-bg); border: 1px solid var(--acc-bd); color: var(--acc-ink); }
|
|
.off { background: var(--pan2); border: 1px solid var(--line); color: var(--mute); }
|
|
.statusText { flex: 1; min-width: 0; }
|
|
.statusTitle { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-5); font-size: var(--t-5); font-weight: 600; }
|
|
.statusSub { color: var(--mute); margin-top: var(--s-1); }
|
|
|
|
/* Top tables: name, a bar for the share, the hits, the row menu. */
|
|
/* The name wraps at its dots only (`ui/DomainName`), never inside a label. */
|
|
.name { font-family: var(--font-mono); }
|
|
.hits { font-family: var(--font-mono); text-align: right; white-space: nowrap; }
|
|
/* The header over the hits sits where the figures end, not where they would begin.
|
|
Written to outweigh `.table thead th` of ui/Table, which sets every header left. */
|
|
thead > tr > th.hitsHead { text-align: right; }
|
|
/* A block, not the span's inline box: an inline element ignores `height`. */
|
|
.share { display: block; position: relative; height: var(--s-3); min-width: var(--s-12); border-radius: var(--r-1); background: var(--line2); }
|
|
.share > i { position: absolute; inset: 0 auto 0 0; border-radius: var(--r-1); }
|
|
.shareBlocked > i { background: var(--ch-block); }
|
|
.shareTotal > i { background: var(--ch-total); }
|
|
.time { font-family: var(--font-mono); color: var(--faint); white-space: nowrap; }
|
|
/* Where Recently Blocked's rows stack (`stack` in ui/Table: always below 560), the time
|
|
no longer has to share a line with the domain and keeps its one line. It used to
|
|
wrap there, `2026-10-` / `16` / `09:42:52`, beside a domain a few characters wide. */
|
|
.mono { font-family: var(--font-mono); }
|
|
/* The node after Recently Blocked's title: part of the title, quieter than it. */
|
|
.where { color: var(--mute); font-weight: 400; }
|
|
/*
|
|
Muted, not `--warn`: on this screen the paused mark is `--acc`, and tokens.css
|
|
measures the two ambers as indistinguishable. The sentence and its icon say it.
|
|
*/
|
|
.partial { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-5) var(--s-9); color: var(--mute); }
|
|
|
|
/*
|
|
A figure's trend, beside its text and as tall as it (`.kpi` in Blocking.module.css):
|
|
the text keeps its width, so its three lines stay level with the other cards', and the
|
|
trend takes what is left, up to half the card. Size containment drops the drawing's own
|
|
100:32 shape, so a wide screen cannot make the trend, and with it the card, taller.
|
|
*/
|
|
.spark {
|
|
display: block;
|
|
flex: 1 1 0;
|
|
align-self: stretch;
|
|
min-width: var(--s-12);
|
|
max-width: 50%;
|
|
height: auto;
|
|
contain: size;
|
|
}
|
|
/*
|
|
`--bp-stack`. Two cards a row leave no room beside the text, so the trend drops to the
|
|
card's foot and runs to its edges, as the drawing has it: the body's padding
|
|
(`--s-9`, ui/Panel) is given back on three sides and the panel's rounded corners clip
|
|
it. The two cards with a trend share the first row, so no card in a row has a band
|
|
the other lacks.
|
|
*/
|
|
@media (max-width: 560px) {
|
|
.trended { flex-wrap: wrap; }
|
|
.spark {
|
|
flex-basis: calc(100% + 2 * var(--s-9));
|
|
max-width: none;
|
|
height: var(--s-12);
|
|
margin: 0 calc(-1 * var(--s-9)) calc(-1 * var(--s-9));
|
|
}
|
|
}
|
|
.sparkTotal { color: var(--ch-total); }
|
|
.sparkBlocked { color: var(--ch-block); }
|
|
|
|
/* The ring, with the share written in its hole. */
|
|
.ring { position: relative; }
|
|
.ringValue { position: absolute; inset: 0; display: grid; place-content: center; text-align: center; font-family: var(--font-mono); font-size: var(--t-6); font-weight: 600; pointer-events: none; }
|
|
.ringLabel { display: block; font-family: var(--font-ui); font-size: var(--t-1); font-weight: var(--text-weight); letter-spacing: var(--text-tracking); color: var(--mute); }
|
|
|
|
/*
|
|
The status block and "Check, block or allow a domain" share a row, and the grid
|
|
stretches both to the taller one. Before any check that is what balances the row:
|
|
the status block is the shorter, and its content sits in its middle (`.centred`).
|
|
Once the check panel holds something under its field (the wait, the verdict, or why
|
|
there is none), stretching would leave the status block a tall box with one line
|
|
floating in it, so it keeps its own height instead, top-aligned. The check panel's
|
|
answer region is empty (`:empty`) until then.
|
|
*/
|
|
.checkRow:has([aria-live]:not(:empty)) > :first-child { align-self: start; }
|