/* SPDX-License-Identifier: AGPL-3.0-only */
/* Webmonit — the same logic and tokens as the Shieldlist console: dark
   first, light when chosen or when the system asks; one accent; data in
   monospace; small radii; no library, no font download. */
:root {
  --ground: #0d141d; --ground-2: #121b26; --panel: #1a2634; --panel-2: #22303f; --panel-3: #2a3a4c;
  --line: rgba(255,255,255,.10); --line-2: rgba(255,255,255,.18);
  --ink: #f4f7fa; --ink-2: #d5dde6; --mute: #aab5c2;
  --act: #5c98ff; --act-2: #8b6cff; --act-ink: #fff;
  --ok: #6fd39c; --chart: #59d38f; --chart-2: #5c98ff; --warn: #f0c14b; --danger: #ff6b86; --red: #ff5252; --maint: #7fb5ff; --ext: #b79bff; --unknown: #7a8795; --ack: #9aa8c7;
  --orange: #e8944a;
  --field: rgba(0,0,0,.28); --overlay: #1e2b3a; --shadow: 0 10px 34px rgba(0,0,0,.45); --glow: rgba(92,152,255,.28);
  --mono: ui-monospace, "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --r: 10px; --r-s: 7px; --t: .16s ease;
  color-scheme: dark;
}
:root[data-theme="light"] {
  --ground: #eef1f5; --ground-2: #e6eaf0; --panel: #fff; --panel-2: #f1f4f8; --panel-3: #e5eaf1;
  --line: rgba(20,30,45,.10); --line-2: rgba(20,30,45,.20);
  --ink: #121a24; --ink-2: #2f3b49; --mute: #5b6875;
  --act: #2b6fe6; --act-2: #6a4ce6;
  --ok: #1f9d5b; --chart: #12925a; --chart-2: #2b6fe6; --warn: #b8860b; --danger: #d6335a; --red: #d61f1f; --maint: #2b6fe6; --ext: #7a4fd6; --unknown: #8a95a1; --ack: #5b6b8f;
  --orange: #c2691a;
  --field: #fff; --overlay: #fff; --shadow: 0 10px 34px rgba(20,30,45,.16); --glow: rgba(43,111,230,.2);
  color-scheme: light;
}
@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) {
  --ground: #eef1f5; --ground-2: #e6eaf0; --panel: #fff; --panel-2: #f1f4f8; --panel-3: #e5eaf1;
  --line: rgba(20,30,45,.10); --line-2: rgba(20,30,45,.20);
  --ink: #121a24; --ink-2: #2f3b49; --mute: #5b6875;
  --act: #2b6fe6; --act-2: #6a4ce6;
  --ok: #1f9d5b; --chart: #12925a; --chart-2: #2b6fe6; --warn: #b8860b; --danger: #d6335a; --red: #d61f1f; --maint: #2b6fe6; --ext: #7a4fd6; --unknown: #8a95a1; --ack: #5b6b8f;
  --orange: #c2691a;
  --field: #fff; --overlay: #fff; --shadow: 0 10px 34px rgba(20,30,45,.16); --glow: rgba(43,111,230,.2);
  color-scheme: light;
} }
* { box-sizing: border-box; }
html, body { margin: 0; min-height: 100%; }
body { background: var(--ground); color: var(--ink); font: 14px/1.5 var(--sans); }
a { color: var(--act); text-decoration: none; transition: color var(--t); }
a:hover { color: var(--act-2); }
code, .mono, input, select, textarea, pre { font-family: var(--mono); font-size: 13px; }
h1, h2, h3 { font-weight: 650; letter-spacing: -0.01em; margin: 0 0 .5rem; color: var(--ink); }
h1 { font-size: 21px; display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
h2 { color: var(--ink-2); text-transform: uppercase; letter-spacing: .1em; font-size: 11.5px; margin-top: 1.6rem; font-weight: 700; display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
h2 a { color: var(--ink); text-transform: none; letter-spacing: 0; font-size: 14px; }
h2 .mono, h2 .dim { text-transform: none; letter-spacing: 0; font-weight: 400; }
p { margin: 0 0 .75rem; color: var(--ink-2); }
.dim { color: var(--mute); }
.small { font-size: 12px; }
button, .btn { background: var(--panel-2); color: var(--ink); border: 1px solid var(--line); border-radius: var(--r-s); padding: .42rem .85rem; cursor: pointer; font: inherit; line-height: 1.3; transition: background var(--t), border-color var(--t), transform var(--t); }
button:hover, .btn:hover { background: var(--panel-3); border-color: var(--line-2); transform: translateY(-1px); color: var(--ink); }
button.primary { background: linear-gradient(135deg, var(--act), var(--act-2)); color: #fff; font-weight: 600; border-color: transparent; box-shadow: 0 4px 14px var(--glow); }
button.danger { color: var(--danger); background: color-mix(in srgb, var(--danger) 10%, transparent); border-color: color-mix(in srgb, var(--danger) 25%, transparent); }
button.small, .btn.small { padding: .24rem .6rem; font-size: 12px; }
button.ghost { background: transparent; border-color: transparent; color: var(--ink-2); }
button.on, .chips button.on { background: var(--panel-3); border-color: var(--act); }
button:disabled { opacity: .5; cursor: default; transform: none; }
input, select, textarea { background: var(--field); color: var(--ink); border: 1px solid var(--line-2); border-radius: var(--r-s); padding: .42rem .65rem; }
input:focus, select:focus { border-color: var(--act); box-shadow: 0 0 0 3px var(--glow); outline: none; }
label { color: var(--ink); font-size: 12px; display: block; margin-bottom: .2rem; }
label input, label select { display: block; width: 100%; margin-top: .15rem; }
label.check { display: flex; align-items: center; gap: .45rem; font-size: 13px; }
label.check input { width: auto; }
.hint { color: var(--mute); font-size: 12px; margin: .35rem 0 0; }
.inline { display: inline-flex; gap: .5rem; align-items: flex-end; flex-wrap: wrap; }
.inline label { margin: 0; }
form.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: .6rem; align-items: end; margin-top: .6rem; }
/* A block that belongs to the whole form, not to one column. */
form.grid > .wide, form.grid > fieldset { grid-column: 1 / -1; }
form.grid > button { grid-column: 1 / -1; justify-self: start; }
details.adder summary { list-style: none; display: inline-block; }
details.adder[open] summary { margin-bottom: .4rem; }

/* header */
/* An anchor followed lands under the sticky top bar otherwise: what
   the reader clicked on sits a bar's height too low (Robin,
   2026-08-30). */
html { scroll-padding-top: 4rem; }
.top { display: grid; grid-template-columns: auto 1fr auto; gap: 1rem; align-items: center; padding: .55rem 1.2rem; border-bottom: 1px solid var(--line); background: var(--panel); position: sticky; top: 0; z-index: 5; }
.brand { color: var(--ink); font-weight: 700; white-space: nowrap; font-size: 15.5px; display: flex; align-items: center; gap: .45rem; }
.brand .logo { height: 20px; width: auto; display: block; }
.loginlogo { height: 54px; width: auto; display: block; margin: 0 auto .75rem; }
.menu { display: flex; gap: .2rem; flex-wrap: wrap; align-items: center; }
.menu a, .menu .drop > a { color: var(--ink-2); padding: .3rem .7rem; border-radius: var(--r-s); display: inline-block; line-height: 1.4; }
.menu a:hover { background: var(--panel-2); color: var(--ink); }
.menu a.on, .menu .drop.on > a { background: var(--panel-3); color: var(--ink); }
.drop { position: relative; display: inline-flex; align-items: center; }
.drop .panel { display: none; position: absolute; top: 100%; left: 0; background: var(--overlay); border: 1px solid var(--line-2); border-radius: var(--r-s); box-shadow: var(--shadow); padding: .3rem; min-width: 180px; z-index: 10; flex-direction: column; }
.drop:hover .panel, .drop:focus-within .panel { display: flex; }
.drop .panel a { display: block; }
.who { display: flex; gap: .6rem; align-items: center; }
.who form { display: inline; }
.who a.on { color: var(--ink); text-decoration: underline; }
/* theme toggle: auto / dark / light, as on the family's site */
.theme { display: none; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--line); background: var(--panel-2); color: var(--ink-2); cursor: pointer; padding: 0; }
.js .theme { display: inline-flex; }
.theme:hover { color: var(--ink); border-color: var(--mute); transform: none; }
.theme svg { width: 18px; height: 18px; display: none; }
.theme[data-mode="auto"] .i-auto, .theme[data-mode="dark"] .i-dark, .theme[data-mode="light"] .i-light { display: block; }
.tabs { display: flex; gap: .3rem; margin: .6rem 0; }
.tabs a { padding: .3rem .8rem; border-radius: var(--r-s); border: 1px solid var(--line); color: var(--ink-2); }
.tabs a.on { background: var(--panel-3); color: var(--ink); border-color: var(--act); }
.toolbar { display: flex; gap: .4rem; flex-wrap: wrap; align-items: center; margin-top: .4rem; }
.toolbar .filter { width: 320px; }
.toolbar .short { width: 150px; }
.crumbs { margin: 0 0 .2rem; font-size: 12px; }
.family { display: flex; gap: .4rem; flex-wrap: wrap; margin: .4rem 0 .8rem; }
.pill { display: inline-flex; align-items: center; gap: .4rem; padding: .2rem .6rem; border: 1px solid var(--line); border-radius: 999px; background: var(--panel); color: var(--ink); font-family: var(--mono); font-size: 12.5px; }
.pill:hover { border-color: var(--act); color: var(--ink); }

/* An ultrawide screen had a third of it empty on each side (Robin,
   2026-08-27, 3440×1440). The page follows the window up to a width
   where a table still reads, and the activity belt takes the lot. */
main { padding: 1.2rem; max-width: min(2200px, 96vw); margin: 0 auto; }
@media (max-width: 1500px) { main { max-width: 1400px; } }
main.wallpage { max-width: none; padding: 0; }
.flash { background: color-mix(in srgb, var(--warn) 15%, transparent); border: 1px solid color-mix(in srgb, var(--warn) 40%, transparent); padding: .5rem .8rem; border-radius: var(--r-s); margin-bottom: 1rem; }
/* A blind monitor is not a warning about a site: it is the tool
   saying its own answers are worthless (SPEC §5.15). */
.flash.blind { background: color-mix(in srgb, var(--red) 15%, transparent); border-color: color-mix(in srgb, var(--red) 45%, transparent); }
.head { margin-bottom: .6rem; }
.head .actions { display: flex; gap: .4rem; margin-top: .4rem; }
.counts { display: flex; gap: .4rem; flex-wrap: wrap; margin: .3rem 0; }
.filter { margin-top: .4rem; width: 300px; }
.cols { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; }
@media (max-width: 900px) { .cols { grid-template-columns: 1fr; } .top { grid-template-columns: 1fr; } }

/* tags and dots */
.tag { display: inline-block; padding: .08rem .5rem; border-radius: 999px; font-size: 11.5px; font-family: var(--mono); background: var(--panel-3); color: var(--ink-2); border: 1px solid var(--line); vertical-align: middle; }
.tag.ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 40%, transparent); background: color-mix(in srgb, var(--ok) 12%, transparent); }
.tag.down { color: var(--red); border-color: color-mix(in srgb, var(--red) 40%, transparent); background: color-mix(in srgb, var(--red) 14%, transparent); }
.tag.warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 40%, transparent); background: color-mix(in srgb, var(--warn) 12%, transparent); }
.tag.maint { color: var(--maint); border-color: color-mix(in srgb, var(--maint) 40%, transparent); background: color-mix(in srgb, var(--maint) 12%, transparent); }
.tag.mute, .tag.unknown { color: var(--mute); }
.tag.on { border-color: var(--act); color: var(--ink); }
.tag.critical { color: var(--red); }
.dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; background: var(--unknown); flex: none; }
.dot.big { width: 14px; height: 14px; }
.dot.ok { background: var(--ok); } .dot.down { background: var(--red); box-shadow: 0 0 8px var(--red); } .dot.warn { background: var(--warn); } .dot.maint { background: var(--maint); } .dot.mute { background: var(--mute); opacity: .5; }
.c-down { color: var(--red); } .c-warn { color: var(--warn); } .c-ok { color: var(--ok); }

