/* LightningMonitor status page */
:root {
  --bg:    #f4f5f7;
  --card:  #ffffff;
  --fg:    #1b2130;
  --muted: #677086;
  --line:  #e2e5eb;
  --ok:    #2b8a3e;
  --bad:   #c92a2a;
  --rm:    #1971c2;   /* monitored radius, and strikes outside V, on the svg maps */
  /* alert levels, from 5 (low) to 1 (very high), and their text colour */
  --lv:    #f2c200;   /* V vigilance */
  --la:    #e03131;   /* A alert */
  --lc:    #a61e4d;   /* C critical */
  --on-v:  #1b2130;   /* text on them */
  --on-a:  #ffffff;
  --on-c:  #ffffff;
  --amber: #f59f00;   /* simulation button */
  /* OSM background of the svg maps (LOCATIONS.<id>.OSM): discreet, under the strikes */
  --osm-coast:  #6b7a90;
  --osm-border: #9b6fb0;
  --osm-road:   #c9853f;
  --osm-road2:  #dbb894;
  --osm-water:  #74a9d8;
  color-scheme: light;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:    #0f1218;
    --card:  #181d26;
    --fg:    #e5e8ee;
    --muted: #98a1b3;
    --line:  #2a313d;
    --ok:    #51cf66;
    --bad:   #ff6b6b;
    --rm:    #4dabf7;
    --osm-coast:  #8c99ad;
    --osm-border: #b48cc8;
    --osm-road:   #b9824a;
    --osm-road2:  #7d6a55;
    --osm-water:  #3f78a8;
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg:    #0f1218;
  --card:  #181d26;
  --fg:    #e5e8ee;
  --muted: #98a1b3;
  --line:  #2a313d;
  --ok:    #51cf66;
  --bad:   #ff6b6b;
  --rm:    #4dabf7;
  --osm-coast:  #8c99ad;
  --osm-border: #b48cc8;
  --osm-road:   #b9824a;
  --osm-road2:  #7d6a55;
  --osm-water:  #3f78a8;
  color-scheme: dark;
}
/* DISCONNECTED: the whole page turns red */
:root.disc {
  --bg:    #6e0b0b;
  --card:  #861414;
  --fg:    #ffffff;
  --muted: #ffc9c9;
  --line:  #a82a2a;
  --ok:    #b2f2bb;
  --bad:   #ffe3e3;
  color-scheme: dark;
}

* { box-sizing: border-box }
body {
  margin:     0;
  background: var(--bg);
  color:      var(--fg);
  font:       14px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}
main {
  max-width:  1100px;
  margin:     0 auto;
  padding:    14px 16px 28px;
}
header  { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 16px; margin-bottom: 8px }
h1      { font-size: 19px; margin: 0 }
h2      { font-size: 14px; margin: 18px 0 6px }
a       { color: inherit }
footer  { margin-top: 18px; font-size: 12px }
.muted  { color: var(--muted) }
.num    { font-variant-numeric: tabular-nums }
.nowrap { white-space: nowrap }
.said   { cursor: help }

/* header buttons: simulation (when simulating) and voice (TTS) */
.ctl { margin-left: auto; display: flex; flex-wrap: wrap; gap: 6px }
.btn {
  font:          inherit;
  font-size:     12px;
  font-weight:   600;
  padding:       2px 10px;
  border-radius: 999px;
  border:        1px solid var(--line);
  background:    var(--card);
  color:         var(--fg);
  cursor:        pointer;
}
.btn.on       { border-color: var(--ok); color: var(--ok) }
.btn.prime    { border-color: var(--amber); background: var(--amber); color: var(--on-v) }
.btn.sim      { border-color: var(--amber); box-shadow: 0 0 0 2px var(--amber) }   /* simulation played */
.btn:disabled { cursor: default; opacity: .6 }
.btn[hidden]  { display: none }

/* "Sources": collapsible (collapsed by default), one line per source; while collapsed, a
   dot per source next to the title */
.src > summary {
  display:     flex;
  align-items: center;
  gap:         6px;
  margin:      18px 0 6px;
  list-style:  none;
  cursor:      pointer;
}
.src > summary::-webkit-details-marker { display: none }
.src > summary::before {
  content:     "\25B8";                 /* ▸, turned down when open */
  display:     inline-block;
  color:       var(--muted);
  font-size:   12px;
  transition:  transform .15s;
}
.src[open] > summary::before { transform: rotate(90deg) }
.src > summary h2            { margin: 0 }
.src[open] .src-dots         { display: none }
.src-dots .dot               { margin-right: 3px }
.sources { display: grid; gap: 2px; color: var(--muted); font-size: 13px }

