Files
technitium-console/src/screens/blocking/Overview.module.css
T
DenozordecandClaude Sonnet 5.5 f4513533c4 App shell as the canvas draws it, full lazy Cache tree, styles aligned with the parent projects
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>
2026-10-27 09:35:41 +07:00

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; }