/* lists */
.hostblock { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r); padding: .5rem 1rem .6rem; margin-bottom: .6rem; }
.hostblock h2 { margin-top: .2rem; }
.hostblock summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; font-size: 14px; }
.hostblock summary::-webkit-details-marker { display: none; }
.hostblock summary::before { content: "▸"; color: var(--mute); width: .8rem; display: inline-block; transition: transform var(--t); }
.hostblock[open] summary::before { transform: rotate(90deg); }
.hostblock .hostname { font-weight: 650; color: var(--ink); font-family: var(--mono); }
.owner { margin: .5rem 0 .2rem 1.2rem; }
.ownerhead { font-size: 11.5px; text-transform: uppercase; letter-spacing: .08em; color: var(--mute); margin-bottom: .15rem; }
.ownerhead a { color: var(--ink-2); }
/* the hosts-and-sites table: one line per site, aligned columns */
table.sites { width: 100%; border-collapse: collapse; font-size: 13px; }
table.sites th { text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em; color: var(--mute); padding: .25rem .5rem; border-bottom: 1px solid var(--line); font-weight: 600; cursor: pointer; user-select: none; white-space: nowrap; }
table.sites th.num, table.sites td.num { text-align: right; }
table.sites th[data-sort].on::after { content: " ▾"; color: var(--act); }
table.sites th[data-sort].on.asc::after { content: " ▴"; }
table.sites td { padding: .18rem .5rem; border-bottom: 1px solid color-mix(in srgb, var(--line) 60%, transparent); white-space: nowrap; vertical-align: middle; }
table.sites tr:last-child td { border-bottom: 0; }
table.sites tr.owner td { padding-top: .5rem; font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em; color: var(--mute); border-bottom: 0; }
table.sites tr.child td.name { padding-left: 1.6rem; }
table.sites td.name a { color: var(--ink); font-family: var(--mono); }
table.sites td.name .dot { margin-right: .4rem; }
table.sites tr:hover td { background: var(--panel-2); }
table.sites tr[hidden] { display: none; }
table.sites td.reason { max-width: 320px; overflow: hidden; text-overflow: ellipsis; color: var(--mute); }
table.sites .elsewhere { color: var(--warn); }
table.sites .fwd { color: var(--ink-2); font-family: var(--mono); font-size: 12px; }
.treebar { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; margin: .3rem 0 .6rem; }
.treebar input[type=search] { width: 300px; }
.treebar .count { color: var(--mute); font-size: 12px; margin-left: auto; }
.cards.compact .card { padding: .4rem .7rem; }
/* One card does not stretch across the page. */

.cards.compact .card .num { font-size: 19px; }
.card.off { opacity: .5; }
.alerts .tl { grid-template-columns: 120px auto 1fr auto; }
.sitegrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: .15rem .8rem; }
.siterow { display: grid; grid-template-columns: 12px 1fr auto auto; gap: .1rem .5rem; align-items: center; padding: .25rem .4rem; border-radius: var(--r-s); color: var(--ink); }
.siterow:hover { background: var(--panel-2); color: var(--ink); }
.siterow .name { font-family: var(--mono); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.siterow .name.sub { color: var(--ink-2); padding-left: .8rem; }
.siterow .st { font-size: 11.5px; color: var(--mute); font-family: var(--mono); }
.siterow .reason { grid-column: 2 / 4; font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.siterow .since { grid-column: 4; font-size: 11.5px; font-family: var(--mono); }
.siterow .reason:empty, .siterow .since:empty { display: none; }
.siterow[hidden] { display: none; }
table.list { width: 100%; border-collapse: collapse; background: var(--panel); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
table.list th { text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .08em; color: var(--mute); padding: .5rem .7rem; border-bottom: 1px solid var(--line); font-weight: 600; }
table.list td { padding: .42rem .7rem; border-bottom: 1px solid var(--line); vertical-align: top; }
table.list tr:last-child td { border-bottom: 0; }
table.list tr.open td { background: color-mix(in srgb, var(--red) 6%, transparent); }
.res .fam { font-family: var(--mono); font-size: 11px; color: var(--mute); display: inline-block; min-width: 2.2rem; }
.empty { text-align: center; padding: 3rem 1rem; color: var(--mute); }
.empty code { display: inline-block; margin: .2rem .3rem; background: var(--panel-2); padding: .1rem .4rem; border-radius: 4px; }
.tags .tag { margin-left: .2rem; }
details.evidence { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-s); margin-bottom: .4rem; }
details.evidence summary { padding: .4rem .7rem; cursor: pointer; color: var(--ink-2); }
details.evidence pre { margin: 0; padding: .6rem .8rem; border-top: 1px solid var(--line); white-space: pre-wrap; word-break: break-all; max-height: 400px; overflow: auto; font-size: 12px; }
/* the "acknowledged by" pill on an incident: a box, never a row — a
   site row carries the status class ack too (Robin, 2026-08-31) */
.ackbox { background: color-mix(in srgb, var(--ok) 10%, transparent); border: 1px solid color-mix(in srgb, var(--ok) 30%, transparent); padding: .4rem .7rem; border-radius: var(--r-s); display: inline-block; }

/* chart */
/* One window, one header, every chart under it on the same axis. */
.twinhead { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; margin-top: 1rem; }
.twinhead .chips { display: inline-flex; gap: .3rem; }
.twindow.picked .twinhead { position: sticky; top: 0; z-index: 3; background: var(--ground); padding: .3rem 0; }
.legend .k { cursor: pointer; user-select: none; }
/* The name wears the colour of the thing it names — muted enough to
   stay readable, because a legend is read as text before it is read as
   a colour (Robin, 2026-08-28). */
.mchart .legend .k.m-used { color: var(--mem-used); } .mchart .legend .k.m-buf { color: var(--mem-buf); }
.mchart .legend .k.m-cache { color: var(--mem-cache); } .mchart .legend .k.m-swap { color: var(--mem-swap); }
.mchart .legend .k.m-avail { color: var(--mem-avail); }
.legend .k.total { color: var(--chart); } .legend .k.ttfb { color: var(--act-2); } .legend .k.rtt { color: var(--warn); }
.legend .k.s1 { color: var(--act); } .legend .k.s2 { color: var(--act-2); } .legend .k.s3 { color: var(--warn); }
.legend .k.s4 { color: var(--red); } .legend .k.s5 { color: var(--chart-2); } .legend .k.s6 { color: var(--ok); }
.legend .k.s0 { color: var(--chart); }
.legend .k.off { opacity: .35; text-decoration: line-through; }
.chart { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r); padding: .6rem 1rem .6rem; margin-top: 1rem; }
.chart h2 { margin-top: 0; }
.chart .chips { display: inline-flex; gap: .3rem; margin-left: .3rem; }
.chart .avail { margin-left: auto; text-transform: none; letter-spacing: 0; font-weight: 400; font-family: var(--mono); }
.graphwrap { position: relative; }
.graph { width: 100%; height: 240px; display: block; }
.graph .hover line { stroke: var(--ink); stroke-width: 1; stroke-dasharray: 2 3; vector-effect: non-scaling-stroke; }
.graph .band { fill: color-mix(in srgb, var(--chart) 22%, transparent); stroke: none; }
.tip { position: absolute; pointer-events: none; background: var(--overlay); border: 1px solid var(--line-2); border-radius: var(--r-s); padding: .35rem .55rem; font-size: 12px; font-family: var(--mono); box-shadow: var(--shadow); white-space: nowrap; z-index: 3; color: var(--ink); }
.legend .band::before { background: color-mix(in srgb, var(--act) 35%, transparent); height: 8px; }
.graph .grid line { stroke: var(--line); stroke-width: 1; mix-blend-mode: overlay; opacity: .85; }
.graph .grid line.zero { stroke: var(--line-2); }
.graph .grid text { fill: var(--mute); font-size: 11px; font-family: var(--mono); paint-order: stroke; stroke: var(--panel); stroke-width: 3px; }
.graph path { fill: none; stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.graph circle.total { fill: var(--act); } .graph circle.ttfb { fill: var(--act-2); } .graph circle.rtt { fill: var(--warn); } .graph circle.warm { fill: var(--ok); }
.graph .total { stroke: var(--chart); stroke-width: 2; } .graph .ttfb { stroke: var(--act-2); } .graph .rtt { stroke: var(--warn); stroke-dasharray: 4 3; } .graph .warm { stroke: var(--ok); stroke-width: 2; }
.graph .down { fill: color-mix(in srgb, var(--red) 25%, transparent); }
/* What was last measured, held across a window it did not fall in. */
.graph .lastknown { stroke-dasharray: 3 4; opacity: .7; }
/* A chart whose series are DISCOVERED, not declared — one line per
   kind of check that ran, one per database that exists — needs a
   palette that is not tied to a meaning: s0…s9, cycled. Every one has
   its line, its marker and its legend chip, so a series added tomorrow
   is drawn without touching this file. */
.graph .s0 { stroke: var(--chart); } .graph .s1 { stroke: var(--act); } .graph .s2 { stroke: var(--act-2); }
.graph .s3 { stroke: var(--warn); } .graph .s4 { stroke: var(--red); } .graph .s5 { stroke: var(--chart-2); }
.graph .s6 { stroke: var(--ok); stroke-dasharray: 5 3; } .graph .s7 { stroke: var(--act); stroke-dasharray: 5 3; }
.graph .s8 { stroke: var(--warn); stroke-dasharray: 5 3; } .graph .s9 { stroke: var(--unknown); }
.graph circle.s0 { fill: var(--chart); } .graph circle.s1 { fill: var(--act); } .graph circle.s2 { fill: var(--act-2); }
.graph circle.s3 { fill: var(--warn); } .graph circle.s4 { fill: var(--red); } .graph circle.s5 { fill: var(--chart-2); }
.graph circle.s6 { fill: var(--ok); } .graph circle.s7 { fill: var(--act); }
.graph circle.s8 { fill: var(--warn); } .graph circle.s9 { fill: var(--unknown); }
/* The peak behind the mean: the same colour, barely there. */
.graph path.band { stroke: none; fill: color-mix(in srgb, currentColor 18%, transparent); }
.graph path.band.total { fill: color-mix(in srgb, var(--chart) 18%, transparent); }
.graph path.band.ttfb { fill: color-mix(in srgb, var(--act-2) 18%, transparent); }
.legend { font-size: 11.5px; display: flex; gap: 1rem; margin-top: .3rem; }
.legend .k::before { content: ""; display: inline-block; width: 14px; height: 3px; margin-right: .3rem; vertical-align: middle; background: var(--chart); }
.legend .ttfb::before { background: var(--act-2); } .legend .rtt::before { background: var(--warn); } .legend .warm::before { background: var(--ok); }
.legend .s1::before { background: var(--act); } .legend .s2::before { background: var(--act-2); }
.legend .s3::before { background: var(--warn); } .legend .s4::before { background: var(--red); }
.legend .s5::before { background: var(--chart-2); } .legend .s6::before { background: var(--ok); }
.legend .s7::before { background: var(--act); } .legend .s8::before { background: var(--warn); }
.legend .s9::before { background: var(--unknown); }

/* wall */
.wall { background: var(--ground); padding: 1.2rem 1.5rem; }
/* the bars and the latest changes share the wall's margins; the wall no
   longer claims the whole screen, the changes sit under it (2026-08-31) */
.wallside { padding: .6rem 1.5rem 0; }
.wallside.below { padding-top: 0; }
.wallside .treebar { margin: 0 0 .4rem; }
.wallhead { display: flex; align-items: baseline; gap: 1.2rem; margin-bottom: 1rem; }
.wallhead .big { font-size: 34px; font-weight: 700; }
.wallhead .live { margin-left: auto; color: var(--mute); font-size: 12px; }
.wallhead .walltoggle { text-decoration: none; }
.wallhead .walltoggle.on { color: var(--ink); }
.wallhead .live.on { color: var(--ok); }
/* auto-FIT, not auto-fill: with one tile it takes the whole width
   and its rows split into columns inside it, instead of a single
   column down the middle of a wide screen (Robin, 2026-08-27). */
.walltiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); gap: .8rem; align-items: start; }
.tile { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r); padding: .6rem 1rem .8rem; }
.tile h2 { margin-top: .1rem; font-size: 13px; letter-spacing: .04em; }
.tile .siterow { grid-template-columns: 12px 1fr auto; font-size: 15px; }
.tile .siterow .name { font-size: 15px; }
.allwell { text-align: center; font-size: 140px; color: var(--ok); margin-top: 12vh; opacity: .85; }
.login { max-width: 360px; margin: 12vh auto; background: var(--panel); border: 1px solid var(--line); border-radius: var(--r); padding: 1.5rem; }
.login label { margin-bottom: .6rem; }
.login button { width: 100%; margin-top: .4rem; }