/* source status dots */
.dot {
  display:       inline-block;
  width:         9px;
  height:        9px;
  border-radius: 50%;
  margin-right:  6px;
  background:    var(--bad);
}
.dot.ok   { background: var(--ok) }
.dot.warn { background: #f59f00 }
.dot.off  { background: var(--muted) }

/* flashing DISCONNECTED modal */
.modal {
  position:        fixed;
  inset:           0;
  display:         flex;
  align-items:     center;
  justify-content: center;
  padding:         16px;
  background:      rgba(40, 0, 0, .45);
  z-index:         10;
}
.modal-box {
  background:    #e03131;
  color:         #ffffff;
  border:        3px solid #ffffff;
  border-radius: 14px;
  padding:       26px 32px;
  text-align:    center;
  max-width:     min(100%, 560px);
  box-shadow:    0 10px 40px rgba(0, 0, 0, .5);
  animation:     flash 1s steps(1, end) infinite;
}
.modal-box strong { display: block; font-size: clamp(30px, 9vw, 60px); letter-spacing: .08em; line-height: 1.1 }
.modal-box p      { margin: 10px 0 0; font-size: 14px }
@keyframes flash  { 0% { background: #e03131 } 50% { background: #5c0909 } }

/* POI cards: up to --cols per row, each at least --card-min wide (fewer columns below that) */
.grid {
  --cols:     3;
  --gap:      10px;
  --card-min: 310px;
  display:    grid;
  gap:        var(--gap);
  grid-template-columns: repeat(auto-fill,
    minmax(max(min(100%, var(--card-min)), (100% - (var(--cols) - 1) * var(--gap)) / var(--cols)), 1fr));
}
.card            { background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; min-width: 0 }
.card.off        { opacity: .5; border-style: dashed }     /* POI with enabled: false */
.card.off .badge { border-color: var(--muted); color: var(--muted) }
.poi-head        { display: flex; justify-content: space-between; gap: 8px; align-items: flex-start }
.poi-head h3     { margin: 0; font-size: 15px; line-height: 1.3 }
.poi-head .muted { font-size: 12px; line-height: 1.35 }
.badge {
  font-weight:   700;
  font-size:     12px;
  padding:       2px 8px;
  border-radius: 999px;
  white-space:   nowrap;
  border:        1px solid var(--ok);
  color:         var(--ok);
}
/* Vigilance, Alert, Critical: narrow boxes, coloured while active; their last line is the
   cool-down, "time left / cool-down" while active (same height either way) */
.levels { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; margin: 8px 0 0 }
.lv {
  border:        1px solid var(--line);
  border-radius: 7px;
  padding:       5px 2px;
  min-width:     0;
  font-size:     12px;
  line-height:   1.3;
  text-align:    center;
  white-space:   nowrap;
  overflow:      hidden;
}
.lv b         { display: block; font-size: 13px }
.lv > span    { display: block; color: var(--muted) }
.lv em        { font-style: normal; font-weight: 700; font-variant-numeric: tabular-nums }
.lv.on.hold   { opacity: .65 }        /* cool-down over, hysteresis dn_c before going down */

/* tables */
.tbl      { overflow-x: auto; background: var(--card); border: 1px solid var(--line); border-radius: 10px }
table     { width: 100%; border-collapse: collapse; font-size: 13px }
th, td    { text-align: left; padding: 4px 8px; border-bottom: 1px solid var(--line); white-space: nowrap }
th        { color: var(--muted); font-weight: 600 }
.pill     { display: inline-block; padding: 0 7px; border-radius: 999px; font-weight: 700; font-size: 12px }
.pill.lvl-s { border: 1px solid var(--ok); color: var(--ok); padding: 0 6px }
/* live map */
.map {
  height:        clamp(300px, 55vh, 560px);
  border:        1px solid var(--line);
  border-radius: 10px;
  overflow:      hidden;
  background:    var(--card);
}
.map iframe  { display: block; width: 100%; height: 100%; border: 0 }
#bomap-reset { font-size: 12px; font-weight: 400; margin-left: 10px }

/* svg maps (SETTINGS.map: svg): one square map per POI, in the POI cards' grid */
.smap-hint       { font-size: 12px; font-weight: 400; margin-left: 10px }
.smap .poi-head  { align-items: baseline }
.smap-reset      { font-size: 12px; white-space: nowrap }
.smap-box {
  aspect-ratio:  1 / 1;
  margin-top:    8px;
  border-radius: 8px;
  overflow:      hidden;
  background:    var(--bg);
  box-shadow:    inset 0 0 0 1px var(--line);
}
.smap-svg        { display: block; width: 100%; height: 100%; cursor: grab;
                   touch-action: none; user-select: none; -webkit-user-select: none }
.smap-svg.drag   { cursor: grabbing }
.smap-foot       { font-size: 12px; margin-top: 4px }
.ring            { fill-opacity: .07; stroke-width: 1.5 }
.ring.on         { fill-opacity: .2; stroke-width: 3 }         /* level on */
.ring.rm         { fill: var(--rm); stroke: var(--rm); fill-opacity: .04 }
.ring.lvl-v       { fill: var(--lv); stroke: var(--lv) }
.ring.lvl-a       { fill: var(--la); stroke: var(--la) }
.ring.lvl-c       { fill: var(--lc); stroke: var(--lc) }
/* strikes: coloured by the innermost circle they are in, blue outside V */
.strike           { stroke: var(--fg); stroke-width: 1; stroke-opacity: .55; fill: var(--rm) }
.strike.lvl-v     { fill: var(--lv) }
.strike.lvl-a     { fill: var(--la) }
.strike.lvl-c     { fill: var(--lc) }
.strike.new      { animation: pop .6s ease-out; transform-box: fill-box; transform-origin: center }
@keyframes pop   { from { transform: scale(3) } }
.poi-dot         { fill: var(--fg); stroke: var(--bg); stroke-width: 2 }
.map-pt          { font-size: 14px; cursor: default; user-select: none }
.ring-label, .poi-label, .scale-label, .map-pt-label {
  font-size:       11px;
  fill:            var(--muted);
  paint-order:     stroke;             /* halo: legible over circles and strikes */
  stroke:          var(--bg);
  stroke-width:    3px;
  stroke-linejoin: round;
  pointer-events:  none;
}
.poi-label       { font-size: 12px; font-weight: 700; fill: var(--fg) }
.map-pt-label    { fill: var(--fg) }
.scale           { fill: none; stroke: var(--muted); stroke-width: 1.5 }
/* OSM background: strokes in px whatever the zoom (the group is scaled to km) */
.osm             { fill: none; vector-effect: non-scaling-stroke; stroke-linejoin: round;
                   stroke-linecap: round; pointer-events: none }
.osm-coast       { stroke: var(--osm-coast);  stroke-width: 1.2 }
.osm-border2     { stroke: var(--osm-border); stroke-width: 1.4; stroke-dasharray: 6 3 }
.osm-border4     { stroke: var(--osm-border); stroke-width: 1;   stroke-dasharray: 4 3; stroke-opacity: .8 }
.osm-motorway    { stroke: var(--osm-road);   stroke-width: 1.2; stroke-opacity: .75 }
.osm-primary     { stroke: var(--osm-road2);  stroke-width: .8;  stroke-opacity: .75 }
.osm-secondary   { stroke: var(--osm-road2);  stroke-width: .6;  stroke-opacity: .55 }
.osm-tertiary    { stroke: var(--osm-road2);  stroke-width: .5;  stroke-opacity: .4 }
.osm-river       { stroke: var(--osm-water);  stroke-width: .8;  stroke-opacity: .8 }
.osm-lake        { stroke: var(--osm-water);  stroke-width: .9 }
/* world map (map/world.json, 1:110m): where no OSM map covers, a little fainter */
.world           { fill: none; vector-effect: non-scaling-stroke; stroke-linejoin: round;
                   pointer-events: none }
.world-coast     { stroke: var(--osm-coast);  stroke-width: 1;   stroke-opacity: .8 }
.world-border2   { stroke: var(--osm-border); stroke-width: 1.2; stroke-dasharray: 6 3; stroke-opacity: .7 }
.osm-place       { pointer-events: none }
.osm-place circle { fill: var(--muted) }
.osm-place text  { font-size: 10px; fill: var(--muted); paint-order: stroke; stroke: var(--bg);
                   stroke-width: 3px; stroke-linejoin: round }
.osm-city text   { font-size: 11px; font-weight: 600 }

/* 5 px viewport border: most severe level of all POIs, flashing red when disconnected */
.vp                { position: fixed; inset: 0; border: 5px solid transparent; pointer-events: none; z-index: 30 }
.vp.disc           { border-color: #ff3030; animation: vpflash 1s steps(1, end) infinite }
@keyframes vpflash { 50% { border-color: #ffffff } }

@media (prefers-reduced-motion: reduce) {
  .modal-box, .vp.disc, .strike.new { animation: none }
}

/* alert level colours: active level cell, pill, badge, POI card outline, viewport border */
.lv.on.lvl-v, .pill.lvl-v { background: var(--lv); color: var(--on-v); border-color: var(--lv) }
.lv.on.lvl-a, .pill.lvl-a { background: var(--la); color: var(--on-a); border-color: var(--la) }
.lv.on.lvl-c, .pill.lvl-c { background: var(--lc); color: var(--on-c); border-color: var(--lc) }
.lv.on.lvl-v > span { color: var(--on-v); opacity: .8 }
.lv.on.lvl-a > span { color: var(--on-a); opacity: .8 }
.lv.on.lvl-c > span { color: var(--on-c); opacity: .8 }
.card.lvl-s { border-color: var(--ok); box-shadow: 0 0 0 2px var(--ok) }
.card.lvl-v { border-color: var(--lv); box-shadow: 0 0 0 2px var(--lv) }
.card.lvl-a { border-color: var(--la); box-shadow: 0 0 0 2px var(--la) }
.card.lvl-c { border-color: var(--lc); box-shadow: 0 0 0 2px var(--lc) }
.vp.lvl-v { border-color: var(--lv) }
.vp.lvl-a { border-color: var(--la) }
.vp.lvl-c { border-color: var(--lc) }
