:root {
  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans", Ubuntu, Arial, sans-serif;
  --mut: rgba(255,255,255,.66); --dim: rgba(255,255,255,.45); --line: rgba(255,255,255,.1);
  --ok: #3ddc97; --chg: #4fc3f7; --bat: #ffb300; --bad: #ff5252; --sun: #ffd54f; --boil: #ff8a65; --gray: #9aa9b6;
  --card: rgba(255,255,255,.045);
}
* { box-sizing: border-box; }
html, body { margin: 0; }
body { --a: var(--gray); --b0: #0b0f12; --b1: #232a31; min-height: 100vh; background: var(--b0); color: #fff;
  font-family: var(--font); -webkit-font-smoothing: antialiased; transition: background-color 1.2s; }
body.st-city     { --a: var(--ok);  --b0: #03120d; --b1: #0d4433; }
body.st-charging { --a: var(--chg); --b0: #030d18; --b1: #0b3a5c; }
body.st-battery  { --a: var(--bat); --b0: #140801; --b1: #5a2607; }
body.st-offline, body.st-stale { --a: var(--gray); --b0: #0b0f12; --b1: #2a3138; }
.bg { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }
.bg i { position: absolute; width: 90vmax; height: 90vmax; border-radius: 50%; filter: blur(60px); opacity: .55;
  background: radial-gradient(circle, var(--b1), transparent 65%); transition: background 1.2s; }
.bg .b1 { top: -45vmax; left: -30vmax; animation: drift 38s ease-in-out infinite alternate; }
.bg .b2 { bottom: -50vmax; right: -35vmax; animation: drift 46s ease-in-out infinite alternate-reverse; }
@keyframes drift { to { transform: translate(8vmax, 6vmax) scale(1.08); } }
@media (prefers-reduced-motion: reduce) { .bg i { animation: none; } }

main { max-width: 1180px; margin: 0 auto; padding: max(16px, env(safe-area-inset-top)) 16px 40px; }
.boot { padding: 24px 0; font-size: 22px; font-weight: 700; }
.grid { display: grid; gap: 16px; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 900px) { .grid.two { grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); } }
.card { background: var(--card); border: 1px solid var(--line); border-radius: 24px; padding: 16px 18px;
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); min-width: 0; }
.card h2 { margin: 0 0 12px; font-size: 13px; letter-spacing: .12em; text-transform: uppercase; font-weight: 800;
  color: color-mix(in srgb, var(--a) 55%, #fff); display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.card h2 small { font-size: 12px; letter-spacing: 0; text-transform: none; color: var(--dim); font-weight: 600; }
.mut { color: var(--mut); } .dim { color: var(--dim); }

/* hero */
.top { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 14px; }
h1 { margin: 0; font-size: clamp(40px, 11vw, 64px); line-height: .98; font-weight: 850; letter-spacing: -.035em;
  color: color-mix(in srgb, var(--a) 30%, #fff); text-wrap: balance; }
/* hero: power map city -> battery -> house */
.pmap { --spd: 1s; --soc: 0; --sc: var(--ok); display: grid; grid-template-columns: auto minmax(18px, 1fr) minmax(150px, 2.6fr) minmax(18px, 1fr) auto;
  align-items: center; gap: 0; }
@media (min-width: 700px) { .pmap { max-width: 760px; margin: 0 auto; } }
.node { display: grid; justify-items: center; gap: 6px; min-width: 56px; }
.node .ico { width: 52px; height: 52px; border-radius: 50%; display: grid; place-items: center; transition: all .6s;
  background: rgba(255,255,255,.05); border: 1.5px solid rgba(255,255,255,.14); color: var(--dim); }
.node .ico svg { width: 26px; height: 26px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.node .nv { font-size: 13px; color: var(--mut); font-weight: 700; white-space: nowrap; }
.node .nv b { font-size: 17px; color: #fff; font-weight: 850; font-variant-numeric: tabular-nums; }
.pmap.city .grid .ico { color: var(--ok); border-color: rgba(61,220,151,.5); }
.pmap.nocity .grid .ico { color: var(--bad); border-color: rgba(255,82,82,.4); background: rgba(255,82,82,.08); }
.pmap.f-chg .grid .ico { color: var(--chg); border-color: var(--chg); background: rgba(79,195,247,.14); box-shadow: 0 0 22px rgba(79,195,247,.35); }
.pmap.f-dis .house .ico { color: var(--bat); border-color: var(--bat); background: rgba(255,179,0,.14); box-shadow: 0 0 22px rgba(255,179,0,.35); }
/* wires: a faint rail, and dots running along it while power flows */
.wire { position: relative; height: 4px; margin: 0 4px 26px; border-radius: 2px; background: rgba(255,255,255,.08); }
.wire::after { content: ""; position: absolute; inset: -2px 0; opacity: 0; transition: opacity .6s;
  background-image: radial-gradient(circle, var(--wc) 2.6px, transparent 3px); background-size: 14px 8px; background-repeat: repeat-x;
  filter: drop-shadow(0 0 4px var(--wc)); animation: dots var(--spd) linear infinite; }
.w-in { --wc: var(--chg); } .w-out { --wc: var(--bat); }
.pmap.f-chg .w-in::after, .pmap.f-dis .w-out::after { opacity: 1; }
@keyframes dots { from { background-position: 0 50%; } to { background-position: 14px 50%; } }
/* the battery: a static glassy fill up to the SOC, coloured by SOC; no motion inside it.
   Direction is told by the icon before the number and the dots on the wires. */
.batt { position: relative; height: 96px; margin-bottom: 26px; border-radius: 20px; border: 2px solid rgba(255,255,255,.22);
  background: rgba(255,255,255,.04); overflow: visible; }
.batt .nub { position: absolute; right: -8px; top: 34%; bottom: 34%; width: 6px; border-radius: 0 4px 4px 0; background: rgba(255,255,255,.22); }
.batt .fill { position: absolute; left: 4px; top: 4px; bottom: 4px; width: calc((100% - 8px) * var(--soc) / 100); border-radius: 15px;
  overflow: hidden; transition: width 1.5s ease, background 1s;
  background: linear-gradient(180deg, color-mix(in srgb, var(--sc) 70%, #fff) 0%, var(--sc) 38%, color-mix(in srgb, var(--sc) 62%, #000) 100%);
  box-shadow: 0 0 24px color-mix(in srgb, var(--sc) 35%, transparent); }
.batt .fill::before { content: ""; position: absolute; left: 6px; right: 6px; top: 5px; height: 32%; border-radius: 12px;
  background: linear-gradient(180deg, rgba(255,255,255,.32), rgba(255,255,255,0)); }
.pct .ic { font-style: normal; font-size: .42em; vertical-align: .62em; margin-right: 4px; }
.pct .ic.up { color: #bfeaff; } .pct .ic.dn { color: #ffe1a3; }
/* under 15 %: a red frame */
.pmap.low .batt { border-color: rgba(255,82,82,.85); box-shadow: 0 0 22px rgba(255,82,82,.35); }
.batt .bi { position: absolute; inset: 0; display: grid; place-content: center; text-align: center; text-shadow: 0 1px 6px rgba(0,0,0,.55); }
.batt .pct { font-size: 44px; font-weight: 850; letter-spacing: -.03em; line-height: 1; font-variant-numeric: tabular-nums; }
.batt .pct small { font-size: 18px; font-weight: 750; opacity: .75; }
.batt .cap { font-size: 12px; font-weight: 700; color: rgba(255,255,255,.8); margin-top: 3px; }
/* below: how long it lasts, and the outage / schedule chips */
.hfoot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 16px; margin-top: 6px; }
@media (min-width: 700px) { .hfoot { max-width: 760px; margin: 6px auto 0; } }
.rt { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0 8px; } .rt:empty { display: none; }
.rt .k { font-size: 15px; color: var(--mut); font-weight: 650; }
.rt b { font-size: 26px; font-weight: 850; letter-spacing: -.02em; white-space: nowrap; }
.hchips { display: flex; flex-wrap: wrap; gap: 6px; } .hchips:empty { display: none; }
.hc { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 650; color: var(--mut); padding: 4px 10px;
  border-radius: 999px; background: rgba(255,255,255,.06); white-space: nowrap; }
.hc b { color: #fff; font-weight: 800; }
.hc i { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.hc.warn { color: #ffd27a; background: rgba(255,179,0,.13); } .hc.bad { color: #ffb3b3; background: rgba(255,82,82,.14); white-space: normal; }
@media (max-width: 420px) {
  .node { min-width: 48px; } .node .ico { width: 44px; height: 44px; } .node .ico svg { width: 22px; height: 22px; }
  .batt { height: 84px; } .batt .pct { font-size: 36px; } .batt .cap { font-size: 11px; }
  .pmap { grid-template-columns: auto minmax(14px, 1fr) minmax(130px, 3fr) minmax(14px, 1fr) auto; }
}
@media (prefers-reduced-motion: reduce) { .wire::after { animation: none; } }

/* schedule tracks */
.day + .day { margin-top: 14px; }
.dh { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; margin: 0 2px 6px; font-size: 14px; color: var(--mut); }
.dh b { color: #fff; font-size: 16px; font-weight: 800; }
.track { position: relative; height: 68px; border-radius: 14px; overflow: hidden; background: rgba(61,220,151,.13);
  border: 1px solid rgba(61,220,151,.25); }
.track .pl { position: absolute; top: 0; bottom: 0; background: repeating-linear-gradient(135deg, rgba(255,82,82,.85) 0 7px, rgba(185,29,29,.85) 7px 14px); }
.track .pl.ref, .lg-pl.ref { opacity: .32; }
.chip.ref { opacity: .55; }
.track .ac { position: absolute; bottom: 0; height: 22px; background: var(--bat); box-shadow: 0 0 12px rgba(255,179,0,.6); border-radius: 4px 4px 0 0; }
.track .past { position: absolute; top: 0; bottom: 0; left: 0; background: rgba(0,0,0,.35); }
.track .now { position: absolute; top: -2px; bottom: -2px; width: 2px; background: #fff; box-shadow: 0 0 8px #fff; }
.track .tl { position: absolute; z-index: 3; font-size: 11px; font-weight: 800; line-height: 1; white-space: nowrap; padding: 0 4px;
  font-variant-numeric: tabular-nums; pointer-events: none; }
.track .tl.r { transform: translateX(-100%); }
.track .tp { top: 4px; color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.9); }
.track.guess .tp { color: rgba(255,255,255,.6); }
.track .ta { bottom: 4px; padding: 2px 4px; color: #3a2600; background: var(--bat); border-radius: 4px; }
.track .ovl { position: absolute; z-index: 2; left: 0; right: 0; top: 20px; text-align: center; font-size: 12px; font-weight: 800;
  letter-spacing: .08em; text-transform: uppercase; pointer-events: none; text-shadow: 0 1px 3px rgba(0,0,0,.9); }
.ovl.em { color: #ffd27a; } .ovl.ok { color: #9ff0c9; } .ovl.wait { color: var(--mut); }
@media (max-width: 480px) { .dh .dd { display: none; } }
.sums { display: inline-flex; gap: 12px; white-space: nowrap; }
.sum { font-weight: 700; color: #fff; } .sum.ref { color: var(--mut); }
.sum i { display: inline-block; width: 12px; height: 9px; border-radius: 3px; margin-right: 5px; vertical-align: 0; }
.axis { position: relative; height: 16px; margin-top: 3px; font-size: 11px; color: var(--dim); }
.axis span { position: absolute; transform: translateX(-50%); } .axis span:first-child { transform: none; } .axis span:last-child { transform: translateX(-100%); }
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.chip { font-size: 13px; font-weight: 700; padding: 3px 9px; border-radius: 999px; background: rgba(255,82,82,.16); color: #ffb3b3; white-space: nowrap; }
.chip.a { background: rgba(255,179,0,.16); color: #ffd27a; }
.chip.ok { background: rgba(61,220,151,.14); color: #9ff0c9; }
.legend { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 12px; font-size: 13px; color: var(--mut); }
.legend i { display: inline-block; width: 14px; height: 10px; border-radius: 3px; margin-right: 6px; vertical-align: -1px; }
.lg-pl { background: repeating-linear-gradient(135deg, #ff5252 0 3px, #b91d1d 3px 6px); } .lg-ac { background: var(--bat); } .lg-ok { background: rgba(61,220,151,.4); }
.note { margin-top: 8px; font-size: 13px; color: var(--dim); }
.warn { color: #ffd27a; }

/* outages list */
.olist { display: grid; gap: 2px; }
.orow { display: grid; grid-template-columns: 92px minmax(0, 1fr) auto; gap: 10px; align-items: center; padding: 9px 4px;
  border-top: 1px solid var(--line); font-size: 14px; }
.orow:first-child { border-top: 0; }
.orow .d { font-weight: 800; } .orow .d small { display: block; font-weight: 600; color: var(--dim); font-size: 12px; }
.orow .tot { text-align: right; font-weight: 800; white-space: nowrap; } .orow .tot small { display: block; font-weight: 600; color: var(--dim); font-size: 12px; }
.orow .chips { margin-top: 0; }

/* stats */
.tabs { display: inline-flex; gap: 4px; padding: 4px; background: rgba(255,255,255,.06); border-radius: 999px; margin-bottom: 12px; flex-wrap: wrap; }
.tabs button { font: inherit; font-size: 14px; font-weight: 700; color: var(--mut); background: none; border: 0; padding: 7px 14px;
  border-radius: 999px; cursor: pointer; }
@media (max-width: 420px) { .tabs button { padding: 7px 11px; font-size: 13px; } }
.tabs button.on { background: color-mix(in srgb, var(--a) 28%, transparent); color: #fff; }
.chart { width: 100%; min-height: 200px; } .chart.big { min-height: 320px; }
.chart + .chart { margin-top: 10px; }
.ctitle { font-size: 13px; font-weight: 700; color: var(--mut); margin: 6px 2px 2px; }
.u-legend { font-size: 13px; color: var(--mut); } .u-legend .u-marker { border-radius: 3px; }
.u-legend th { font-weight: 600; } .u-legend td { font-weight: 800; color: #fff; }
.u-select { background: rgba(255,255,255,.08); }
.kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; margin: 14px 0 4px; }
@media (max-width: 620px) { .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.kpi { border-radius: 16px; padding: 10px 12px; background: rgba(255,255,255,.04); border: 1px solid var(--line); }
.kpi .k { font-size: 12px; color: var(--dim); font-weight: 700; } .kpi .v { font-size: 22px; font-weight: 850; margin-top: 2px; }
.kpi .v small { font-size: 13px; color: var(--mut); font-weight: 700; }
.bars { display: grid; gap: 4px; margin-top: 6px; }
.bar { display: grid; grid-template-columns: 74px minmax(0, 1fr) 118px; gap: 10px; align-items: center; font-size: 13px; }
.bar .lbl { color: var(--mut); font-weight: 700; white-space: nowrap; }
.bar .bt { position: relative; height: 16px; border-radius: 6px; background: rgba(255,255,255,.05); overflow: hidden; }
.bar .bt .p { position: absolute; left: 0; top: 0; bottom: 0; border: 1.5px dashed rgba(255,82,82,.7); border-radius: 6px; }
.bar .bt .x { position: absolute; left: 0; top: 3px; bottom: 3px; background: var(--bat); border-radius: 4px; }
.bar .val { text-align: right; font-weight: 800; white-space: nowrap; } .bar .val small { color: var(--dim); font-weight: 600; }
.empty { padding: 18px 4px; color: var(--dim); font-size: 14px; }

footer { margin-top: 18px; display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; font-size: 13px; color: var(--dim); }
.linkbtn { font: inherit; color: var(--mut); background: none; border: 1px solid var(--line); border-radius: 999px; padding: 6px 14px; cursor: pointer; }
.linkbtn:hover { color: #fff; }

/* PIN screen */
.login { min-height: calc(100vh - 60px); display: grid; place-items: center; }
.pinbox { width: min(340px, 100%); text-align: center; }
.pinbox h1 { font-size: 40px; }
.pinbox p { color: var(--mut); font-size: 16px; margin: 10px 0 22px; font-weight: 600; }
.dots { display: flex; justify-content: center; gap: 14px; margin-bottom: 18px; }
.dots i { width: 16px; height: 16px; border-radius: 50%; border: 2px solid rgba(255,255,255,.5); transition: background .15s; }
.dots i.f { background: #fff; border-color: #fff; }
.dots.shake { animation: shake .4s; }
@keyframes shake { 20%, 60% { transform: translateX(-9px); } 40%, 80% { transform: translateX(9px); } }
.pad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.pad button { font: inherit; font-size: 28px; font-weight: 700; color: #fff; height: 68px; border-radius: 20px; cursor: pointer;
  background: rgba(255,255,255,.07); border: 1px solid var(--line); -webkit-tap-highlight-color: transparent; }
.pad button:active { background: rgba(255,255,255,.18); }
.pad button.fn { font-size: 18px; color: var(--mut); background: transparent; border-color: transparent; }
.pad button:disabled { opacity: .35; }
.perr { min-height: 22px; margin-top: 14px; font-weight: 700; color: #ff9b9b; font-size: 15px; }
.sr { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