/* cards, timeline, modal */
/* Cards line up from the left and keep their size: one card alone
   must not stretch across the page. */
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, max-content)); gap: .6rem; margin: .6rem 0 .4rem; justify-content: start; }
.card { display: flex; flex-direction: column; gap: .05rem; background: var(--panel); border: 1px solid var(--line); border-radius: var(--r); padding: .4rem .7rem; color: var(--ink); border-left-width: 4px; }
.card:hover { border-color: var(--line-2); color: var(--ink); }
.card .num { font-size: 18px; font-weight: 700; font-family: var(--mono); line-height: 1.15; }
.card .lbl { font-size: 12.5px; color: var(--ink-2); }
.card.ok { border-left-color: var(--ok); } .card.down { border-left-color: var(--red); } .card.warn, .card.maint { border-left-color: var(--warn); } .card.unknown { border-left-color: var(--unknown); }
.card.down .num { color: var(--red); } .card.warn .num { color: var(--warn); }
.cols.three { grid-template-columns: 1fr 1fr 1fr; }
@media (max-width: 1100px) { .cols.three { grid-template-columns: 1fr; } }
.timeline { border-left: 2px solid var(--line-2); margin: .3rem 0 .3rem .4rem; padding-left: 1rem; }
.tl { display: grid; grid-template-columns: 150px auto 1fr; gap: .6rem; align-items: baseline; padding: .25rem 0; position: relative; }
.tl::before { content: ""; position: absolute; left: calc(-1rem - 6px); top: .6rem; width: 8px; height: 8px; border-radius: 50%; background: var(--mute); }
.tl.incident::before { background: var(--red); } .tl.placement::before { background: var(--act); }
.tl .when { font-family: var(--mono); font-size: 12px; }
details.more { margin-top: 1.2rem; }
details.more summary { list-style: none; display: inline-block; }
details.more h3 { margin-top: 1rem; text-transform: uppercase; font-size: 11.5px; letter-spacing: .08em; color: var(--ink-2); }
.modal { position: fixed; inset: 0; background: rgba(0,0,0,.55); z-index: 40; display: flex; align-items: flex-start; justify-content: center; padding: 4vh 1rem; overflow: auto; }
.modal[hidden] { display: none; }
.modalbox { background: var(--ground); border: 1px solid var(--line-2); border-radius: var(--r); box-shadow: var(--shadow); width: min(1100px, 100%); position: relative; max-height: 92vh; overflow: auto; }
.modalbox .close { position: absolute; top: .5rem; right: .5rem; z-index: 2; }
.modalbody { padding: 1rem 1.2rem; }
.graph text { font-family: var(--mono); font-size: 11px; fill: var(--mute); }
.foot { max-width: min(2200px, 96vw); margin: 2rem auto 1rem; padding: 0 1.2rem; font-size: 12px; }
.foot a { color: var(--mute); }

/* A badge on a site row is also a filter: it looks clickable. */
table.sites .tag.badge { cursor: pointer; }
table.sites .tag.badge:hover { border-color: var(--act); color: var(--act); }
.actions form.inline { display: inline-flex; gap: .4rem; align-items: center; }

/* Per-family pills: IPv4 and IPv6, each for itself. */
table.sites .fam { display: inline-block; min-width: 1.15rem; text-align: center; border-radius: 4px; font-family: var(--mono); font-size: 11px; padding: 0 .18rem; border: 1px solid var(--line); color: var(--mute); margin-right: .18rem; }
table.sites .fam.ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
table.sites .fam.down { color: var(--red); border-color: color-mix(in srgb, var(--red) 50%, transparent); background: color-mix(in srgb, var(--red) 12%, transparent); }
table.sites .fam.warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 50%, transparent); }

/* Columns the user turned off (saved on their account). */
#tree.no-resp .c-resp, #tree.no-fam .c-fam, #tree.no-status .c-status, #tree.no-since .c-since, #tree.no-addr .c-addr, #tree.no-detail .c-detail { display: none; }
#tree.no-badges .tag.badge { display: none; }
.cols-picker { position: relative; display: inline-block; }
.cols-picker .menu { position: absolute; right: 0; top: 100%; margin-top: .3rem; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: .55rem .8rem; display: flex; flex-direction: column; gap: .3rem; z-index: 30; white-space: nowrap; box-shadow: 0 8px 24px rgba(0,0,0,.35); }

/* The pulse: the plan above, the results as they land. */
.pulse .feed { border-top: 1px solid var(--line); }
.pulse .feed .row { display: flex; gap: .6rem; padding: .28rem 0; border-bottom: 1px solid var(--line); align-items: baseline; font-size: 13px; }
.pulse .feed .row .what { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pulse #upcoming td.num { width: 3.2rem; }

/* The pulse tape: planned checks drift in from the right, cross the
   now-line, light up as their result lands. */
.pad { padding: 1.1rem 1.4rem; }
.tape { position: relative; height: 104px; overflow: hidden; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; margin-bottom: 1rem; }
#tapetrack { position: absolute; inset: 0; will-change: transform; }
/* The bar is the middle, everywhere: it is where a tick stops and
   waits for its answer, and the code puts it at half the width. */
.tape .now-line { position: absolute; left: 50%; top: 0; bottom: 0; width: 2px; background: var(--act); opacity: .65; z-index: 2; }
.tape .tape-legend { position: absolute; right: .6rem; bottom: .25rem; font-size: 11px; z-index: 2; }
.chip { cursor: pointer; position: absolute; padding: .06rem .4rem; border-radius: 4px; font-family: var(--mono); font-size: 11px; background: var(--panel-3); border: 1px solid var(--line); color: var(--ink-2); white-space: nowrap; max-width: 220px; overflow: hidden; text-overflow: ellipsis; }
.chip.ghost { opacity: .4; border-style: dashed; }
.chip.ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
.chip.down { color: var(--red); border-color: color-mix(in srgb, var(--red) 55%, transparent); background: color-mix(in srgb, var(--red) 14%, transparent); }
.chip.warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 50%, transparent); }

/* A parent's caret unfolds its subdomains. */
table.sites .caret { background: none; border: 1px solid var(--line); color: var(--mute); border-radius: 4px; font-size: 10px; margin-left: .45rem; cursor: pointer; padding: 0 .3rem; line-height: 1.5; }
table.sites .caret.open { color: var(--act); border-color: var(--act); }

/* The settings form on the policy page. */
form.settings input.short { width: 6.5rem; }
form.settings .tune { display: flex; flex-wrap: wrap; gap: .9rem 1.4rem; align-items: end; margin: .9rem 0; }
form.settings .tune label { display: flex; flex-direction: column; gap: .25rem; font-size: 13px; color: var(--ink-2); }

/* The activity tape v2: full height on /activity, a strip on the
   overview; the now-line in the middle; a label per lane. */
.tape.full { height: calc(100vh - 240px); min-height: 380px; }
.tape { background-image: repeating-linear-gradient(90deg, color-mix(in srgb, var(--line) 55%, transparent) 0 1px, transparent 1px 100%); background-position: 0 0; }
.tape.home { height: 192px; margin-bottom: 1.2rem; }
.tape .now-line { left: 50%; }
.tape .lanelbl { position: absolute; left: .6rem; font-size: 11px; z-index: 2; font-family: var(--mono); }
.chip { max-width: none; }

/* Status filter buttons: pressed = shown, the colours are the statuses'. */
.fbtns { display: inline-flex; gap: .35rem; }
/* A filter button wears its own colour from the start, faded, and
   comes up to full strength when it is pressed: the reader sees what
   each one means before clicking it (Robin, 2026-08-27). */
.fbtns .fb { background: none; border: 1px solid var(--line); border-radius: 999px; padding: .15rem .75rem; font-size: 12px; color: var(--mute); cursor: pointer; opacity: .62; transition: opacity .12s ease, background-color .12s ease; }
.fbtns .fb:hover { opacity: .85; }
.fbtns .fb.on { opacity: 1; font-weight: 600; }
.fbtns .fb.down { color: var(--red); border-color: color-mix(in srgb, var(--red) 45%, transparent); }
.fbtns .fb.warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 45%, transparent); }
.fbtns .fb.ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
.fbtns .fb.maint { color: var(--act); border-color: color-mix(in srgb, var(--act) 45%, transparent); }
/* A number field holds three digits, not a sentence — and what can be
   filled can be emptied. */
.clearable { position: relative; display: inline-flex; align-items: center; }
.clearable input.ms { width: 5.2rem; padding-right: 1.4rem; }
.clearbtn { position: absolute; right: .15rem; background: none; border: 0; color: var(--mute); cursor: pointer; font-size: 11px; line-height: 1; padding: .15rem .25rem; }
.clearbtn:hover { color: var(--ink); }
.nowrap { white-space: nowrap; }
/* The four figures a machine carries on its own line. */
/* Each figure with its own name above it, and room between them: four
   numbers in a row with no labels is a number soup, whoever is
   reading (Robin, 2026-08-28). */
.hostblock summary .vitals { display: inline-flex; gap: 1rem; margin: 0 .3rem; vertical-align: middle; }
.vitals .v { display: inline-flex; flex-direction: column; line-height: 1.15; }
.vitals .v i { font-style: normal; font-size: 9.5px; text-transform: uppercase; letter-spacing: .07em; color: var(--mute); }
.vitals .v b { font-family: var(--mono); font-size: 12.5px; font-weight: 600; color: var(--ink); }
.vitals .v u { text-decoration: none; font-family: var(--mono); font-size: 10.5px; color: var(--mute); margin-top: -1px; }
.hostblock summary .services { display: inline-flex; gap: .25rem; flex-wrap: wrap; margin-left: .4rem; }
#foldall { margin-left: .3rem; }
.fbtns .fb.mute { color: var(--ink-2); }
/* Every status the mapping knows has its chip in its own colour —
   nothing falls back to grey for want of a rule. */
.fbtns .fb.ext { color: var(--ext); border-color: color-mix(in srgb, var(--ext) 45%, transparent); }
.fbtns .fb.unknown { color: var(--unknown); border-color: color-mix(in srgb, var(--unknown) 45%, transparent); }
.fbtns .fb.on.down, .fbtns .fb.down:hover { color: var(--red); border-color: color-mix(in srgb, var(--red) 55%, transparent); }
.fbtns .fb.on.down { background: color-mix(in srgb, var(--red) 14%, transparent); }
.fbtns .fb.on.warn, .fbtns .fb.warn:hover { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 55%, transparent); }
.fbtns .fb.on.warn { background: color-mix(in srgb, var(--warn) 12%, transparent); }
.fbtns .fb.on.ok, .fbtns .fb.ok:hover { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 50%, transparent); }
.fbtns .fb.on.ok { background: color-mix(in srgb, var(--ok) 12%, transparent); }
.fbtns .fb.on.maint, .fbtns .fb.maint:hover { color: var(--act); border-color: color-mix(in srgb, var(--act) 50%, transparent); }
.fbtns .fb.on.maint { background: color-mix(in srgb, var(--act) 12%, transparent); }
.fbtns .fb.on.mute { color: var(--ink-2); border-color: var(--ink-2); background: color-mix(in srgb, var(--ink-2) 10%, transparent); }

/* A host's services, one pill each, right on the overview. */
.hostblock .services { display: flex; flex-wrap: wrap; gap: .35rem; padding: .5rem .9rem .2rem; }
.hostblock .services .svc { border: 1px solid var(--line); border-radius: 5px; padding: .12rem .55rem; font-size: 12px; color: var(--ink-2); text-decoration: none; }
.hostblock .services .svc.ok { border-color: color-mix(in srgb, var(--ok) 35%, transparent); }
.hostblock .services .svc.ok:hover { border-color: var(--ok); }
.hostblock .services .svc.down { color: var(--red); border-color: color-mix(in srgb, var(--red) 55%, transparent); background: color-mix(in srgb, var(--red) 12%, transparent); }
.hostblock .services .svc.warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 55%, transparent); }

/* A tick still unresolved at the LEFT edge pins there: the jam is the delay. */
.chip.pending { border-color: var(--act); border-style: solid; opacity: .9; z-index: 3; }
/* The bar reveals: a soft landing pulse. */
.chip.landed { animation: land .45s ease-out; }
@keyframes land { from { box-shadow: 0 0 0 6px color-mix(in srgb, var(--act) 25%, transparent); } to { box-shadow: none; } }
/* Soft separators between lanes; the labels sit in their own box. */
.tape .lanesep { position: absolute; left: 0; right: 0; height: 1px; background: linear-gradient(90deg, transparent, var(--line) 15%, var(--line) 85%, transparent); opacity: .5; }
.tape .lanelbl { background: var(--panel); border: 1px solid var(--line); border-radius: 5px; padding: .05rem .45rem; z-index: 4; }

