Files
Privatae e4c9b69b46
ci / personal-data (push) Successful in 5s
ci / test (push) Successful in 3m4s
ci / fuzz (push) Successful in 3m45s
bastion 0.53.2
2026-10-20 04:42:14 +00:00

189 lines
6.3 KiB
CSS

/* The local UI's whole stylesheet. Plain, literal, no framework — the same
voice as the product's copy. Served from the binary, never from a CDN. */
:root {
--bg: #16181d;
--panel: #1e2128;
--line: #2c313b;
--ink: #e6e8ec;
--dim: #9aa1ad;
--ok: #4ea96b;
--warn: #d79a3c;
--bad: #d1584f;
}
* { box-sizing: border-box; }
body {
margin: 0;
padding: 2rem 1.5rem 4rem;
background: var(--bg);
color: var(--ink);
font: 15px/1.55 -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
main, header, footer { max-width: 46rem; margin: 0 auto; }
header { margin-bottom: 1.5rem; }
h1 { margin: 0; font-size: 1.35rem; font-weight: 600; letter-spacing: -0.01em; }
.sub { margin: 0.15rem 0 0; color: var(--dim); font-size: 0.85rem; }
.state {
padding: 1rem 1.1rem;
border: 1px solid var(--line);
border-left-width: 3px;
border-radius: 6px;
background: var(--panel);
margin-bottom: 1.25rem;
}
.state.ok { border-left-color: var(--ok); }
.state.warn { border-left-color: var(--warn); }
.state.bad { border-left-color: var(--bad); }
.state h2 { margin: 0; font-size: 1rem; font-weight: 600; }
.state p { margin: 0.45rem 0 0; color: var(--dim); font-size: 0.87rem; }
/* ── waiting for you ───────────────────────────────────────────────────────
The only thing on this page that is time-critical, so it is the only thing
allowed to shout. */
h3.urgent { color: var(--warn); font-size: 0.85rem; margin-top: 0; }
.flash {
padding: 0.7rem 1rem;
border-radius: 6px;
margin-bottom: 1rem;
font-size: 0.88rem;
border: 1px solid var(--line);
}
.flash.ok { border-color: var(--ok); color: var(--ok); }
.flash.warn { border-color: var(--warn); color: var(--warn); }
.flash.bad { border-color: var(--bad); color: var(--bad); }
.approval {
border: 1px solid var(--warn);
border-radius: 6px;
background: var(--panel);
padding: 1rem 1.1rem;
margin-bottom: 0.8rem;
}
.approval-head { font-weight: 600; }
.approval-head .id {
color: var(--dim); font-weight: 400;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-size: 0.8rem;
}
.approval-line { margin: 0.45rem 0 0; font-size: 0.88rem; white-space: pre-wrap; }
.approval.unreadable { border-color: var(--bad); }
.approval.unreadable .approval-line strong { color: var(--bad); }
.approval-acts { display: flex; gap: 0.6rem; margin-top: 0.9rem; flex-wrap: wrap; }
/* Deny is written first in the markup so it leads for keyboard and screen
readers; on a describable request the visual order goes back to Approve
first, where it belongs. */
.approval-acts:not(.reversed) { flex-direction: row-reverse; justify-content: flex-end; }
.approval-acts form { display: flex; gap: 0.4rem; margin: 0; }
.approval-foot { margin: 0.7rem 0 0; color: var(--dim); font-size: 0.78rem; }
input.code {
width: 9rem;
padding: 0.45rem 0.6rem;
border: 1px solid var(--line);
border-radius: 5px;
background: var(--bg);
color: var(--ink);
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-size: 0.95rem;
letter-spacing: 0.08em;
}
input.code:focus { outline: 2px solid var(--warn); outline-offset: 1px; }
button {
padding: 0.45rem 1rem;
border-radius: 5px;
border: 1px solid var(--line);
background: var(--line);
color: var(--ink);
font: inherit;
font-size: 0.88rem;
font-weight: 600;
cursor: pointer;
}
button.go { background: var(--ok); border-color: var(--ok); color: #0d1410; }
button.no { background: transparent; color: var(--dim); }
button:hover { filter: brightness(1.12); }
/* ── what has happened here ────────────────────────────────────────────────
The same card as .host, deliberately NOT the .approval treatment: an approval
is a question the page is holding open, and these are answers to questions
nobody asked. A recent one — or a live refusal — takes the bad border,
because the host killing your programs is the one thing on this page you did
not do and were never told about. The border is the whole difference; an
event is never hidden once it stops being recent, it only stops shouting. */
.event {
border: 1px solid var(--line);
border-radius: 6px;
background: var(--panel);
padding: 0.85rem 1.1rem;
margin-bottom: 0.6rem;
}
.event.recent, .event.refused { border-color: var(--bad); }
.event-when { color: var(--dim); font-size: 0.78rem; }
.event-line { margin: 0.35rem 0 0; font-size: 0.88rem; }
.event-foot { margin: 0.65rem 0 0; color: var(--dim); font-size: 0.78rem; }
.host {
border: 1px solid var(--line);
border-radius: 6px;
background: var(--panel);
padding: 0.85rem 1.1rem;
margin-bottom: 0.6rem;
}
.host-name { font-weight: 600; word-break: break-all; }
.host-facts {
margin: 0.5rem 0 0;
display: grid;
grid-template-columns: 8.5rem 1fr;
gap: 0.2rem 0.75rem;
font-size: 0.85rem;
}
.host-facts dt { color: var(--dim); }
.host-facts dd { margin: 0; word-break: break-all; }
.tag {
display: inline-block;
margin-left: 0.5rem;
padding: 0.05rem 0.45rem;
border-radius: 999px;
font-size: 0.72rem;
font-weight: 600;
vertical-align: 0.08em;
}
.tag.ok { background: rgba(78,169,107,0.16); color: var(--ok); }
.tag.warn { background: rgba(215,154,60,0.16); color: var(--warn); }
.tag.bad { background: rgba(209,88,79,0.16); color: var(--bad); }
h3 { margin: 1.6rem 0 0.6rem; font-size: 0.8rem; font-weight: 600;
color: var(--dim); text-transform: none; letter-spacing: 0; }
/* Was an inline style="margin-top:1rem" until review pointed out the page's own
CSP (`default-src 'self'`, ui.go) covers style-src and therefore blocks it —
the policy was silently winning against the markup. A class costs nothing and
keeps the CSP with no 'unsafe-inline' escape hatch in it. */
.checked-at { margin-top: 1rem; }
footer { margin-top: 2.5rem; color: var(--dim); font-size: 0.8rem; }
footer a { color: var(--dim); }
.note {
margin-top: 0.6rem;
padding: 0.7rem 0.9rem;
border: 1px dashed var(--line);
border-radius: 6px;
color: var(--dim);
font-size: 0.84rem;
}
code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-size: 0.85em; color: var(--ink); }