The firewall page now manages zones (assign each LAN or tunnel, add and remove zones) and rules with zone, address and port on both sides plus the protocol. router.firewall.zones declares zones without members and rules take sourcePorts. The temperature chart draws every thermal zone and hwmon sensor; the overview defaults to 15 minutes, 1h stays an option. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AeFqV9dZrK6nipHkPfyM4F
78 lines
5.7 KiB
CSS
78 lines
5.7 KiB
CSS
:root { --fg: #1d2125; --muted: #5b636b; --bg: #fff; --line: #d6dade; --accent: #2457c5; --warn: #fff4d6; --bad: #b3261e; --ok: #e6f2e9; }
|
|
@media (prefers-color-scheme: dark) {
|
|
:root { --fg: #e4e7ea; --muted: #9aa2aa; --bg: #15181b; --line: #30363c; --accent: #7aa2ff; --warn: #3a3218; --bad: #ff8a80; --ok: #1d3324; }
|
|
}
|
|
* { box-sizing: border-box; }
|
|
body { margin: 0; font: 15px/1.5 system-ui, sans-serif; color: var(--fg); background: var(--bg); }
|
|
header { display: flex; gap: 1.5rem; align-items: center; padding: .75rem 1rem; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
|
|
nav { display: flex; gap: 1rem; align-items: center; flex-wrap: wrap; }
|
|
nav form { display: inline; }
|
|
a { color: var(--accent); }
|
|
main { max-width: 72rem; margin: 0 auto; padding: 1rem; }
|
|
h1 { font-size: 1.4rem; margin: .5rem 0 1rem; }
|
|
h2 { font-size: 1.1rem; margin: 0 0 .5rem; }
|
|
section { margin: 0 0 1.25rem; }
|
|
section.busy, section.pending { padding: .75rem 1rem; border-radius: 6px; background: var(--warn); }
|
|
.flash { padding: .5rem .75rem; background: var(--ok); border-radius: 6px; }
|
|
.error, .field-error { color: var(--bad); }
|
|
.field-error { font-size: .9em; }
|
|
.hint { color: var(--muted); font-size: .9em; margin: .25rem 0; }
|
|
dl { display: grid; grid-template-columns: max-content 1fr; gap: .25rem 1rem; }
|
|
dt { color: var(--muted); }
|
|
dd { margin: 0; overflow-wrap: anywhere; }
|
|
fieldset { border: 1px solid var(--line); border-radius: 6px; margin: 0 0 1rem; padding: .75rem 1rem; overflow-x: auto; }
|
|
label { display: inline-flex; flex-direction: column; margin: 0 1rem .5rem 0; font-size: .9em; color: var(--muted); }
|
|
input, select, textarea, button { font: inherit; color: var(--fg); background: var(--bg); border: 1px solid var(--line); border-radius: 4px; padding: .3rem .5rem; }
|
|
textarea { width: 100%; font-family: ui-monospace, monospace; font-size: 13px; }
|
|
table { border-collapse: collapse; }
|
|
th { text-align: left; font-weight: 500; color: var(--muted); font-size: .85em; padding: 0 .3rem; }
|
|
td { padding: .15rem .3rem; }
|
|
button { background: var(--accent); color: var(--bg); border-color: var(--accent); cursor: pointer; padding: .4rem 1rem; }
|
|
button.secondary { background: transparent; color: var(--accent); }
|
|
button.link { background: none; border: none; color: var(--accent); padding: 0; text-decoration: underline; }
|
|
.actions { display: flex; gap: .75rem; flex-wrap: wrap; }
|
|
.narrow { max-width: 22rem; display: flex; flex-direction: column; gap: .75rem; }
|
|
.narrow label { margin: 0; }
|
|
pre.log { background: color-mix(in srgb, var(--line) 35%, transparent); padding: .75rem; border-radius: 6px; overflow-x: auto; font-size: 12.5px; max-height: 30rem; }
|
|
code { font-size: .9em; overflow-wrap: anywhere; }
|
|
.muted { color: var(--muted); }
|
|
.bad { color: var(--bad); }
|
|
.ok { color: var(--good); }
|
|
:root { --good: #1e7b34; --s0: #2457c5; --s1: #d9730d; --s2: #2f9e44; --s3: #9c36b5; --s4: #c92a2a; --s5: #0b7285; --s6: #862e9c; --s7: #5c940d; --s8: #a61e4d; --s9: #5f3dc4; }
|
|
@media (prefers-color-scheme: dark) { :root { --good: #69db7c; --s0: #7aa2ff; --s1: #ffa94d; --s2: #69db7c; --s3: #da77f2; --s4: #ff8787; --s5: #66d9e8; --s6: #e599f7; --s7: #c0eb75; --s8: #faa2c1; --s9: #b197fc; } }
|
|
.ranges { display: flex; gap: .25rem; margin: 0 0 1rem; }
|
|
.ranges a { padding: .2rem .7rem; border: 1px solid var(--line); border-radius: 4px; text-decoration: none; }
|
|
.ranges a.active { background: var(--accent); color: var(--bg); border-color: var(--accent); }
|
|
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); gap: 1rem; margin: 0 0 1.25rem; }
|
|
.card { border: 1px solid var(--line); border-left-width: 4px; border-radius: 6px; padding: .75rem 1rem; margin: 0; }
|
|
.card.up { border-left-color: var(--good); }
|
|
.card.degraded { border-left-color: #e8a600; }
|
|
.card.down { border-left-color: var(--bad); }
|
|
.card .state { font-weight: 600; margin: 0 0 .5rem; }
|
|
.card dl { margin: 0; font-size: .92em; }
|
|
.events { list-style: none; margin: 0; padding: 0; font-size: .9em; }
|
|
.events li span:first-child { display: inline-block; width: 2.5rem; font-weight: 600; }
|
|
.scroll { overflow-x: auto; }
|
|
.leases td, .leases th { padding: .2rem .75rem .2rem 0; white-space: nowrap; }
|
|
.charts { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 30rem), 1fr)); gap: 1rem; margin: 0 0 1.5rem; }
|
|
.chart { margin: 0; border: 1px solid var(--line); border-radius: 6px; padding: .5rem .75rem; min-width: 0; }
|
|
.chart figcaption { display: flex; flex-wrap: wrap; gap: .25rem 1rem; justify-content: space-between; font-size: .9em; }
|
|
.legend { display: flex; flex-wrap: wrap; gap: .1rem .9rem; }
|
|
.key::before { content: ""; display: inline-block; width: .7rem; height: .2rem; margin: 0 .3rem .2rem 0; background: currentColor; vertical-align: middle; }
|
|
.key b { font-weight: 500; color: var(--fg); }
|
|
.chart svg { width: 100%; height: auto; display: block; overflow: visible; }
|
|
.chart .grid { stroke: var(--line); stroke-width: 1; }
|
|
.chart .lab { fill: var(--muted); font-size: 11px; }
|
|
.chart .line { fill: none; stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; }
|
|
.chart .hover { fill: transparent; }
|
|
.chart .hover:hover { fill: color-mix(in srgb, var(--fg) 8%, transparent); }
|
|
.s0 { color: var(--s0); stroke: var(--s0); } .s1 { color: var(--s1); stroke: var(--s1); } .s2 { color: var(--s2); stroke: var(--s2); }
|
|
.s3 { color: var(--s3); stroke: var(--s3); } .s4 { color: var(--s4); stroke: var(--s4); }
|
|
.s5 { color: var(--s5); stroke: var(--s5); } .s6 { color: var(--s6); stroke: var(--s6); } .s7 { color: var(--s7); stroke: var(--s7); } .s8 { color: var(--s8); stroke: var(--s8); } .s9 { color: var(--s9); stroke: var(--s9); }
|
|
|
|
/* WireGuard */
|
|
.qr svg { width: 14rem; height: 14rem; background: #fff; }
|
|
pre { overflow-x: auto; white-space: pre-wrap; word-break: break-all; }
|
|
form.inline { margin-top: 0.5rem; }
|
|
details { margin: 0.5rem 0; }
|