/* The tape's own settings: speed and effects, the user's. */
.tape .tape-gear { position: absolute; right: .5rem; top: .35rem; z-index: 5; }
.tape .tape-gear summary { list-style: none; cursor: pointer; color: var(--mute); border: 1px solid var(--line); border-radius: 5px; padding: 0 .4rem; background: var(--panel); }
.tape .tape-gear summary:hover { color: var(--ink); }
.tape .tape-gear .menu { position: absolute; right: 0; top: 100%; margin-top: .3rem; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: .55rem .8rem; display: flex; flex-direction: column; gap: .4rem; white-space: nowrap; box-shadow: 0 8px 24px rgba(0,0,0,.35); font-size: 12.5px; }
.tape.no-fx .chip.landed { animation: none; }


.tape-gear .paceset, .tape-gear .modeset { display: inline-flex; gap: .3rem; }
.tape-gear .modeset button { background: none; border: 1px solid var(--line); border-radius: 999px; padding: .1rem .6rem; font-size: 12px; color: var(--mute); cursor: pointer; }
.tape-gear .modeset button.on { color: var(--act); border-color: var(--act); }
.tape-gear .paceset button { background: none; border: 1px solid var(--line); border-radius: 999px; padding: .1rem .6rem; font-size: 12px; color: var(--mute); cursor: pointer; }
.tape-gear .paceset button.on { color: var(--act); border-color: var(--act); }

/* A tick with no journey to make appears in place, softly. */
.chip.fade { animation: chipfade .3s ease-out; }
@keyframes chipfade { from { opacity: 0; } to { opacity: 1; } }

/* The host page: service tiles, the machine card, the metric charts. */
.cards.svc { margin: .2rem 0 .4rem; }
a.card { color: var(--ink); cursor: pointer; }
a.card:hover { border-color: var(--act); }
.card.unknown .num { color: var(--mute); }
.machine .gauges { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: .55rem 1.1rem; margin-top: .3rem; }
.gauge .lbl { font-size: 12px; color: var(--mute); display: block; margin-bottom: .2rem; }
.gauge .lbl b { color: var(--ink); font-weight: 600; }
.gauge .bar { display: block; position: relative; height: 7px; background: var(--panel-3); border-radius: 4px; overflow: hidden; }
.gauge .bar i { position: absolute; left: 0; top: 0; bottom: 0; background: var(--act); border-radius: 4px; }
.gauge .bar.warn i { background: var(--warn); }
.gauge .bar.down i { background: var(--red); }
/* Stacked, never side by side: one shared time axis to correlate
   (Robin, 2026-08-25). */
.machine .mgrid { display: grid; grid-template-columns: 1fr; gap: .3rem; }
.mchart h3 { margin: .3rem 0 .1rem; font-size: 11.5px; text-transform: uppercase; letter-spacing: .07em; color: var(--mute); }
.mchart .mgraph { height: 130px; }
.mchart .k { font-size: 11px; text-transform: none; letter-spacing: 0; margin-left: .5rem; }
.mchart .k::before { content: ""; display: inline-block; width: 12px; height: 3px; margin-right: .25rem; vertical-align: middle; }
.graph .rx { stroke: var(--chart); stroke-width: 1.6; }
.graph .tx { stroke: var(--warn); stroke-width: 1.6; }

/* Hierarchy on the tiles: the label reads first, the value is the
   news; the ping is the base and stands out. */
.tile { gap: .15rem; }
.tile .lbl { display: flex; align-items: center; gap: .35rem; }
.tile.feat { grid-column: span 2; }
.tile.feat .num { font-size: 34px; }
.mstats { margin-left: .6rem; font-family: var(--mono); font-size: 11px; text-transform: none; letter-spacing: 0; color: var(--mute); }
.mstats b { color: var(--ink); font-weight: 650; }
.graph .sel rect { fill: color-mix(in srgb, var(--act) 18%, transparent); stroke: var(--act); stroke-width: 1; }
.mgraph { cursor: crosshair; }
.users .utable td { vertical-align: middle; }
.users .utable .lbl { display: block; font-size: 11.5px; margin-bottom: .15rem; }
.users .utable .bar { display: block; max-width: 280px; position: relative; height: 6px; background: var(--panel-3); border-radius: 4px; overflow: hidden; }
.users .utable .bar i { position: absolute; left: 0; top: 0; bottom: 0; background: var(--act); border-radius: 4px; }

/* Legend chips mask their series; each user has a colour. */
.k.off, .ku.off { opacity: .4; text-decoration: line-through; }
.legend .k[data-sk], .mchart .k { user-select: none; }
.mchart .ku { font-family: var(--mono); margin-right: .55rem; }
/* The per-user legend: a machine has hundreds of accounts, so the list
   folds, searches, and says which site each login serves (Robin,
   2026-08-26 — "ça devient illisible de fou"). */
.uleg .uhead { display: flex; align-items: center; gap: .5rem; margin-bottom: .3rem; }
.uleg .usearch {
  font: inherit; font-family: var(--mono); padding: .1rem .4rem; width: 14rem; max-width: 45%;
  border: 1px solid var(--line); border-radius: var(--r); background: var(--ground); color: var(--ink);
}
.uleg .usearch:focus { outline: none; border-color: var(--act); }
.uleg .ucount { white-space: nowrap; }
.uleg .ufold { cursor: pointer; white-space: nowrap; }
.uleg .ulist { max-height: 9rem; overflow-y: auto; line-height: 1.7; }
/* The three-way switch over the accounts: show them all, only the
   active ones, or only those that used something (Robin, 2026-08-26). */
/* Two readings on a host's line: what the machine serves, and what
   the sites are doing. Separated so the eye does not mix them. */
#tree summary .group + .group::before { content: "|"; opacity: .35; margin: 0 .45rem 0 .25rem; }
/* The ticks that say what a channel carries. */
.carries { border: 1px solid var(--line); border-radius: var(--r); padding: .5rem .7rem; margin: .2rem 0; }
.carries .hint { margin: 0 0 .2rem; }
.carries legend { padding: 0 .3rem; color: var(--mute); font-size: 12.5px; }
.carries .ticks { display: flex; flex-wrap: wrap; align-items: center; gap: .2rem .1rem; margin: .35rem 0; color: var(--mute); font-size: 12.5px; }
.carries .tick { display: inline-flex; align-items: center; gap: .3rem; margin-left: .8rem; white-space: nowrap; color: var(--ink); }
.carries .tick input { margin: 0; }
/* What is ticked and what is merely possible must not read the same:
   a group ruled out by an "all" or by a mode is dimmed, not hidden —
   the reader still sees what they could choose. */
.tick.off, .ticks.off { opacity: .45; }
.alertform { align-items: flex-end; gap: .7rem; flex-wrap: wrap; }
.alertform fieldset { border: 1px solid var(--line); border-radius: var(--r); padding: .35rem .7rem; margin: 0; }
.alertform fieldset legend { padding: 0 .3rem; color: var(--mute); font-size: 12px; }
.alertform .importance .ticks { gap: .1rem .8rem; align-items: flex-end; }
.alertform .importance .urow { margin: 0; font-size: 12px; }
.alertform .importance select { font-size: 12px; }
.alertform .ticks { display: inline-flex; flex-wrap: wrap; align-items: center; gap: .1rem; font-size: 12.5px; }
.alertform .chanpick { margin-left: .8rem; padding-left: .8rem; border-left: 1px solid var(--line); }
/* A form's buttons belong on one line: what it does and the way out
   of it. */
.formacts { display: flex; gap: .5rem; align-items: center; }
/* How loud each thing is on a channel: a row per kind of news, side
   by side so the whole scale is read at once. */
.urgency .rows { display: grid; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); gap: .45rem .9rem; margin-top: .35rem; }
.urgency .urow { margin: 0; color: var(--ink); font-size: 12.5px; }
.urgency .urow select { font-size: 12.5px; }
/* A channel's buttons stay on one line rather than wrapping under the
   name of the next one. */
.list td.acts { white-space: nowrap; }
.list td.acts button { margin-right: .25rem; }
.ownerfold { border: 0; background: none; color: var(--mute); cursor: pointer; font: inherit; padding: 0 .25rem 0 0; }
.ownerfold:hover { color: var(--ink); }
/* A list of open incidents is a list, not a page: it scrolls in place
   rather than pushing everything below out of reach (Robin,
   2026-08-26: "c'est devenu scroll simulator"). */
.alerts.scrollable { max-height: 15rem; overflow-y: auto; padding-right: .3rem; }
.secthead { margin-top: 1.1rem; }
/* A site that points away from us: watched in case it comes back,
   never alarming, and never confused with a failure (Robin,
   2026-08-26). */
.tag.ext { color: var(--ext); border-color: color-mix(in srgb, var(--ext) 45%, transparent); background: color-mix(in srgb, var(--ext) 14%, transparent); }
.dot.ext { background: var(--ext); }
.card.ext { border-left-color: var(--ext); }
.card.ext .num { color: var(--ext); }
.svc.ext { border-color: var(--ext); }
.c-ext { color: var(--maint); }
/* What a site's records could be doing better: said, never raised. */
.notices { margin: .6rem 0 0; }
.notices p { margin: .15rem 0; }
/* The site cards over a host's list: smaller than the headline cards,
   and the one in force is marked. */
