/* The admin pages speak the language of the sign's web UI and the flasher: Cargan, black on paper
   white, a 3 px bar above and a 6 px bar below the masthead, no rounded corners, no capitals,
   red only for errors and always with text. Sizes: 15 px text, 13 px meta, 17 px h3, 22 px h2,
   the masthead 22 to 34 px, chart text 11 px; spacing on a 4 px grid with 8, 12, 16, 24 and 40
   as the usual steps. Controls and buttons are 40 px tall, small buttons 28. The dark scheme
   swaps the tokens; docs/ui-language.md names the building blocks. */
@font-face{font-family:'CarganWeb';src:url('/static/fonts/cargan-400.e0d0c826.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'CarganWeb';src:url('/static/fonts/cargan-700.7f24afcb.woff2') format('woff2');font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:'CarganWeb';src:url('/static/fonts/cargan-400i.8720ba55.woff2') format('woff2');font-weight:400;font-style:italic;font-display:swap}
:root{color-scheme:light dark;--fg:#121212;--fg-soft:#5a5a5a;--bg:#f7f7f5;--paper:#fff;--line-soft:#d0d0cd;--err:#a00;--err-bg:#fbeeee;--note:#efefe9;--mid:#8a8a86;--mono:ui-monospace,Consolas,Menlo,monospace}
@media(prefers-color-scheme:dark){:root{--fg:#f2f2ee;--fg-soft:#a6a6a0;--bg:#0f0f0f;--paper:#181818;--line-soft:#3a3a38;--err:#ff7070;--err-bg:#2a1414;--note:#232322;--mid:#6d6d69}}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{font-family:'CarganWeb',Arial,sans-serif;font-size:15px;line-height:1.45;margin:0;background:var(--bg);color:var(--fg)}
a{color:var(--fg);text-underline-offset:2px}
:focus-visible{outline:2px solid var(--fg);outline-offset:2px}
[tabindex="-1"]:focus{outline:none}
[hidden]{display:none!important}
h1,h2,h3,h4{margin:0;line-height:1.15}
p{margin:0}
/* An id or key in running text keeps the page's face: soft, spaced, in groups of four (the
   template function group). Monospace only where a value is copied out of a field. */
code{font-family:inherit;font-size:13px;color:var(--fg-soft);font-variant-numeric:tabular-nums;letter-spacing:.04em;overflow-wrap:anywhere}
.mono{font-family:var(--mono);font-size:13px;overflow-wrap:anywhere}
.num{font-variant-numeric:tabular-nums}
.soft{color:var(--fg-soft)}
.err{color:var(--err)}
.nowrap{white-space:nowrap}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.skip{position:absolute;left:-9999px;top:8px;background:var(--fg);color:var(--paper);padding:8px 12px}
.skip:focus{left:16px;z-index:10}
/* The second, small line under a value: in a table cell, a definition, a list item. */
td small,th small,dd small,li small{display:block;font-size:13px;color:var(--fg-soft);font-weight:400}
/* A tick or a cross before a word; the glyphs come from the system font. */
.mark-ok::before,.acked::before,.delivery-sent::before,.status-transferred::before{content:'\2713\00a0';font-weight:700}
.mark-no::before,.delivery-failed::before,.status-rejected::before{content:'\2715\00a0';font-weight:700}

/* frame */
.wrap{max-width:1440px;margin:0 auto;padding:0 16px}
.top{border-top:3px solid var(--fg);border-bottom:6px solid var(--fg);margin:16px 0 0;padding:16px 0 12px;display:flex;flex-wrap:wrap;justify-content:space-between;align-items:flex-end;gap:8px 24px}
h1{font-size:clamp(22px,4vw,34px);letter-spacing:-.01em}
h1 a{text-decoration:none}
.sub{margin-top:4px;color:var(--fg-soft);font-size:13px}
.who{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 16px;font-size:13px}
.who form{margin:0}
.nav{display:flex;gap:24px;overflow-x:auto;border-bottom:1px solid var(--line-soft);scrollbar-width:none}
.nav a{display:block;padding:12px 0 9px;text-decoration:none;white-space:nowrap;border-bottom:3px solid transparent}
.nav a:hover{border-bottom-color:var(--line-soft)}
.nav a[aria-current=page]{border-bottom-color:var(--fg);font-weight:700}
.nav .count{display:inline-block;min-width:20px;padding:0 6px;background:var(--fg);color:var(--paper);font-size:12px;font-weight:700;line-height:20px;text-align:center;vertical-align:1px}
main{min-width:0;min-height:50vh;padding-top:24px}
footer{margin:40px 0 24px;padding-top:12px;border-top:1px solid var(--line-soft);font-size:13px;color:var(--fg-soft);display:flex;flex-wrap:wrap;gap:8px 24px}

/* page heads, messages */
.pagehead{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:flex-end;gap:12px 24px;margin-bottom:16px}
h2{font-size:22px}
h3{font-size:17px}
h4{font-size:15px;margin:16px 0 4px}
.crumb{font-size:13px;margin-bottom:4px}
.crumb a{color:var(--fg-soft)}
.pagehead .title{display:flex;flex-wrap:wrap;align-items:center;gap:4px 12px}
.pagehead .soft{margin-top:4px;font-size:13px}
/* The pencil that renames a sign: 40 px to hit, shown on hover or focus, always where there is no pointer. */
.pagehead .edit{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;margin:-12px 0;color:var(--fg-soft);opacity:0}
.pagehead:hover .edit,.pagehead:focus-within .edit{opacity:1}
.pagehead .edit:hover{color:var(--fg)}
@media(hover:none){.pagehead .edit{opacity:1}}
.lead{margin-bottom:16px;max-width:70ch}
.note{background:var(--note);padding:8px 12px;margin-bottom:16px;font-size:13px}
.banner{background:var(--note);border-left:3px solid var(--fg);padding:12px 16px;margin-bottom:16px}
.banner.err{background:var(--err-bg);border-left-color:var(--err);color:var(--fg)}
.empty{background:var(--paper);border:1px dashed var(--line-soft);padding:24px;display:flex;flex-direction:column;align-items:flex-start;gap:12px;margin-bottom:16px}
.empty-chart{color:var(--fg-soft);padding:8px 0}

/* cards and lists */
.card{background:var(--paper);border:1px solid var(--line-soft);padding:16px;margin-bottom:16px;min-width:0}
.card>h3,.card>.head,.setting form>.head{margin-bottom:12px}
.head{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:baseline;gap:4px 16px}
.head .soft,.head>a{font-size:13px}
.head .title{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 12px}
.narrow{max-width:440px;margin:24px auto}
.narrow>h2{margin-bottom:16px}
.split{display:grid;gap:16px;margin-bottom:16px}
.split>.card{margin-bottom:0}
@media(min-width:900px){.split{grid-template-columns:repeat(2,minmax(0,1fr));align-items:start}}
dl.kv{display:grid;grid-template-columns:auto minmax(0,1fr);gap:4px 24px;margin:0}
dl.kv dt{font-weight:700}
dl.kv dd{margin:0;overflow-wrap:anywhere}
dl.kv.stack{grid-template-columns:1fr;gap:0}
dl.kv.stack dt{font-weight:400;font-size:13px;color:var(--fg-soft);margin-top:12px}
dl.kv.stack>dt:first-child,dl.facts>div:first-child>dt{margin-top:0}
dl.kv.stack dd{font-weight:700}
dl.kv.stack dd small{font-weight:400}
/* Key figures as tiles: a small label, the value at 20 px, a small line that says what it is. */
dl.stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px 24px;margin:0}
dl.stats>div{min-width:0}
dl.stats dt{font-size:13px;color:var(--fg-soft)}
dl.stats dd{margin:0;font-size:20px;font-weight:700;font-variant-numeric:tabular-nums;line-height:1.2}
dl.stats dd small{display:block;font-size:13px;font-weight:400;color:var(--fg-soft);margin-top:2px}

/* buttons: primary filled, secondary outlined, link for row actions, danger outlined with its
   text; filled red only in the confirmation dialog. All 40 px tall, .small 28. */
button,.button{display:inline-block;font-family:inherit;font-size:15px;font-weight:700;line-height:18px;border:1px solid var(--fg);background:var(--fg);color:var(--paper);padding:10px 16px;cursor:pointer;border-radius:0;text-decoration:none;text-align:center}
button:hover,.button:hover{box-shadow:inset 0 0 0 1px var(--paper)}
button:active,.button:active{box-shadow:inset 0 2px 0 0 rgba(0,0,0,.35)}
button:disabled,.button[aria-disabled=true]{background:var(--line-soft);border-color:var(--line-soft);color:var(--fg-soft);cursor:default;box-shadow:none}
button.secondary,.button.secondary{background:transparent;color:var(--fg);font-weight:400}
button.secondary:hover,.button.secondary:hover{box-shadow:inset 0 0 0 1px var(--fg)}
button.secondary:disabled{background:transparent;color:var(--fg-soft)}
button.small,.button.small{font-size:13px;line-height:16px;padding:5px 10px}
button.link{background:none;border:0;padding:0;color:var(--fg);font-size:inherit;line-height:inherit;font-weight:400;text-decoration:underline;text-underline-offset:2px;text-align:left}
button.link:hover,button.link:active{box-shadow:none}
button.danger{background:var(--err);border-color:var(--err);color:var(--paper)}
button.danger-outline,.button.danger-outline{background:transparent;color:var(--err);border-color:var(--err);font-weight:400}
button.danger-outline:hover,.button.danger-outline:hover{box-shadow:inset 0 0 0 1px var(--err)}
.danger-text{color:var(--err)!important}
.block{display:block;width:100%}
.or{text-align:center;color:var(--fg-soft);font-size:13px;margin:16px 0 8px}
.buttons{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px;align-items:center}
.button[aria-current=true]{background:var(--fg);color:var(--paper);font-weight:700}

/* forms */
.fields{display:grid;gap:16px;grid-template-columns:repeat(auto-fill,minmax(220px,1fr))}
.field{min-width:0}
.field.wide{grid-column:1/-1}
fieldset.field{border:0;padding:0;margin:0}
fieldset.field>legend{padding:0}
fieldset.field[aria-invalid=true]{border-bottom:1px solid var(--err);padding-bottom:4px}
.field>label:not(.switch),.field .lbl{display:block;font-weight:700;margin-bottom:2px}
.opt{font-weight:400;font-size:13px;color:var(--fg-soft)}
.control{display:flex;align-items:baseline;border-bottom:1px solid var(--fg)}
.control:focus-within{box-shadow:0 1px 0 0 var(--fg)}
.control[aria-invalid=true]{border-bottom-color:var(--err);box-shadow:0 1px 0 0 var(--err)}
.control[aria-invalid=true]:focus-within{outline:2px solid var(--fg);outline-offset:2px}
input[type=text],input[type=password],input[type=email],input[type=url],input[type=search],input[type=number],input[type=time],input[type=date],select,textarea{font-family:inherit;font-size:15px;padding:8px 4px;border:0;border-radius:0;background:transparent;color:var(--fg);width:100%;min-width:0}
/* One height for a text field and a select, so their lines meet; with the control's line, 40 px. */
.control>input,.control>select{height:39px}
.control>input.mono{font-family:var(--mono);font-size:13px}
select{cursor:pointer}
select option{background:var(--paper);color:var(--fg)}
/* Inside a control the line shows the focus; a check box keeps the page's ring. */
.control>input:focus,.control>select:focus,.control>textarea:focus{outline:none}
input:disabled,select:disabled,textarea:disabled{color:var(--fg);opacity:1;-webkit-text-fill-color:var(--fg);cursor:default}
.control:has(:disabled){border-bottom-style:dotted}
textarea{resize:vertical;line-height:1.4}
textarea.mono{font-family:var(--mono);font-size:13px;word-break:break-all}
.unit{flex:none;padding:0 4px 0 8px;color:var(--fg-soft);font-size:13px;white-space:nowrap}
.help{display:block;font-size:13px;color:var(--fg-soft);margin-top:4px}
.help.err{color:var(--err)}
.switch{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;cursor:pointer;padding:12px 0;border-top:1px solid var(--line-soft)}
.switch>span{flex:1}
.switch .lbl{font-weight:700}
.switch .help{margin-top:2px}
/* In a field grid the gap spaces a switch; one under another wide field gets the line centred. */
.fields>.field.wide>.switch{border-top:0;padding:0}
.fields>.field.wide+.field.wide>.switch{border-top:1px solid var(--line-soft);padding-top:16px}
input[type=checkbox]{flex:none;width:20px;height:20px;margin:0;accent-color:var(--fg);cursor:pointer}
input[type=checkbox]:disabled{cursor:default}
.daylist{display:flex;flex-wrap:wrap;gap:8px 16px;padding:8px 0}
.daylist label{display:inline-flex;align-items:center;gap:8px;cursor:pointer}
.daylist input{width:18px;height:18px}
.filters{display:flex;flex-wrap:wrap;gap:12px 16px;align-items:flex-end;margin-bottom:16px}
.filters .field{flex:1 1 160px;max-width:240px}
.filters .field.grow{flex:2 1 240px;max-width:none}
.filter-actions{display:flex;gap:16px;align-items:center}
.filters .shown{flex:1 0 100%;font-size:13px;margin-top:-4px}

/* tables */
.table-wrap{overflow-x:auto;margin-bottom:16px}
.card>.table-wrap:last-child,details .table-wrap{margin-bottom:0}
.table-wrap.card{padding:0 16px}
table{width:100%;border-collapse:collapse;font-size:15px}
th{text-align:left;font-weight:700;vertical-align:top}
thead th{font-size:13px;font-weight:400;color:var(--fg-soft);padding:8px 16px 8px 0;white-space:nowrap;border-bottom:1px solid var(--fg)}
thead th a{color:var(--fg-soft);text-decoration:none}
thead th a:hover{text-decoration:underline}
thead th[aria-sort] a{color:var(--fg);font-weight:700}
thead th[aria-sort=ascending] a::after{content:' \2191'}
thead th[aria-sort=descending] a::after{content:' \2193'}
td,tbody th{padding:12px 16px 12px 0;border-top:1px solid var(--line-soft);vertical-align:top}
tbody tr:first-child>*{border-top:0}
tbody tr:hover>*{background:var(--bg)}
td:last-child,th:last-child{padding-right:0}
tbody th a{text-decoration:none}
tbody th a:hover{text-decoration:underline}
table.devices{min-width:960px}
table.alarm-history{min-width:880px}
table.recipients{min-width:720px}
/* A small button in a row keeps its label on the row's first line. */
td .small{padding-top:3px;padding-bottom:3px}
tr.off>*,tr.off a{color:var(--fg-soft)}
td code,th code{white-space:nowrap}
td.state small{margin-top:4px}
td.state small a{text-decoration:none}
td.state small a:hover{text-decoration:underline}
.row-actions{display:flex;flex-wrap:wrap;gap:4px 16px;white-space:nowrap}
.row-actions form{margin:0}
ul.signins{list-style:none;margin:0;padding:0;display:grid;gap:4px}
ul.signins form{display:inline;margin:0}
.page-range{font-size:13px;margin:0 0 8px}
.pager{display:flex;gap:24px;margin-bottom:16px}

/* badges and states */
.badge{display:inline-block;font-size:13px;font-weight:400;line-height:1.5;padding:0 8px;margin:2px 0;border:1px solid var(--line-soft);white-space:nowrap}
dl.kv.stack .badge{margin:4px 0}
ul.events .badge{margin-left:4px}
.state-low,.alarm-battery{border-color:var(--fg);background:repeating-linear-gradient(135deg,transparent 0 3px,var(--line-soft) 3px 5px)}
.state-overdue,.alarm-overdue,.alarm-rejected,.settings-rejected{border-color:var(--err);color:var(--err)}
.alarm-calendar,.settings-pending,.code-open,.rev-signed,.event-running{border-color:var(--fg)}
.state-waiting{border-style:dashed;color:var(--fg-soft)}
.state-revoked,.code-used,.code-expired{color:var(--fg-soft);background:var(--note)}
.rev-superseded{border-style:dashed}
.status{font-size:13px;color:var(--fg-soft)}
.status-transferred{color:var(--fg)}
.status-rejected{color:var(--err)}
.status-pending{background:var(--fg);color:var(--paper);padding:0 8px}
.lock{display:inline-flex;align-items:center;gap:4px;font-size:13px}
.lock .icon{flex:none}
.lock-pending,.lock-release{color:var(--fg-soft)}
.lock-switch{margin-top:16px}
a.lock{text-decoration:none}
.field-lock{margin-left:6px;vertical-align:-2px}
table.locks input[type=checkbox]{margin:0}
table.locks .lock{white-space:nowrap}
.setting.pending{border-color:var(--fg);box-shadow:inset 3px 0 0 var(--fg)}
.setting.invalid{border-color:var(--err)}
.setting .delivery{font-size:13px;margin-bottom:12px}
.mark{display:inline-block;width:8px;height:8px;margin-left:8px;vertical-align:middle;background:var(--fg)}
.mark-rejected{width:auto;height:auto;margin-left:4px;vertical-align:baseline;background:none;color:var(--err);font-weight:700}
.mark-rejected::before{content:'\2715'}

/* a sign's page: panel left, tabs right */
.tabs,.subtabs{display:flex;gap:24px;overflow-x:auto;border-bottom:1px solid var(--fg);margin-bottom:16px;scrollbar-width:none}
.tabs a,.subtabs a{padding:8px 0 6px;text-decoration:none;white-space:nowrap;border-bottom:3px solid transparent}
.tabs a:hover,.subtabs a:hover{border-bottom-color:var(--line-soft)}
.tabs a[aria-current=page],.subtabs a[aria-current=page]{border-bottom-color:var(--fg);font-weight:700}
.subtabs{border-bottom-color:var(--line-soft);gap:20px}
.device{display:grid;gap:16px;align-items:start}
@media(min-width:960px){.device{grid-template-columns:280px minmax(0,1fr);gap:24px}.panel{position:sticky;top:16px;max-height:calc(100vh - 32px);overflow:auto}}
/* The panel's facts: one under another beside the tab; on a narrow screen, where the panel
   stands above the tab, in columns, and only on the overview (.wide-only elsewhere). */
dl.facts>div{display:contents}
@media(max-width:959px){
  .panel.wide-only{display:none}
  dl.kv.stack.facts{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px 16px}
  dl.facts>div{display:block}
  dl.facts>div>dt{margin-top:0}
  .seal{display:flex;flex-wrap:wrap;gap:4px 24px}
  .seal code{display:inline}
}
.device-main{min-width:0}
.seal{margin-top:16px;padding-top:12px;border-top:1px solid var(--line-soft);display:grid;gap:8px;font-size:13px}
.seal p{display:grid;gap:4px}
.seal b{font-size:15px}
.seal code{display:block}
.panel-actions{margin-top:16px}
.panel-actions .button{display:block}

/* disclosure */
summary{cursor:pointer;list-style:none;display:flex;justify-content:space-between;align-items:center;gap:12px}
summary::-webkit-details-marker{display:none}
summary::after{content:'';flex:none;width:8px;height:8px;border:solid var(--fg);border-width:0 2px 2px 0;transform:rotate(45deg);margin:0 4px 4px 0}
details[open]>summary::after{transform:rotate(-135deg);margin:4px 4px 0 0}
details.more{margin-top:16px;border-top:1px solid var(--line-soft)}
details.more>summary{padding:12px 0;font-weight:700}
details.more.card{padding-top:4px;padding-bottom:4px}
details.more.card[open]{padding-bottom:16px}
.card-foot{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:flex-start;gap:12px 24px;margin-top:16px;padding-top:12px;border-top:1px solid var(--line-soft)}
.card-foot>button{margin-left:auto}
details.copy{flex:1 1 280px}
details.copy>summary{padding:8px 0;justify-content:flex-start}
.pick-all{display:flex;gap:8px;align-items:center;margin:8px 0;font-weight:700}
ul.signs{list-style:none;margin:8px 0 0;padding:0;max-height:240px;overflow:auto;display:grid;gap:4px}
ul.signs label{display:flex;gap:8px;align-items:center;cursor:pointer}
details.values>summary{justify-content:flex-start;color:var(--fg-soft);padding:4px 0}
details.values[open]>summary{margin-bottom:4px}

/* charts: x in percent of the plot, y in pixels (charts.go), so a chart fills its box at any
   width while its text, strokes and marks keep their size. The labels stand in the padding, which
   charts.go counts on; the minimum width is the plot the labels are spaced for plus that padding,
   and a narrower box scrolls (.chart-scroll) */
.chart,.wakegrid{display:block;box-sizing:border-box;width:100%;overflow:visible}
.chart{padding:10px 24px 24px 52px}
.chart.wide{min-width:748px}
.chart.half{min-width:426px}
.chart.revisions{padding:0 10px 22px 160px;min-width:520px}
.wakegrid{padding:4px 12px 18px 64px;min-width:604px}
.chart-scroll{overflow-x:auto}
.chart text,.wakegrid text{font-family:inherit;font-size:11px;fill:var(--fg-soft)}
.gridline{stroke:var(--line-soft);stroke-width:1}
.ink{fill:none;stroke:var(--fg);stroke-width:2;stroke-linejoin:round}
.spark .ink{stroke-width:1.5}
.hit{fill:transparent}
.dot,.bar{fill:var(--fg)}
.hollow,.barh{fill:var(--paper);stroke:var(--fg);stroke-width:1.5}
.threshold{stroke:var(--err);stroke-width:1;stroke-dasharray:4 3}
.forecast{stroke:var(--fg);stroke-width:1.5;stroke-dasharray:2 3}
.lost{stroke:var(--err);stroke-width:2.5;fill:none}
.now{stroke:var(--fg);stroke-dasharray:2 2}
svg.sw{display:inline-block;vertical-align:-1px;margin-right:8px;flex:none}
.charts{display:grid;gap:16px}
@media(min-width:1280px){.charts{grid-template-columns:repeat(2,minmax(0,1fr))}.charts>.card{margin-bottom:0}}
.legend.shared{margin:8px 0 16px}
.toolbar{display:flex;flex-wrap:wrap;justify-content:space-between;gap:8px 16px;margin-bottom:16px}
.range{display:flex;gap:8px;align-items:center}
.toolbar .soft{font-size:13px}
.spark{display:block;width:120px;height:28px;margin-top:4px}
.timeline{display:block;width:160px;height:20px;margin-top:4px}
.timeline .axis{stroke:var(--line-soft)}
.timeline .now{stroke:var(--fg-soft);stroke-dasharray:2 2}
.timeline .tick{stroke:var(--fg);stroke-width:1.5}
.timeline .due{fill:var(--paper);stroke:var(--fg);stroke-width:1.5}
.timeline .due.late{stroke:var(--err);fill:var(--err)}
.fleet{margin-bottom:16px}
.fleetbar,.phasebar{display:block;width:100%}
.fleetbar a:focus-visible rect{stroke:var(--fg);stroke-width:2}
.fleetbar .gap{stroke:var(--bg);stroke-width:3}
.phasebar{margin-bottom:8px}
.phasebar .gap{stroke:var(--paper);stroke-width:2}
.seg-ok{fill:var(--fg)}
.seg-low{fill:url(#hatch-fleet)}
.hatch-bg{fill:var(--paper)}
.hatch{stroke:var(--fg);stroke-width:2.5}
.seg-overdue{fill:var(--err)}
.seg-waiting{fill:var(--mid)}
.seg-revoked{fill:var(--paper);stroke:var(--mid);stroke-width:1}
/* The phases of a wake, the same look in the bar, its legend and both views: the six network
   phases in greys as before, the four every wake has in patterns. */
.p-radio{fill:var(--fg)}.p-assoc{fill:var(--fg-soft)}.p-dhcp{fill:var(--mid)}.p-ntp{fill:var(--line-soft)}.p-ics{fill:var(--paper);stroke:var(--fg);stroke-width:1.5}.p-sync{fill:var(--note);stroke:var(--fg-soft);stroke-width:1}
.p-start{fill:url(#hatch-start)}.p-draw{fill:url(#hatch-draw)}.p-refresh{fill:url(#hatch-refresh)}.p-rest{fill:var(--paper);stroke:var(--line-soft);stroke-width:1.5;stroke-dasharray:3 2}
.hatch.soft{stroke:var(--fg-soft);stroke-width:1.5}.hatch-bg.dark{fill:var(--fg-soft)}.hatch.paper{stroke:var(--paper);stroke-width:1.5}
/* Every segment and swatch outlined, so the greys read as parts. */
.phasebar>rect{stroke:var(--fg);stroke-width:1}
.sw.p-start,.sw.p-radio,.sw.p-assoc,.sw.p-dhcp,.sw.p-ntp,.sw.p-ics,.sw.p-sync,.sw.p-draw,.sw.p-refresh{border-color:var(--fg)}
.phases .range{margin-bottom:12px}
.cell-full{fill:var(--fg)}
.cell-hollow{fill:var(--paper);stroke:var(--fg);stroke-width:1.5}
.cell-none{fill:var(--mid)}
.legend{list-style:none;display:flex;flex-wrap:wrap;gap:4px 16px;margin:8px 0 0;padding:0;font-size:13px;color:var(--fg-soft)}
.legend a{color:var(--fg-soft);text-decoration:none;display:inline-flex;align-items:center}
.legend a:hover{color:var(--fg)}
.legend a[aria-current=true]{color:var(--fg);font-weight:700;text-decoration:underline}
.legend b{color:var(--fg);font-weight:700;margin-left:4px}
.legend+dl.kv{margin-top:16px}
.legend li{display:inline-flex;align-items:center}
.sw{display:inline-block;width:12px;height:12px;margin-right:8px;flex:none;border:1px solid transparent}
.sw.seg-ok,.sw.p-radio,.sw.cell-full{background:var(--fg)}
.sw.cell-none{width:4px;height:4px;background:var(--mid);margin:0 12px 0 4px}
.sw.seg-low{background:repeating-linear-gradient(45deg,var(--fg) 0 2px,var(--paper) 2px 5px);border-color:var(--fg)}
.sw.seg-overdue{background:var(--err)}
.sw.seg-waiting{background:var(--mid)}
.sw.p-ntp{background:var(--line-soft)}
.sw.seg-revoked{background:var(--paper);border-color:var(--mid)}
.sw.p-assoc{background:var(--fg-soft)}.sw.p-dhcp{background:var(--mid)}
.sw.p-ics,.sw.cell-hollow{background:var(--paper);border:1.5px solid var(--fg)}
.sw.p-sync{background:var(--note);border-color:var(--fg-soft)}
.sw.p-start{background:repeating-linear-gradient(135deg,var(--fg-soft) 0 2px,var(--paper) 2px 4px)}
.sw.p-draw{background:repeating-linear-gradient(135deg,var(--paper) 0 2px,var(--fg) 2px 4px)}
.sw.p-refresh{background:repeating-linear-gradient(135deg,var(--paper) 0 2px,var(--fg-soft) 2px 4px)}
.sw.p-rest{background:var(--paper);border:1.5px dashed var(--line-soft)}
.sw.line,.sw.line-forecast,.sw.line-threshold{height:0;border:0;border-top:2px solid var(--fg);width:16px}
.sw.line-forecast{border-top-style:dotted}
.sw.line-threshold{border-top:1px dashed var(--err)}
.sw.dot{background:var(--fg);border-radius:50%}
.sw.dot-hollow{background:var(--paper);border:1.5px solid var(--fg);border-radius:50%}

/* alarms */
.checklist .daylist{padding:4px 0 0}
ol.recent{list-style:none;margin:0;padding:0}
ol.recent>li{display:grid;grid-template-columns:9em minmax(0,1fr) auto;align-items:baseline;gap:4px 16px;padding:12px 0;border-top:1px solid var(--line-soft)}
ol.recent b a{text-decoration:none}
ol.recent b a:hover{text-decoration:underline}
ol.recent>li:first-child{border-top:0;padding-top:0}
ol.recent>li:last-child{padding-bottom:0}
.rule summary h3{font-size:inherit}
.rule summary .soft{font-weight:400}
/* A rule has a number or two: one column, so a help line runs wider than its input. */
.rule .fields{grid-template-columns:minmax(0,1fr)}
.rule .control{max-width:240px}
.delivery-failed{color:var(--err)}

/* events and history */
h4.day{margin-top:24px}
h4.day:first-of-type{margin-top:0}
ul.events{list-style:none;margin:0;padding:0}
ul.events>li{display:grid;grid-template-columns:8em minmax(0,1fr);gap:4px 16px;padding:8px 0;border-top:1px solid var(--line-soft)}
ul.events>li:first-child{border-top:0}
ul.events .when{font-variant-numeric:tabular-nums;white-space:nowrap}
ul.events .past{color:var(--fg-soft)}
ol.revisions{list-style:none;margin:0;padding:0}
ol.revisions>li{padding:12px 0;border-top:1px solid var(--line-soft)}
ol.revisions>li:first-child{border-top:0;padding-top:0}
.rev-head{display:flex;flex-wrap:wrap;gap:4px 16px;align-items:baseline;margin-bottom:4px}
.rev-head .soft{font-size:13px}
ul.changes{list-style:none;margin:4px 0 0;padding:0;display:grid;gap:4px}
ul.changes .what{font-weight:700}
ul.changes .from{color:var(--fg-soft);text-decoration:line-through;text-decoration-color:var(--mid)}

/* pairing */
.code-grid{display:grid;gap:16px;align-items:start}
@media(min-width:760px){.code-grid{grid-template-columns:minmax(0,1fr) 240px}}
.qr{display:block;width:100%;max-width:240px;height:auto;border:1px solid var(--line-soft)}
figure{margin:0}
figcaption{font-size:13px;margin-top:4px}
.code-card{border:1px solid var(--fg);border-top:6px solid var(--fg)}
.code-card .lead{margin-bottom:12px}
ol.steps-list{margin:4px 0 0;padding-left:24px;display:grid;gap:4px}
ol.steps-list+p{margin-top:12px}
.naming{display:grid;gap:16px;grid-template-columns:repeat(auto-fill,minmax(280px,1fr))}

/* dialog */
dialog{border:1px solid var(--fg);border-top:6px solid var(--err);background:var(--paper);color:var(--fg);padding:24px;max-width:520px;width:calc(100% - 32px)}
dialog::backdrop{background:rgba(0,0,0,.45)}
dialog.plain{border-top-color:var(--fg)}
.rename-form h2{margin-bottom:16px}
.danger-form h2{margin-bottom:8px}
.danger-form ul{margin:12px 0 16px;padding-left:24px;display:grid;gap:4px}
.switch.confirm{border-top:1px solid var(--line-soft);border-bottom:1px solid var(--line-soft)}

@media(max-width:600px){
  ol.recent>li{grid-template-columns:minmax(0,1fr)}
  dl.stats{grid-template-columns:repeat(2,minmax(0,1fr))}
  /* On a phone a table becomes a list of blocks: each row a card-like block, every cell a line,
     a cell with data-label named. A table names its own grid areas when it needs more. */
  table.blocks,table.blocks tbody{display:block;min-width:0}
  table.blocks thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
  table.blocks tr{display:grid;grid-template-columns:minmax(0,1fr);gap:4px;padding:12px 0;border-top:1px solid var(--line-soft)}
  table.blocks tr:first-child{border-top:0}
  table.blocks tr>*{padding:0;border:0;background:none!important}
  table.blocks td[data-label]::before{content:attr(data-label) ': ';color:var(--fg-soft)}
  /* Open alarms, reached from a mail on a phone: the time and the button right. */
  table.alarms tr{grid-template-columns:minmax(0,1fr) auto;gap:4px 16px}
  table.alarms tr>:nth-child(1){grid-area:1/1}
  table.alarms tr>:nth-child(2){grid-area:2/1}
  table.alarms tr>:nth-child(3){grid-area:1/2;text-align:right}
  table.alarms tr>:nth-child(4){grid-area:3/1}
  table.alarms tr>:nth-child(5){grid-area:2/2/4/3;align-self:end;text-align:right}
  /* The list of signs: name and state on the first line; then the last contact beside the
     battery, each with its small chart under it; then the next sync beside the firmware. A
     cell's name stands over its value. */
  table.devices tr{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:8px 16px}
  table.devices tr>:nth-child(1){grid-area:1/1}
  table.devices tr>:nth-child(2){grid-area:1/2;text-align:right}
  table.devices tr>:nth-child(3){grid-area:2/1}
  table.devices tr>:nth-child(5){grid-area:2/2;text-align:left}
  table.devices tr>:nth-child(4){grid-area:3/1}
  table.devices tr>:nth-child(6){grid-area:3/2}
  table.devices td[data-label]::before{content:attr(data-label);display:block;font-size:13px}
  table.devices .timeline,table.devices .spark{display:block;width:100%;max-width:160px;height:auto}
  .card,.table-wrap.card{padding:12px}
  .card-foot>button{width:100%}
}
@media print{
  :root{color-scheme:light;--fg:#000;--fg-soft:#444;--bg:#fff;--paper:#fff;--line-soft:#bbb;--err:#a00;--err-bg:#fff;--note:#fff;--mid:#888}
  .nav,footer,.buttons,.who,.skip,.panel-actions,.tabs,.subtabs,.filters,.toolbar,.pager,.card-foot,.row-actions{display:none!important}
  .card{border:0;padding:0}
}