.sitecards { margin-top: .2rem; }
.sitecards .card { cursor: pointer; }
.sitecards .card.picked { outline: 2px solid var(--act); outline-offset: -2px; }
.uleg .useg { display: inline-flex; border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.uleg .useg button {
  font: inherit; font-size: .82rem; padding: .05rem .45rem; border: 0; border-right: 1px solid var(--line);
  background: var(--ground); color: var(--mute); cursor: pointer;
}
.uleg .useg button:last-child { border-right: 0; }
.uleg .useg button.on { background: var(--panel-2, var(--panel)); color: var(--ink); font-weight: 600; }

.graph .uall { stroke: var(--ink); stroke-width: 2; opacity: .85; }
.graph .uall.band { fill: var(--ink); opacity: .12; stroke: none; }
.uleg .ku .usite { opacity: .65; color: inherit; text-decoration: none; }
.uleg .ku .usite:hover { opacity: 1; text-decoration: underline; }
.uleg .ku.off .usite { opacity: .45; }
.mchart .ku::before { content: ""; display: inline-block; width: 12px; height: 3px; margin-right: .3rem; vertical-align: middle; }
.graph .u0 { stroke: var(--chart); }
.graph .u1 { stroke: var(--chart-2); }
.graph .u2 { stroke: var(--warn); }
.graph .u3 { stroke: #c678dd; }
.graph .u4 { stroke: #56b6c2; }
.graph .u5 { stroke: var(--red); }
.graph .u6 { stroke: #d19a66; }
.graph .u7 { stroke: var(--mute); }

/* Legends live under their graph. */
.mchart .legend, .mchart .uleg { margin: .15rem 0 .5rem; display: flex; flex-wrap: wrap; gap: .2rem .9rem; align-items: center; }
.mchart .uleg { font-size: 11.5px; }

/* The three loads, three colours — every sysadmin reads them together. */


/* A hidden field is hidden, whatever a layout rule says. */
[hidden] { display: none !important; }

/* The machine's dials: CPU and memory read as a needle, the rest as a
   number over the last five minutes — a bar said too little (Robin,
   2026-08-26). Disk space is not a headline any more: it lives under
   the disk chart. */
.machine .dial { width: 100%; max-width: 148px; height: 74px; display: block; margin: .05rem 0 0; }
.dial .track { fill: none; stroke: var(--panel-3); stroke-width: 9; stroke-linecap: round; }
.dial .fill { fill: none; stroke-width: 9; stroke-linecap: round; }
.dial .fill.ok { stroke: var(--chart); } .dial .fill.warn { stroke: var(--warn); } .dial .fill.down { stroke: var(--red); }
/* Two directions on one dial: what comes in outside, what goes out
   inside — a link saturates either way (Robin, 2026-08-26). */
.dial .fill.dir { stroke-width: 5; }
.dial .fill.dir.up { stroke: var(--chart); }
.dial .fill.dir.dn { stroke: var(--red); }
.dial .fill.dir.dl { stroke: var(--chart-2); }
.dial .tick { stroke: var(--line-2); stroke-width: 1.5; }
.dial .needle { stroke: var(--ink); stroke-width: 2.5; stroke-linecap: round; }
/* The needle glides to its new value; it does not jump. */
.dial .needle-g { transition: transform .12s ease-out; }
@media (prefers-reduced-motion: reduce) { .dial .needle-g { transition: none; } }
.dial .needle.warn { stroke: var(--warn); } .dial .needle.down { stroke: var(--red); }
.dial .hub { fill: var(--ink); }
.dial .val { fill: var(--ink); font-family: var(--mono); font-size: 17px; font-weight: 700; }
.dial .val .pc { font-size: 12px; fill: var(--mute); }
.machine .sparkwrap { position: relative; width: 100%; margin-top: auto; }
.machine .spark { width: 100%; height: 30px; display: block; margin-top: .25rem; opacity: .95; cursor: crosshair; }
/* No declared link speed, no gauge: the rate draws itself instead,
   up for what comes in, down for what goes out (Robin, 2026-08-26). */
/* No link speed to measure against, so no gauge: the rate draws
   itself, what comes in above the line and what goes out below, and
   the block keeps the height of the ones beside it (Robin,
   2026-08-26). */
.machine .sparkwrap.big { width: 100%; }
.machine .sparkwrap.big .spark { height: 116px; }
.mstat .num.rates { display: flex; gap: .9rem; align-items: baseline; justify-content: center; font-size: 15px; }
.mstat .num.rates .in { color: var(--chart); }
.mstat .num.rates .out { color: var(--red); }
.spark .sc { fill: var(--mute); font-family: var(--mono); font-size: 8.5px; opacity: .8; }
.machine .sparkwrap .tip { font-size: 11px; }
.spark path { fill: none; stroke-width: 1.4; vector-effect: non-scaling-stroke; }
.spark .total { stroke: var(--chart); } .spark .rx { stroke: var(--chart); } .spark .tx { stroke: var(--warn); }
.spark .area { stroke: none; fill: color-mix(in srgb, var(--chart) 16%, transparent); }
.mstat .num.two { font-size: 15.5px; }
.mstat .sub { text-overflow: ellipsis; }

/* What the machine IS rides on the title line, after the badges; the
   status badge carries how long it has held (Robin, 2026-08-26). */
.head h1 .what { font-size: 12px; font-weight: 400; font-family: var(--mono); letter-spacing: 0; margin-left: .35rem; }
.mchart h3 .addrs { font-size: 10.5px; text-transform: none; letter-spacing: 0; margin-left: .4rem; }
.mstat .sub.spec { white-space: normal; line-height: 1.35; font-size: 10.5px; }

/* The three loads read by weight: one minute green, five blue,
   fifteen red — a high fifteen is the one that matters (Netdata's
   reading, Robin 2026-08-26). */
.graph .l1 { stroke: var(--chart); stroke-width: 1.6; }
.graph .l5 { stroke: var(--chart-2); stroke-width: 1.6; }
.graph .l15 { stroke: var(--red); stroke-width: 1.6; }

/* The thresholds a volume is judged on, drawn where they are. */
.graph .thr { stroke-dasharray: 3 4; stroke-width: 1; }
.graph .thr.warn { stroke: color-mix(in srgb, var(--warn) 70%, transparent); }
.graph .thr.down { stroke: color-mix(in srgb, var(--red) 70%, transparent); }
.mchart .mleg { font-size: 11.5px; }
/* Memory reads as bands: what processes hold, what the kernel keeps
   for them, what is free — and the line of what is really available.
   The swap in use hangs below the axis (Robin, 2026-08-26). */
.mchart.tall .mgraph { height: 190px; }
/* A stacked band is drawn in ITS OWN colour, not a faded one: a
   translucent fill takes the colour of whatever is behind it, so the
   swatch in the legend and the swatch in the tooltip never matched
   what the eye saw on the chart (Robin, 2026-08-28). One colour per
   thing, defined once, used by the band, the legend and the tooltip.
   The grid is drawn OVER the bands instead of under them, which is
   what the transparency was there to achieve. */
:root { --mem-used: #d98b3d; --mem-buf: #8b6cff; --mem-cache: #5c98ff; --mem-free: #5b6674; --mem-swap: #ff5252; --mem-avail: #59d38f; }
@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) { --mem-free: #b9c2cc; } }
:root[data-theme="light"] { --mem-free: #b9c2cc; }
/* A band is a TINT of its colour, a line is the colour itself.
   Opaque tint, not transparency: mixed with the panel rather than laid
   over whatever is behind, so the swatch in the legend is exactly what
   the eye sees — which is why the transparency had to go — while a
   line still reads over any band without needing an outline around it
   (Robin, 2026-08-28: the halo was ugly and was not the answer). */
.graph path.fill { fill: color-mix(in srgb, var(--sk, var(--chart)) 42%, var(--panel)); }
.legend .k.band::before { background: color-mix(in srgb, var(--sk, var(--chart)) 42%, var(--panel)); }
.graph path.boundary { stroke-width: 2.2; fill: none; }
.graph .m-avail { stroke: var(--mem-avail); stroke-width: 2.2; stroke-dasharray: 5 3; fill: none; }
.nowv .n.m-used { color: var(--orange); } .nowv .n.m-avail { color: var(--chart); }

/* The live control: one pace for the page, and a dot that pulses only
   when data came back (Robin, 2026-08-26 — the shape Shieldlist uses). */
.livegroup { display: inline-flex; align-items: center; gap: .4rem; margin-left: auto; }
.livegroup select { padding: .3rem .4rem; font-size: 12px; }
.livebtn { display: inline-flex; align-items: center; gap: .5rem; border-radius: 999px; padding: .32rem .9rem .32rem .6rem; font-size: 12.5px; border: 1px solid var(--line); background: var(--panel-2); color: var(--ink); cursor: pointer; }
.livebtn .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--mute); display: inline-block; }
.livebtn.on .dot { background: var(--ok); }
.livebtn .ic { width: 14px; text-align: center; font-size: 11px; color: var(--mute); }
.livebtn.on { border-color: color-mix(in srgb, var(--ok) 50%, transparent); }
.livebtn.on .dot.tick { animation: tick .45s ease-out; }
@keyframes tick {
  0% { transform: scale(1.8); box-shadow: 0 0 0 4px color-mix(in srgb, var(--ok) 50%, transparent); }
  100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) { .livebtn.on .dot.tick { animation: none; } }
@media (max-width: 900px) { .livegroup { order: 9; width: 100%; justify-content: flex-end; } }

/* Two subjects on one axis: what answers from outside, and what the
   machine does inside (Robin, 2026-08-26). */
.mgrid .grouphead { margin: 1.1rem 0 .3rem; padding-bottom: .3rem; border-bottom: 1px solid var(--line); font-size: 12px; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-2); }
.mgrid .grouphead:first-child { margin-top: .2rem; }
.mgrid .grouphead .dim { text-transform: none; letter-spacing: 0; font-size: 11.5px; margin-left: .4rem; }
/* A failure is a moment, not a line: amber while it is being
   confirmed, red once the incident is real. */
.graph .span { pointer-events: none; }
.graph .span.confirming { fill: color-mix(in srgb, var(--warn) 22%, transparent); }
.graph .span.down { fill: color-mix(in srgb, var(--red) 28%, transparent); }

/* Not yet asked again: the line carries on, dashed, to the edge. */
.graph .pending { fill: none; stroke-width: 1.4; stroke-dasharray: 3 4; opacity: .55; vector-effect: non-scaling-stroke; }

/* The lines of one subject: a port, a family, each its own colour. */
.graph .sl0 { stroke: var(--chart); } .nowv .n.sl0 { color: var(--chart); }
.graph .sl1 { stroke: var(--chart-2); } .nowv .n.sl1 { color: var(--chart-2); }
.graph .sl2 { stroke: #e5c07b; } .nowv .n.sl2 { color: #e5c07b; }
.graph .sl3 { stroke: #c678dd; } .nowv .n.sl3 { color: #c678dd; }
.graph .sl4 { stroke: #56b6c2; } .nowv .n.sl4 { color: #56b6c2; }
.graph .sl5 { stroke: #ff79c6; } .nowv .n.sl5 { color: #ff79c6; }
.graph .sl6 { stroke: #d19a66; } .nowv .n.sl6 { color: #d19a66; }
.graph .sl7 { stroke: #8be9fd; } .nowv .n.sl7 { color: #8be9fd; }
.graph [class^="sl"], .graph [class*=" sl"] { stroke-width: 1.6; fill: none; }
.graph .band[class*="sl"] { stroke: none; fill: color-mix(in srgb, var(--chart) 16%, transparent); }
.mchart .svcleg { font-size: 11.5px; }

/* The two roads of one service: v4 and v6 on the same chart. */
.graph .f4 { stroke: var(--chart); stroke-width: 1.8; fill: none; }
.graph .f6 { stroke: var(--chart-2); stroke-width: 1.8; fill: none; }
.graph .band.f4 { fill: color-mix(in srgb, var(--chart) 18%, transparent); stroke: none; }
.graph .band.f6 { fill: color-mix(in srgb, var(--chart-2) 18%, transparent); stroke: none; }
.nowv .n.f4 { color: var(--chart); } .nowv .n.f6 { color: var(--chart-2); }

/* A service's chart: its answer, and where it failed. */
.nowv .n.svcdown { color: var(--red); }
.mchart h3 a.plain { color: inherit; text-decoration: none; }
.mchart h3 a.plain:hover { color: var(--act); }

/* The value now, beside the title, in the series' colour. */
.mchart h3 .nowv { margin-left: .6rem; font-family: var(--mono); font-size: 13px; letter-spacing: 0; text-transform: none; }
.mchart h3 .nowv .n { font-weight: 700; margin-right: .5rem; }
.nowv .n.total, .nowv .n.up { color: var(--chart); } .nowv .n.l5 { color: var(--chart-2); }
.nowv .n.tx { color: var(--warn); } .nowv .n.dn, .nowv .n.l15 { color: var(--red); }
.nowv .n.l1 { color: var(--ok); }
/* The thresholds are named in the legend, not left as two dashes. */
.k.thrk::before { content: ""; display: inline-block; width: 12px; height: 0; border-top: 2px dashed var(--warn); margin-right: .3rem; vertical-align: middle; }
.k.thrk.down::before { border-top-color: var(--red); }

/* A rate is a bar from the middle line: what arrives goes up in blue,
   what leaves goes down in red — the side says the direction, the
   colour repeats it (Robin, 2026-08-26). */
.graph .fill { stroke: none; }
.graph .fill.up { fill: color-mix(in srgb, var(--chart) 62%, transparent); }
.graph .fill.dn { fill: color-mix(in srgb, var(--red) 62%, transparent); }
.graph .fill.dl { fill: color-mix(in srgb, var(--chart-2) 62%, transparent); }
.graph .fill.peak.dl { fill: color-mix(in srgb, var(--chart-2) 26%, transparent); }
.graph .fill.peak.up { fill: color-mix(in srgb, var(--chart) 26%, transparent); }
.graph .fill.peak.dn { fill: color-mix(in srgb, var(--red) 26%, transparent); }
.spark .up { stroke: var(--chart); } .spark .dn { stroke: var(--red); } .spark .dl { stroke: var(--chart-2); }
.spark .area.up { fill: color-mix(in srgb, var(--chart) 30%, transparent); }
.spark .area.dn { fill: color-mix(in srgb, var(--red) 30%, transparent); }

/* One window for every chart: the range chips sit in the title, the
   axis is shared, dragging moves in time. */
.machine .tranges { display: inline-flex; gap: .25rem; flex-wrap: wrap; margin-left: .4rem; }
.machine .tranges button { background: none; border: 1px solid var(--line); border-radius: 999px; padding: .05rem .5rem; font-size: 11.5px; color: var(--mute); cursor: pointer; }
.machine .tranges button.on { color: var(--act); border-color: var(--act); }
.machine .tranges .treset { color: var(--warn); border-color: var(--warn); }
/* The gestures belong between the instruments and the charts, on
   their own line, spaced — not dropped like a hair in the soup
   (Robin, 2026-08-26). */
.machine .navhint { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: .15rem 1.4rem; margin: .9rem 0 .1rem; padding-top: .5rem; border-top: 1px solid var(--line); font-size: 10.5px; letter-spacing: .02em; }
.mgraph { cursor: grab; }
.mgraph.grabbing { cursor: grabbing; }
.mchart .spec { margin: .05rem 0 .55rem; font-size: 11px; }

/* The volumes, under the disk chart where they belong. */

/* The machine reads as stat blocks: label, the number, the context,
   the bar — not a list of sentences. */
.machinegrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: .45rem 1rem; margin-top: .35rem; align-items: stretch; }
.mstat { display: flex; flex-direction: column; align-items: center; text-align: center; gap: .12rem; min-width: 0; }
/* Every block's sparkline sits on the same line, dial or number. */
.mstat .sparkwrap { margin-top: auto; }
.mstat .lbl { font-size: 12.5px; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mstat .num { font-size: 17px; font-weight: 700; font-family: var(--mono); line-height: 1.15; color: var(--ink); white-space: nowrap; }
.mstat .sub { font-size: 11.5px; color: var(--mute); font-family: var(--mono); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mstat .bar { display: block; width: 100%; position: relative; height: 6px; background: var(--panel-3); border-radius: 4px; overflow: hidden; margin-top: .15rem; }
.mstat .bar i { position: absolute; left: 0; top: 0; bottom: 0; background: var(--act); border-radius: 4px; }
.mstat .bar.warn i { background: var(--warn); }
.mstat .bar.down i { background: var(--red); }



/* The tooltip names its series in colour. */
.tip .tipk { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: .4rem; }

/* Sixteen user colours — system users are many. */
.graph .u8 { stroke: #61afef; }
.graph .u9 { stroke: #98c379; }
.graph .u10 { stroke: #e5c07b; }
.graph .u11 { stroke: #ff79c6; }
.graph .u12 { stroke: #8be9fd; }
.graph .u13 { stroke: #bd93f9; }
.graph .u14 { stroke: #ffb86c; }
.graph .u15 { stroke: #7f848e; }
.ku.more { border: 1px dashed var(--line-2); border-radius: 999px; padding: 0 .45rem; }
.ku.more::before { display: none; }
.ku.more.on { border-color: var(--act); color: var(--ink); }


/* ————— one token per series —————
   A series has ONE colour, written once here, and everything that
   shows that series reads it: the swatch under the chart, the name
   beside the swatch, the swatch in the tooltip and the name in the
   tooltip. They used to be declared separately, three or four times
   each, which is why colouring the names reached some and not others
   (Robin, 2026-08-28). Adding a series is now one line. */
.k.total, .tipk.total, .tipn.total, .graph .total { --sk: var(--chart); }
.k.ttfb, .tipk.ttfb, .tipn.ttfb, .graph .ttfb { --sk: var(--act-2); }
.k.rtt, .tipk.rtt, .tipn.rtt, .graph .rtt { --sk: var(--warn); }
.k.warm, .tipk.warm, .tipn.warm, .graph .warm { --sk: var(--ok); }
.k.rx, .tipk.rx, .tipn.rx, .graph .rx { --sk: var(--chart); }
.k.tx, .tipk.tx, .tipn.tx, .graph .tx { --sk: var(--warn); }
.k.up, .tipk.up, .tipn.up, .graph .up { --sk: var(--chart); }
.k.dn, .tipk.dn, .tipn.dn, .graph .dn { --sk: var(--red); }
.k.dl, .tipk.dl, .tipn.dl, .graph .dl { --sk: var(--chart-2); }
.k.l1, .tipk.l1, .tipn.l1, .graph .l1 { --sk: var(--chart); }
.k.l5, .tipk.l5, .tipn.l5, .graph .l5 { --sk: var(--chart-2); }
.k.l15, .tipk.l15, .tipn.l15, .graph .l15 { --sk: var(--red); }
.k.f4, .tipk.f4, .tipn.f4, .graph .f4 { --sk: var(--chart); }
.k.f6, .tipk.f6, .tipn.f6, .graph .f6 { --sk: var(--chart-2); }
.k.svcdown, .tipk.svcdown, .tipn.svcdown, .graph .svcdown { --sk: var(--red); }
.k.peermed, .tipk.peermed, .tipn.peermed, .graph .peermed { --sk: var(--chart-2); }
.k.peerband, .tipk.peerband, .tipn.peerband, .graph .peerband { --sk: var(--chart-2); }
.k.m-used, .tipk.m-used, .tipn.m-used, .graph .m-used { --sk: var(--mem-used); }
.k.m-buf, .tipk.m-buf, .tipn.m-buf, .graph .m-buf { --sk: var(--mem-buf); }
.k.m-cache, .tipk.m-cache, .tipn.m-cache, .graph .m-cache { --sk: var(--mem-cache); }
.k.m-free, .tipk.m-free, .tipn.m-free, .graph .m-free { --sk: var(--mem-free); }
.k.m-swap, .tipk.m-swap, .tipn.m-swap, .graph .m-swap { --sk: var(--mem-swap); }
.k.m-avail, .tipk.m-avail, .tipn.m-avail, .graph .m-avail { --sk: var(--mem-avail); }
.k.uall, .tipk.uall, .tipn.uall, .graph .uall, .k.utotal { --sk: var(--ink); }
/* The phases a response time is made of, stacked: connect, TLS, the
   server's own thinking, the transfer, and whatever the total holds
   that none of them claimed. */
.k.ph1, .tipk.ph1, .tipn.ph1, .graph .ph1 { --sk: var(--chart-2); }
.k.ph2, .tipk.ph2, .tipn.ph2, .graph .ph2 { --sk: var(--act-2); }
.k.ph3, .tipk.ph3, .tipn.ph3, .graph .ph3 { --sk: var(--chart); }
.k.ph4, .tipk.ph4, .tipn.ph4, .graph .ph4 { --sk: var(--warn); }
.k.ph5, .tipk.ph5, .tipn.ph5, .graph .ph5 { --sk: var(--unknown); }
.k.s0, .tipk.s0, .tipn.s0, .graph .s0 { --sk: var(--chart); }
.k.s1, .tipk.s1, .tipn.s1, .graph .s1 { --sk: var(--act); }
.k.s2, .tipk.s2, .tipn.s2, .graph .s2 { --sk: var(--act-2); }
.k.s3, .tipk.s3, .tipn.s3, .graph .s3 { --sk: var(--warn); }
.k.s4, .tipk.s4, .tipn.s4, .graph .s4 { --sk: var(--red); }
.k.s5, .tipk.s5, .tipn.s5, .graph .s5 { --sk: var(--chart-2); }
.k.s6, .tipk.s6, .tipn.s6, .graph .s6 { --sk: var(--ok); }
.k.s7, .tipk.s7, .tipn.s7, .graph .s7 { --sk: var(--act); }
.k.s8, .tipk.s8, .tipn.s8, .graph .s8 { --sk: var(--warn); }
.k.s9, .tipk.s9, .tipn.s9, .graph .s9 { --sk: var(--unknown); }
.k.sl0, .tipk.sl0, .tipn.sl0, .graph .sl0 { --sk: var(--chart); }
.k.sl1, .tipk.sl1, .tipn.sl1, .graph .sl1 { --sk: var(--chart-2); }
.k.sl2, .tipk.sl2, .tipn.sl2, .graph .sl2 { --sk: #e5c07b; }
.k.sl3, .tipk.sl3, .tipn.sl3, .graph .sl3 { --sk: #c678dd; }
.k.sl4, .tipk.sl4, .tipn.sl4, .graph .sl4 { --sk: #56b6c2; }
.k.sl5, .tipk.sl5, .tipn.sl5, .graph .sl5 { --sk: #ff79c6; }
.k.sl6, .tipk.sl6, .tipn.sl6, .graph .sl6 { --sk: #d19a66; }
.k.sl7, .tipk.sl7, .tipn.sl7, .graph .sl7 { --sk: #8be9fd; }
.k.u0, .tipk.u0, .tipn.u0, .graph .u0 { --sk: var(--chart); }
.k.u1, .tipk.u1, .tipn.u1, .graph .u1 { --sk: var(--chart-2); }
.k.u2, .tipk.u2, .tipn.u2, .graph .u2 { --sk: var(--warn); }
.k.u3, .tipk.u3, .tipn.u3, .graph .u3 { --sk: #c678dd; }
.k.u4, .tipk.u4, .tipn.u4, .graph .u4 { --sk: #56b6c2; }
.k.u5, .tipk.u5, .tipn.u5, .graph .u5 { --sk: var(--red); }
.k.u6, .tipk.u6, .tipn.u6, .graph .u6 { --sk: #d19a66; }
.k.u7, .tipk.u7, .tipn.u7, .graph .u7 { --sk: var(--mute); }
.k.u8, .tipk.u8, .tipn.u8, .graph .u8 { --sk: #61afef; }
.k.u9, .tipk.u9, .tipn.u9, .graph .u9 { --sk: #98c379; }
.k.u10, .tipk.u10, .tipn.u10, .graph .u10 { --sk: #e5c07b; }
.k.u11, .tipk.u11, .tipn.u11, .graph .u11 { --sk: #ff79c6; }
.k.u12, .tipk.u12, .tipn.u12, .graph .u12 { --sk: #8be9fd; }
.k.u13, .tipk.u13, .tipn.u13, .graph .u13 { --sk: #bd93f9; }
.k.u14, .tipk.u14, .tipn.u14, .graph .u14 { --sk: #ffb86c; }
.k.u15, .tipk.u15, .tipn.u15, .graph .u15 { --sk: #7f848e; }
.legend .k::before, .tip .tipk { background: var(--sk, var(--chart)); }
.legend .k, .tip .tipn { color: var(--sk, inherit); }
.tip .tipn { font-weight: 600; }
/* The way out to the site an account serves: a mark, not a second
   name on the line. */
.ku .usite { margin-left: .25rem; color: var(--mute); text-decoration: none; }
.ku .usite:hover { color: var(--act); }
/* A swatch that is a dashed rule, not a block, keeps its own shape. */
.k.thrk.down::before { border-top-color: var(--red); }
.legend .k.off { color: var(--mute); }

/* A login, a domain, a path: never shouted in capitals by a title's
   text-transform (Robin: the first letters take a capital, the names
   are written as they are). */
.mchart h3 .mono, .mchart h3 .name, .mchart h3 .dim { text-transform: none; letter-spacing: 0; }
.mchart h3 .dim { font-weight: 400; margin-left: .35rem; }

/* ————— one check, looked at closely (the monitor and site pages) —————
   The same frame and the same colours as the host page: a reader who
   learnt one chart has learnt them all. */
.tcharts .mchart.tall .mgraph { height: 220px; }
.tcharts .nav-help { margin: .1rem 0 .4rem; }
.tcharts .nav-help .tstate { margin-left: .6rem; color: var(--ink-2); }
.tcharts.picked .nav-help .tstate::before { content: "▸ "; }
/* The second family is the same measure on another road: same colour,
   dashed, so the eye pairs them instead of reading two subjects. */
.graph path.f6 { stroke-dasharray: 5 3; opacity: .85; }
.mchart .k.u0::before, .legend .k.u0::before { background: var(--chart); }
.mchart .k.uall::before, .legend .k.uall::before { background: var(--ink); }
.tcharts .legend .k[data-tsk] { cursor: pointer; }
.tcharts .legend .k.off { opacity: .45; text-decoration: line-through; }
.legend .k.sl1::before { background: var(--chart-2); }
.legend .k.sl2::before { background: #e5c07b; }

/* A host with no site matching the filter stays on the page, dimmed:
   the machine and its services are never hidden by a filter that is
   about sites (Robin, 2026-08-27). */
.hostblock.nomatch > summary { opacity: .55; }
.hostblock.nomatch > summary .sitecount::after { content: " — none matches the filter"; font-style: italic; }
.count .clearf { margin-left: .4rem; color: var(--act); text-decoration: none; }
.count .clearf:hover { text-decoration: underline; }

/* A row the filter left out. The owner fold uses [hidden]; the filter
   uses this: one property each, so neither can undo the other. */
tr.fout, .fout { display: none !important; }

/* The machine's other sites: a band from their median to their ninth
   decile, and the median itself dashed. The site's own line stays the
   only solid one, so the two are never read as the same kind of thing. */
/* The neighbours' average is a LINE now, not a filled band: the band
   ran from the median to the ninth decile, a phrase nobody outside
   statistics reads, and its spikes were noise (Robin, 2026-08-29). */
.graph .peerband { fill: none; stroke: var(--chart-2); stroke-dasharray: 4 3; opacity: .8; }
.graph .peermed { stroke: var(--chart-2); stroke-width: 1.4; stroke-dasharray: 5 3; fill: none; }
.legend .k.peermed::before { background: var(--chart-2); }
.legend .k.peerband::before { background: var(--chart-2); opacity: .8; }
.tcharts .legend .pstats { margin-left: auto; }

/* A section that folds: the whole title is the handle. */
.foldhead { cursor: pointer; user-select: none; }
.foldhead .foldbtn { background: none; border: 0; color: var(--mute); font-size: 13px; cursor: pointer; padding: 0 .35rem 0 0; }
.foldhead:hover .foldbtn { color: var(--ink); }
.foldhead a { cursor: pointer; }
.livegroup .blurbtn { width: 26px; padding: .28rem 0; text-align: center; font-size: 13px; line-height: 1; }

/* ————— a phone —————
   The same pages, read on a 390-pixel screen: two cards a row, tables
   that scroll inside their own box instead of pushing the page
   sideways, and the columns an admin can do without on the move
   (Robin, 2026-08-27). */
@media (max-width: 700px) {
  main { padding: .7rem; }
  .cards.compact { grid-template-columns: 1fr 1fr; }
  .card .num { font-size: 18px; }
  table.list, table.sites { display: block; overflow-x: auto; max-width: 100%; }
  table.list > tbody, table.sites > tbody, table.list > thead, table.sites > thead { display: table; width: 100%; }
  #tree .c-addr, #tree .c-since, #tree .c-detail { display: none; }
  .treebar { gap: .35rem; }
  .treebar #treefilter { min-width: 0; flex: 1 1 100%; }
  .head h1 { font-size: 19px; word-break: break-word; }
  .chart { padding: .5rem .6rem; }
  .legend { flex-wrap: wrap; gap: .3rem .7rem; }
  .tape { height: 128px; }
  .tape .chip { max-width: 150px; font-size: 10.5px; }
  /* An incident line stacks instead of holding four columns open. */
  .tl, .alerts .tl { grid-template-columns: auto 1fr; gap: .2rem .5rem; }
  .tl .when { grid-column: 1; }
  .tl .tag { justify-self: start; }
  .tl .what { grid-column: 1 / -1; }
  .alerts .tl > a[href^="/incidents"] { display: none; }
  .services { flex-wrap: wrap; }
  .cards { gap: .4rem; }
  .foot { padding: 0 .7rem; }
}

/* The wall, stacked: a tile whose list is long splits into columns
   rather than running off the bottom of the screen, and the whole
   thing uses the width it is given (Robin, 2026-08-27). */
.wallsect { font-size: 12px; text-transform: uppercase; letter-spacing: .09em; color: var(--ink-2); margin: 1.1rem 0 .4rem; }
.wallsect:first-of-type { margin-top: 0; }
.wall .tilerows { columns: 320px auto; column-gap: 1.2rem; }
.wall .tilerows .siterow { break-inside: avoid; }
.wall .tile.core { border-color: color-mix(in srgb, var(--red) 35%, var(--line)); }
.wall .tile.svc { border-color: color-mix(in srgb, var(--warn) 35%, var(--line)); }
/* In the popup the wall is a panel, not a page. */
.modalbody .wall { min-height: 0; padding: .2rem; background: none; }
.modalbody .wallhead .big { font-size: 22px; }
.modalbody .walltiles { grid-template-columns: 1fr; }
.modalbody .wall .tilerows { columns: auto; }
.wallpeek { font-size: 13px; padding: .25rem .5rem; }

/* A tick held at the bar is the check running: it waits there, and
   passes only once its answer has landed (Robin, 2026-08-27). */
/* Two lines, small: the name, then what it took. */
.chip { line-height: 1.15; }
.chip b { display: block; font-weight: 500; overflow: hidden; text-overflow: ellipsis; }
.chip i { display: block; font-style: normal; font-size: 9.5px; opacity: .65; }
.tape.full .chip { font-size: 12px; max-width: 240px; }
.tape.full .chip i { font-size: 10.5px; }
/* A check still to come must be visible against the belt, not a ghost
   the same colour as the background (Robin, 2026-08-27). */
.chip.ghost { border-style: dashed; border-color: var(--line-2); color: var(--ink-2); background: color-mix(in srgb, var(--panel-3) 60%, transparent); }
.chip.waiting { border-style: solid; border-color: color-mix(in srgb, var(--act) 70%, var(--line)); color: var(--ink); box-shadow: 0 0 0 2px color-mix(in srgb, var(--act) 18%, transparent); }
/* A lane too busy for labels draws ticks: nothing is dropped, a busy
   fleet simply looks busy. */
/* Bars: one belt-wide choice, never a chip that turns into one and
   back. A bar is a coloured mark, not a shrunken label. */
#tapetrack.bars .chip { width: 12px; max-width: 12px; padding: 0; overflow: hidden; height: 15px; border-radius: 3px; }
#tapetrack.bars .chip b, #tapetrack.bars .chip i { display: none; }
#tapetrack.bars .chip.landed.ok { background: var(--ok); border-color: var(--ok); }
#tapetrack.bars .chip.landed.down { background: var(--red); border-color: var(--red); }
#tapetrack.bars .chip.landed.warn { background: var(--warn); border-color: var(--warn); }
#tapetrack.bars .chip.landed.mute { background: var(--mute); border-color: var(--mute); }
#tapetrack.bars .chip.ghost { background: color-mix(in srgb, var(--ink) 14%, transparent); border-color: var(--line-2); }
/* Appearing anywhere but the right edge: fade in, never pop. */
.chip.appear { animation: chipin .45s ease-out; }
@keyframes chipin { from { opacity: 0; transform: translateX(10px); } to { opacity: 1; transform: none; } }

/* The lane's name sits over the belt: it needs its own ground, or a
   note passing behind it is unreadable. */
.tape .lanelbl { background: var(--panel); padding: 0 .3rem; border-radius: 4px; z-index: 3; }

/* What a check is actually saying, at the top of its own page. */
.reasonline { margin: .3rem 0 .5rem; padding: .35rem .6rem; border-radius: var(--r-s); font-family: var(--mono); font-size: 12.5px; background: var(--panel-2); border-left: 3px solid var(--line-2); }
.reasonline.down { border-left-color: var(--red); }
.reasonline.warn { border-left-color: var(--warn); }
.reasonline.ok { border-left-color: var(--ok); }

/* A packet on its way to the line already wears the answer it had last
   time, faintly; it turns solid when its own answer lands. An arriving
   unknown is then told apart from an established one at a glance
   (Robin, 2026-08-27). */
.chip.ghost.was-ok { border-color: color-mix(in srgb, var(--ok) 45%, var(--line)); background: color-mix(in srgb, var(--ok) 9%, transparent); color: var(--ink-2); }
.chip.ghost.was-down { border-color: color-mix(in srgb, var(--red) 45%, var(--line)); background: color-mix(in srgb, var(--red) 9%, transparent); color: var(--ink-2); }
.chip.ghost.was-warn { border-color: color-mix(in srgb, var(--warn) 45%, var(--line)); background: color-mix(in srgb, var(--warn) 9%, transparent); color: var(--ink-2); }
.chip.ghost.was-maint, .chip.ghost.was-mute { border-color: var(--line-2); }
/* Answered: solid, and saturated. */
.chip.landed { color: var(--ink); }
.chip.landed.ok { background: color-mix(in srgb, var(--ok) 26%, transparent); border-color: var(--ok); }
.chip.landed.down { background: color-mix(in srgb, var(--red) 30%, transparent); border-color: var(--red); }
.chip.landed.warn { background: color-mix(in srgb, var(--warn) 28%, transparent); border-color: var(--warn); }
/* And a state that CHANGED says so, once. */
.chip.changed { animation: chipchange 1.6s ease-out; }
@keyframes chipchange {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--ink) 55%, transparent); transform: scale(1.14); }
  35%  { box-shadow: 0 0 0 7px color-mix(in srgb, var(--ink) 0%, transparent); transform: scale(1); }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* Linear or logarithmic, the reader's choice, next to the legend. */
.logtoggle { margin-left: auto; font-size: 10.5px; padding: .05rem .4rem; border: 1px solid var(--line); border-radius: 999px; background: none; color: var(--mute); cursor: pointer; }
.logtoggle.on { color: var(--act); border-color: var(--act); }
/* Which road to read the check on: both together, or one alone. It
   sits at the right end of the legend, before the scale toggle. */
.famsel { margin-left: auto; display: inline-flex; gap: .2rem; }
.famsel + .logtoggle { margin-left: .35rem; }
.famsel button { font-size: 10.5px; padding: .05rem .4rem; border: 1px solid var(--line); border-radius: 999px; background: none; color: var(--mute); cursor: pointer; }
.famsel button.on { color: var(--act); border-color: var(--act); }

/* A reseller's customers are drawn under it, and their sites with
   them: at the same margin they read as peers (Robin, 2026-08-27). */
/* A reseller's customers sit under it, and the nesting must be
   visible without counting pixels (Robin, 2026-08-28: "l'indentation
   pour les clients des revendeurs n'est pas claire"). A rule down the
   left of the nested block says where it belongs; the padding alone
   did not. */
/* Every fault a domain has, each one a filter. They are small and
   quiet: the column is read when something is wrong, not stared at. */
/* The faults take the room they need and no more: what fits stays on
   the line, the rest folds behind a count the reader opens — a row
   that spilled its badges over the column beside it was unreadable
   (Robin, 2026-08-28). */
table.sites td.c-wrong { max-width: 20rem; overflow: hidden; }
table.sites td.c-wrong .probs { display: flex; flex-wrap: wrap; gap: .1rem .2rem; max-height: 1.35rem; overflow: hidden; }
table.sites td.c-wrong.open .probs { max-height: none; }
.probmore { background: none; border: 0; color: var(--mute); font-size: 10.5px; cursor: pointer; padding: 0 .2rem; white-space: nowrap; }
.probmore:hover { color: var(--act); }
#tree.no-notes .tag.prob.note { display: none; }
.tag.prob { font-size: 10.5px; padding: 0 .35rem; margin: 0 .2rem .1rem 0; display: inline-block; border-radius: var(--r-s); border: 1px solid var(--line); color: var(--ink-2); }
.tag.prob:hover { border-color: var(--act); color: var(--ink); }
.tag.prob.down { color: var(--red); border-color: color-mix(in srgb, var(--red) 40%, transparent); }
.tag.prob.warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 40%, transparent); }
.tag.prob.note { color: var(--mute); }
#tree.no-wrong .c-wrong { display: none; }
table.sites tr.owner.d1 td, table.sites tbody.d1 td.name { box-shadow: inset 2px 0 0 var(--line-2); }
table.sites tr.owner.d2 td, table.sites tbody.d2 td.name { box-shadow: inset 2px 0 0 var(--line-2), inset 1.4rem 0 0 -1.2rem var(--line-2); }
table.sites tr.owner.d1 td { padding-left: 2.2rem; }
table.sites tr.owner.d2 td { padding-left: 3.6rem; }
table.sites tr.owner.d1 .under, table.sites tr.owner.d2 .under { margin-right: .15rem; }
table.sites tbody.d1 td.name { padding-left: 2.6rem; }
table.sites tbody.d2 td.name { padding-left: 4rem; }
/* What an alias reaches, rather than what it owns. */
table.list tr.via td { opacity: .72; font-style: italic; }


/* the public status page */
.statuspage { max-width: 900px; margin: 0 auto; }
.statuspage .banner { display: flex; align-items: center; gap: .6rem; padding: .8rem 1rem; border-radius: var(--r); border: 1px solid var(--line); background: var(--panel); font-size: 16px; font-weight: 600; margin: .5rem 0 1.2rem; }
.statuspage .banner.ok { border-color: color-mix(in srgb, var(--ok) 40%, transparent); background: color-mix(in srgb, var(--ok) 10%, var(--panel)); }
.statuspage .banner.warn { border-color: color-mix(in srgb, var(--warn) 40%, transparent); background: color-mix(in srgb, var(--warn) 10%, var(--panel)); }
.statuspage .banner.down { border-color: color-mix(in srgb, var(--red) 40%, transparent); background: color-mix(in srgb, var(--red) 10%, var(--panel)); }
.statuspage .banner.maint { border-color: color-mix(in srgb, var(--maint) 40%, transparent); background: color-mix(in srgb, var(--maint) 10%, var(--panel)); }
.statuspage .comp { padding: .7rem 0; border-bottom: 1px solid var(--line); }
.statuspage .comprow { display: flex; align-items: center; gap: .6rem; margin-bottom: .35rem; }
.statuspage .clabel { font-weight: 600; flex: 1; }
.statuspage .cword { font-size: 13px; }
.statuspage .cavail { font-size: 13px; min-width: 9rem; text-align: right; }
.statuspage .c-ok { color: var(--ok); } .statuspage .c-warn { color: var(--warn); } .statuspage .c-down { color: var(--red); } .statuspage .c-maint { color: var(--maint); } .statuspage .c-unknown, .statuspage .c-ext { color: var(--mute); }
.daybar { display: flex; gap: 2px; }
.daybar i { flex: 1; height: 22px; border-radius: 2px; background: var(--panel-3); min-width: 0; }
.daybar i.ok { background: var(--ok); } .daybar i.warn { background: var(--warn); } .daybar i.down { background: var(--red); } .daybar i.maint { background: var(--maint); }
.daybar i.none { background: var(--panel-3); }
.pubwindows { margin-bottom: 1rem; }
.pubwin { padding: .6rem .9rem; border-radius: var(--r); border: 1px solid color-mix(in srgb, var(--maint) 40%, transparent); background: color-mix(in srgb, var(--maint) 8%, var(--panel)); margin-bottom: .5rem; }
.pubwin p, .pubinc p { margin: .3rem 0 0; }
.pubincidents h2 { margin-top: 1.4rem; }
.pubinc { padding: .6rem 0; border-bottom: 1px solid var(--line); }
.pubfoot { margin-top: 2rem; text-align: center; }
.statusform fieldset { border: 1px solid var(--line); border-radius: var(--r); padding: .4rem .8rem; }
.statusform fieldset legend { font-size: 12px; color: var(--mute); text-transform: uppercase; letter-spacing: .06em; }
.statusform .tick { display: inline-block; margin-right: 1rem; }
.statusform label.wide, .statusform fieldset { grid-column: 1 / -1; }
.statusform textarea { width: 100%; }


/* the save bar of a settings page, and the name server sets */
.savebar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 30; display: flex; justify-content: flex-end; align-items: center; gap: 1rem; padding: .6rem 1.2rem; background: var(--panel); border-top: 1px solid var(--line-2); box-shadow: var(--shadow); }
.savebar[hidden] { display: none; }
.nsedit .nsset { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; padding: .4rem 0; border-bottom: 1px solid var(--line); }
.nsedit .nsname { width: 9rem; }
.nsedit .chips { display: inline-flex; flex-wrap: wrap; gap: .3rem; align-items: center; flex: 1; }
.nsedit .tag .x { padding: 0 .2rem; margin-left: .2rem; line-height: 1; }

.statuspage details.compdet > summary { list-style: none; cursor: pointer; }
.statuspage details.compdet > summary::-webkit-details-marker { display: none; }
.statuspage .caret { font-size: 11px; margin-right: .4rem; transition: transform .15s; }
.statuspage details[open] .caret { transform: rotate(180deg); }
.statuspage .compmore { margin: .5rem 0 0 1.2rem; padding-left: .8rem; border-left: 2px solid var(--line); }
.statuspage .sub { display: flex; align-items: center; gap: .5rem; padding: .2rem 0; font-size: 13px; }
.statuspage .slabel { flex: 1; }
.statuspage .subgrid { display: flex; flex-wrap: wrap; gap: .3rem .9rem; padding: .3rem 0; font-size: 12.5px; }
.statuspage .adminlink { margin-left: .5rem; font-weight: 400; }

.copy, .openlink { padding: 0 .3rem; margin-left: .15rem; font-size: 12px; line-height: 1.2; vertical-align: baseline; color: var(--mute); }
.copy:hover, .openlink:hover { color: var(--ink); }

.head2 .headcols { display: grid; grid-template-columns: 1.4fr 1fr; gap: .4rem 1.5rem; margin: .3rem 0 .2rem; }
.head2 .headcol p { margin: .15rem 0; }
.head2 .reasonline { margin-top: 0; }
@media (max-width: 800px) { .head2 .headcols { grid-template-columns: 1fr; } }
.sites .copy { opacity: 0; }
.sites tr:hover .copy, .sites .copy:focus { opacity: 1; }

.statuspage .sectitle { display: flex; align-items: center; gap: .5rem; margin: 1.4rem 0 .2rem; }
.statuspage .secdesc { margin: 0 0 .4rem; }
.statuspage .subhead { margin: .5rem 0 .1rem; font-size: 11px; text-transform: uppercase; letter-spacing: .06em; }
.statuspage .sub { display: block; padding: .25rem 0; }
.statuspage .sub .daybar.small { margin-top: 3px; }
.statuspage .subrow { display: flex; align-items: center; gap: .5rem; font-size: 13px; }
.statuspage .daybar.small i { height: 10px; }
.statuspage .cnote { font-weight: 400; margin-left: .4rem; }
.layout .lsection { border: 1px solid var(--line); border-radius: var(--r); padding: .5rem .7rem; margin: .5rem 0; background: var(--panel); }
.layout .lhead { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; margin-bottom: .3rem; }
.layout .ltitle { width: 14rem; font-weight: 600; }
.layout .ldesc { flex: 1; min-width: 12rem; }
.layout .litem { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; padding: .25rem 0; border-top: 1px solid var(--line); }
.layout .lname { min-width: 9rem; }
.layout .llabel, .layout .lnote { flex: 1; min-width: 9rem; }
.layout .ladd { display: flex; gap: .4rem; align-items: center; padding-top: .4rem; border-top: 1px dashed var(--line); margin-top: .2rem; }

.pubchartbox { margin: .4rem 0 .2rem; }
.pubchart { width: 100%; height: 90px; display: block; }
.pubchart .line { fill: none; stroke: var(--chart); stroke-width: 1.6; vector-effect: non-scaling-stroke; }
.pubchart .axis { stroke: var(--line-2); stroke-width: 1; vector-effect: non-scaling-stroke; }
.pubchart .grid { stroke: var(--line); stroke-width: 1; stroke-dasharray: 3 3; vector-effect: non-scaling-stroke; }
.pubchart text { font-family: var(--mono); font-size: 10px; fill: var(--mute); }
.layout .lopts { padding: .2rem 0 .4rem 1.5rem; font-size: 12.5px; }
.layout .lopts .tick { margin-right: .8rem; }
.layout .lopts2 { margin-top: .2rem; }

.openinc { margin: .4rem 0 .2rem; padding: .4rem .7rem; border-left: 3px solid var(--red); background: color-mix(in srgb, var(--red) 6%, var(--panel)); border-radius: 0 var(--r) var(--r) 0; }
.openinc .incline { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; padding: .15rem 0; }
.openinc .ackbox { color: var(--ok); font-size: 13px; }
.openinc .ackform { margin: 0; }

/* acknowledged: down, and in someone's hands — its own colour, never red */
.tag.ack { color: var(--ack); border-color: color-mix(in srgb, var(--ack) 45%, transparent); background: color-mix(in srgb, var(--ack) 12%, transparent); }
.dot.ack { background: var(--ack); }
.c-ack { color: var(--ack); }
.card.ack { border-color: color-mix(in srgb, var(--ack) 45%, transparent); }
.card.ack .num { color: var(--ack); }
.fb.ack { color: var(--ack); }

/* one cross on every search field, the browser's own turned off */
input[type=search]::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; display: none; }
.searchbox { position: relative; display: inline-flex; align-items: center; }
.searchbox input[type=search] { padding-right: 1.5rem; }
.searchbox .clearbtn { position: absolute; right: .2rem; top: 50%; transform: translateY(-50%); border: 0; background: none; color: var(--mute); cursor: pointer; padding: 0 .25rem; font-size: 12px; line-height: 1; }
.searchbox .clearbtn:hover { color: var(--ink); }


/* the machine's line: one grid, the same columns on every machine */
.hostblock summary { display: grid; grid-template-columns: 1.1rem minmax(11rem, 15rem) 5.2rem 7.5rem 6.5rem 27rem minmax(12rem, 1fr) auto; grid-template-areas: "caret name state svc rtt vitals load tags" "caret services services services services services services services"; align-items: center; column-gap: .6rem; row-gap: .25rem; }
.hostblock summary::before { grid-area: caret; align-self: start; margin-top: .15rem; }
.hostblock summary .c-name { grid-area: name; display: inline-flex; align-items: center; gap: .5rem; min-width: 0; }
.hostblock summary .c-name .hostname { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hostblock summary .c-state { grid-area: state; }
.hostblock summary .c-svc { grid-area: svc; font-size: 13px; white-space: nowrap; }
.hostblock summary .c-rtt { grid-area: rtt; font-size: 13px; white-space: nowrap; }
.hostblock summary .c-rtt i { font-style: normal; font-size: 9.5px; text-transform: uppercase; letter-spacing: .07em; color: var(--mute); }
.hostblock summary .c-vitals { grid-area: vitals; }
.hostblock summary .vitals { display: grid; grid-template-columns: 5.5rem 7.5rem 6.5rem 6.5rem; gap: 0; margin: 0; }
.hostblock summary .c-load { grid-area: load; font-size: 13px; white-space: normal; line-height: 1.25; }
.hostblock summary .c-tags { grid-area: tags; display: inline-flex; gap: .25rem; flex-wrap: wrap; }
.hostblock summary .c-services { grid-area: services; margin-left: 0; }
@media (max-width: 1100px) { .hostblock summary { display: flex; flex-wrap: wrap; } .hostblock summary .vitals { display: inline-flex; gap: 1rem; } }

/* the groups, said: a title and a rule between two of them */
.grouptitle { margin: 1.4rem 0 .4rem; padding-bottom: .25rem; border-bottom: 1px solid var(--line-2); font-size: 12px; text-transform: uppercase; letter-spacing: .08em; color: var(--mute); }
#tree > .grouptitle:first-child { margin-top: .4rem; }

.ownerpick { width: 13rem; }

/* The host page's chart sections: foldable, remembered, and the
   tables of a section stack with its charts (2026-08-30). */
.mgrid .foldbody { display: grid; grid-template-columns: 1fr; gap: .3rem; }
.mgrid .grouphead.foldhead { cursor: pointer; user-select: none; }
.mgrid .grouphead .foldbtn { background: none; border: 0; color: var(--mute); font-size: 12px; cursor: pointer; padding: 0 .35rem 0 0; }
.mgrid .grouphead:hover .foldbtn { color: var(--ink); }
.mgrid .foldbody > h4 { margin: .4rem 0 .1rem; font-size: 12.5px; font-weight: 600; }
.mgrid .foldbody > h4 .small { font-weight: 400; }
.mgrid .foldbody > table.list { margin-bottom: .5rem; }
.machine h2 .foldall { margin-left: .4rem; }
.tag.selfpill { text-decoration: none; margin-right: .4rem; }

/* the wall's latest changes: the link to a line's history on one line */
#wallev td:last-child { white-space: nowrap; }

/* a chip taken away from a pick (ctrl+click) is dimmed, as a legend's line is */
.fbtns .fb.off { opacity: .45; }
.wall .wallbar { margin: -.2rem 0 .8rem; }


/* ---- SMALL SCREENS, STRUCTURALLY (Robin, 2026-08-30: "si les filtres
   dépassent la ligne ils doivent aller à la ligne ou scroller ; si les
   graphes tiennent pas côte à côte ils doivent se stacker"). Three
   rules, at the source, so that nothing added later starts wide:
   a bar of buttons wraps, a grid child may shrink, a chart takes the
   width it is given. The page never scrolls sideways; what is wider
   than the screen — a table — scrolls inside its own box. */
.fbtns, .chips, .tranges, .foldall, .tabs, .counts, .menu, .who, .grouphead, .uhead, .headcols, .inline, form.inline, .legend, .services, .family { flex-wrap: wrap; min-width: 0; }
.top > * { min-width: 0; }
.machinegrid > *, .cards > *, .walltiles > *, .sitegrid > *, .cols > *, .grid > * { min-width: 0; }
.mchart svg, .graph, svg.graph { width: 100%; max-width: 100%; display: block; }
.tip { max-width: min(92vw, 420px); max-height: 80vh; overflow: hidden; }
.modalbox { max-width: 100%; max-height: 96vh; overflow: auto; }
body { overflow-x: hidden; }
@media (max-width: 700px) {
  .top { padding: .5rem .6rem; gap: .4rem; }
  .brand { font-size: 15px; }
  .machinegrid, .walltiles, .sitegrid, .cols, .cols.three, .grid { grid-template-columns: 1fr; }
  .cards { grid-template-columns: 1fr 1fr; }
  .modal { padding: 1.5vh .4rem; }
  .fbtns { display: flex; }
  .grouphead, h2, h3 { word-break: break-word; }
  .tape { height: 96px; }
  #tree, .tree { max-width: 100%; overflow-x: auto; }
  input, select, textarea { max-width: 100%; }
}
