/* Renew dashboard. Colours are tokens: a full light palette on :root, the dark palette under
   prefers-color-scheme (unless the user picked light) and under [data-theme="dark"].
   Series 1 is blue (forecast, discharging, planned), series 2 orange (actual, charging, realised),
   series 3 aqua (PV, perfect foresight), series 4 violet. The order is validated for colour-vision deficiency. */

:root {
  color-scheme: light;
  --page: #f9f9f7;
  --surface: #fcfcfb;
  --surface-2: #f3f2ee;
  --ink: #0b0b0b;
  --ink-2: #52514e;
  --muted: #6f6e69;        /* axis and helper text; darker than the chart muted grey for 4.5:1 text contrast */
  --grid: #e1e0d9;
  --axis: #c3c2b7;
  --border: rgba(11, 11, 11, 0.10);
  --border-strong: rgba(11, 11, 11, 0.18);
  --s1: #2a78d6;
  --s2: #eb6834;
  --s3: #1baf7a;
  --s4: #6250d6;
  --s5: #b58100;           /* a fifth series: the PV feed-in scheme in the settlement breakdown, the offer comparator */
  --band: rgba(98, 80, 214, 0.08);
  --band-key: rgba(98, 80, 214, 0.35);
  --peer-band: rgba(42, 120, 214, 0.14);   /* the peers' P25-P75 band (docs/benchmark.md) */
  --peer-band-key: rgba(42, 120, 214, 0.40);
  --now: #c2307a;          /* the "now" line: magenta, apart from the series hues (validated against s1-s3) */
  --now-wash: rgba(11, 11, 11, 0.04);
  --accent: #2a78d6;
  --accent-hover: #256abf;
  --accent-ink: #ffffff;
  --accent-wash: #e8f1fc;
  --viewport-wash: rgba(42, 120, 214, 0.12);   /* the time-lapse overview's viewport: translucent, the curve shows through */
  --good: #0ca30c;
  --good-ink: #006300;
  --warning: #fab219;
  --warning-ink: #7a5200;
  --critical: #d03b3b;
  --critical-ink: #b02a2a;
  --info-ink: #1c5cab;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 4px 16px rgba(0, 0, 0, 0.06);
  --radius: 10px;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --page: #0d0d0d;
    --surface: #1a1a19;
    --surface-2: #222220;
    --ink: #f0efec;
    --ink-2: #c3c2b7;
    --muted: #9a9890;
    --grid: #2c2c2a;
    --axis: #383835;
    --border: rgba(255, 255, 255, 0.10);
    --border-strong: rgba(255, 255, 255, 0.18);
    --s1: #3987e5;
    --s2: #d95926;
    --s3: #199e70;
    --s4: #9085e9;
    --s5: #d4a21c;
    --band: rgba(144, 133, 233, 0.12);
    --band-key: rgba(144, 133, 233, 0.45);
    --peer-band: rgba(57, 135, 229, 0.24);
    --peer-band-key: rgba(57, 135, 229, 0.55);
    --now: #e25ca8;
    --now-wash: rgba(255, 255, 255, 0.04);
    --accent: #3987e5;
    --accent-hover: #5598e7;
    --accent-ink: #ffffff;
    --accent-wash: #16263b;
    --viewport-wash: rgba(57, 135, 229, 0.20);
    --good-ink: #0ca30c;
    --warning-ink: #fab219;
    --critical-ink: #e66767;
    --info-ink: #86b6ef;
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 4px 16px rgba(0, 0, 0, 0.35);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --page: #0d0d0d;
  --surface: #1a1a19;
  --surface-2: #222220;
  --ink: #f0efec;
  --ink-2: #c3c2b7;
  --muted: #9a9890;
  --grid: #2c2c2a;
  --axis: #383835;
  --border: rgba(255, 255, 255, 0.10);
  --border-strong: rgba(255, 255, 255, 0.18);
  --s1: #3987e5;
  --s2: #d95926;
  --s3: #199e70;
  --s4: #9085e9;
  --s5: #d4a21c;
  --band: rgba(144, 133, 233, 0.12);
  --band-key: rgba(144, 133, 233, 0.45);
  --peer-band: rgba(57, 135, 229, 0.24);
  --peer-band-key: rgba(57, 135, 229, 0.55);
  --now: #e25ca8;
  --now-wash: rgba(255, 255, 255, 0.04);
  --accent: #3987e5;
  --accent-hover: #5598e7;
  --accent-ink: #ffffff;
  --accent-wash: #16263b;
  --viewport-wash: rgba(57, 135, 229, 0.20);
  --good-ink: #0ca30c;
  --warning-ink: #fab219;
  --critical-ink: #e66767;
  --info-ink: #86b6ef;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 4px 16px rgba(0, 0, 0, 0.35);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; background: var(--page); color: var(--ink); font-size: 14px; line-height: 1.5; min-height: 100vh; }
a { color: var(--info-ink); }
a:hover { text-decoration-thickness: 2px; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
h1 { font-size: 24px; line-height: 1.25; margin: 0; letter-spacing: -0.01em; }
h2 { font-size: 17px; margin: 0 0 2px; }
h3 { font-size: 14px; margin: 16px 0 6px; }
p { margin: 0 0 8px; }
.sub, .hint { color: var(--ink-2); margin: 0; }
.hint { font-size: 13px; max-width: 72ch; }
.muted { color: var(--muted); }
.mono { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; font-size: 13px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.skip { position: absolute; left: -999px; top: 8px; background: var(--surface); padding: 8px 12px; z-index: 50; }
.skip:focus { left: 8px; }

/* ------------------------------------------------------------------ top bar and shell */

.topbar {
  position: sticky; top: 0; z-index: 20; display: flex; align-items: center; gap: 16px;
  padding: 10px 20px; background: color-mix(in srgb, var(--page) 88%, transparent);
  backdrop-filter: saturate(1.4) blur(8px); border-bottom: 1px solid var(--border);
}
.brand { display: inline-flex; align-items: center; gap: 8px; font-weight: 700; font-size: 17px; color: var(--ink); text-decoration: none; }
.brand-mark { width: 22px; height: 22px; border-radius: 6px; background: linear-gradient(135deg, var(--accent), var(--brand-2, var(--s3))); position: relative; }
.brand-mark::after { content: ""; position: absolute; inset: 6px 5px; border: 2px solid #fff; border-radius: 2px; border-right-width: 5px; }
.topnav { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.topnav a { color: var(--ink-2); text-decoration: none; padding: 6px 10px; border-radius: 6px; }
.topnav a:hover, .topnav a[aria-current="page"] { color: var(--ink); background: var(--surface-2); }
.top-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.org-name { color: var(--ink-2); font-size: 13px; max-width: 18ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.theme-toggle { min-width: 34px; padding-inline: 8px; }

/* The side column shows a site name of about 30 characters in full at the outline's site level (docs/section-nav.md). */
.shell { --sidenav-w: min(300px, 26vw); display: grid; grid-template-columns: var(--sidenav-w) minmax(0, 1fr); min-height: calc(100vh - 55px); }
.shell.public { display: block; }
.sidenav { border-right: 1px solid var(--border); padding: 16px 10px; position: sticky; top: 55px; align-self: start; height: calc(100vh - 55px); overflow-y: auto; }
.sidenav ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.sidenav a { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 8px; color: var(--ink-2); text-decoration: none; font-weight: 500; }
.sidenav a:hover { background: var(--surface-2); color: var(--ink); }
.sidenav a[aria-current="page"] { background: var(--accent-wash); color: var(--info-ink); }
.sidenav .nav-sep { height: 1px; background: var(--border); margin: 10px 6px; }
.nav-icon { width: 16px; text-align: center; opacity: 0.8; }
.sidenav .role { margin: 14px 10px 0; font-size: 12px; color: var(--muted); }

main { padding: 24px 28px 48px; max-width: 1240px; width: 100%; margin: 0 auto; }
.shell.public main { max-width: 1120px; }
.page-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-end; gap: 12px 24px; margin-bottom: 18px; }
.page-head .sub { margin-top: 4px; }
.actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.breadcrumb { font-size: 13px; margin-bottom: 6px; }
.breadcrumb a { color: var(--ink-2); }

@media (max-width: 860px) {
  .shell { display: block; }
  .sidenav { position: sticky; top: 53px; z-index: 15; height: auto; border-right: 0; border-bottom: 1px solid var(--border); padding: 6px 10px; background: var(--page); overflow-x: auto; }
  .sidenav ul { flex-direction: row; gap: 2px; width: max-content; }
  .sidenav a { padding: 6px 10px; white-space: nowrap; }
  .sidenav .nav-sep, .sidenav .role, .nav-icon { display: none; }
  main { padding: 18px 16px 40px; }
  .topbar { padding: 8px 16px; gap: 10px; }
  .topnav .hide-narrow, .org-name { display: none; }
  h1 { font-size: 21px; }
}
/* Phone width: the signed-out top bar's buttons and pickers go to a second row instead of past the edge, and a
   control's select (a long option name) never widens its card. */
@media (max-width: 520px) {
  .topbar { flex-wrap: wrap; gap: 8px 12px; }
  .top-right { flex-wrap: wrap; justify-content: flex-end; }
}
.actions { min-width: 0; max-width: 100%; }
.controls { max-width: 100%; }
.controls label { min-width: 0; max-width: 100%; }
.controls select { max-width: 100%; }

/* ------------------------------------------------------------------ cards, tiles, grids */

.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 20px; margin-block: 0 16px; box-shadow: var(--shadow); min-width: 0; }
.card-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start; gap: 12px 16px; margin-bottom: 12px; }
.card > h3:first-child { margin-top: 0; }
.grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
.grid-2 > .card, .grid-3 > .card { margin: 0; }
.stack > * + * { margin-top: 16px; }
@media (max-width: 980px) { .grid-3 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 760px) { .grid-2, .grid-3 { grid-template-columns: 1fr; } }

.tiles { display: flex; flex-wrap: wrap; gap: 14px 32px; margin-block: 4px 12px; }
.tile .label { font-size: 12px; color: var(--ink-2); }
.tile .value { font-size: 22px; font-weight: 600; line-height: 1.25; }
.tile.hero .value { font-size: 48px; line-height: 1.1; letter-spacing: -0.02em; }
.tile .note { font-size: 12px; color: var(--muted); }
@media (max-width: 520px) { .tile.hero .value { font-size: 36px; } .tiles { gap: 12px 22px; } }
/* Two figures that belong together (the overview's planned sales and purchases): side by side under one caption. */
.tile-pair { border-top: 1px solid var(--border); padding-top: 10px; margin-bottom: 12px; }
.tile-pair-caption { font-size: 12px; font-weight: 600; color: var(--ink-2); }
.tile-pair .tiles { flex-wrap: nowrap; margin-block: 4px 0; }

.kv { display: grid; grid-template-columns: max-content 1fr; gap: 6px 16px; margin: 0; }
.kv dt { color: var(--ink-2); }
.kv dd { margin: 0; overflow-wrap: anywhere; }

/* ------------------------------------------------------------------ controls */

label { color: var(--ink-2); font-size: 13px; }
input, select, textarea, button, .button {
  font: inherit; font-size: 14px; color: var(--ink); background: var(--surface);
  border: 1px solid var(--axis); border-radius: 7px; padding: 6px 10px; min-height: 36px;
}
textarea { width: 100%; resize: vertical; line-height: 1.4; }
input[type="number"] { font-variant-numeric: tabular-nums; }
input[type="checkbox"], input[type="radio"] { min-height: 0; width: 16px; height: 16px; accent-color: var(--accent); margin: 0; }
input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"] { border-color: var(--critical); box-shadow: 0 0 0 1px var(--critical); }
input:read-only:not([type="checkbox"]) { background: var(--surface-2); }
button, .button {
  background: var(--accent); color: var(--accent-ink); border-color: transparent; cursor: pointer; font-weight: 600;
  padding-inline: 14px; display: inline-flex; align-items: center; justify-content: center; gap: 6px; text-decoration: none; white-space: nowrap;
}
button:hover, .button:hover { background: var(--accent-hover); }
button.secondary, .button.secondary { background: var(--surface); color: var(--ink); border-color: var(--axis); font-weight: 500; }
button.secondary:hover, .button.secondary:hover { background: var(--surface-2); }
button.ghost { background: transparent; color: var(--ink-2); border-color: transparent; font-weight: 500; }
button.ghost:hover { background: var(--surface-2); color: var(--ink); }
button.danger { background: var(--critical); color: #fff; }
button.danger:hover { background: var(--critical-ink); }
.danger-text { color: var(--critical-ink) !important; }
button.link { background: none; border: 0; color: var(--info-ink); padding: 0 4px; min-height: 0; text-decoration: underline; font-weight: 500; }
button:disabled { opacity: 0.55; cursor: not-allowed; }
button[aria-busy="true"] { cursor: progress; }
button.small, .button.small { min-height: 30px; padding: 3px 10px; font-size: 13px; }
.button.big, button.big { min-height: 44px; padding-inline: 20px; font-size: 15px; }

.controls { display: flex; flex-wrap: wrap; gap: 10px 12px; align-items: flex-end; }
.controls label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; }
.controls input[type="number"] { width: 7.5em; }
.filters { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: flex-end; padding: 12px 16px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: 16px; }
.filters label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; }
.filters input[type="number"] { width: 7em; }
/* Explore's battery picker (pages/explore.js): the catalogue's make / model / modules fields next to the zone, the
   datasheet of the chosen model under them, full width. The size hint is left out: the datasheet shows the size. */
.explore-filters { align-items: flex-start; }
.explore-filters .explore-picker { flex: 1 1 440px; min-width: 0; }
.explore-filters .model-picker { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px 14px; }
.explore-filters .model-picker .field > label { font-weight: normal; }
.explore-filters .model-picker .field > .hint { display: none; }
.explore-filters .explore-spec { flex-basis: 100%; min-width: 0; }
.explore-filters .explore-spec:empty { display: none; }
.explore-filters .explore-note { margin: 8px 0 0; font-size: 12px; color: var(--muted); }
.explore-filters .notice { margin: 0; }
.cycle-cap-field { display: inline-flex; flex-wrap: wrap; gap: 4px 8px; align-items: center; }
.cycle-cap-field input[type="number"] { width: 7.5em; padding: 2px 6px; font-size: 13px; }
.cycle-cap-field .hint { font-size: 12px; }
/* Phone width: the field and its note take the whole row instead of the narrow value column. */
@media (max-width: 520px) { .datasheet-kv dd:has(.cycle-cap-field) { grid-column: 1 / -1; } }
.checks-inline { display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: center; min-height: 36px; }
.checks-inline label { display: inline-flex; flex-direction: row; align-items: center; gap: 6px; font-size: 13px; color: var(--ink); }
.checks-inline label[hidden] { display: none; }

.segmented { display: inline-flex; border: 1px solid var(--axis); border-radius: 8px; overflow: hidden; }
.segmented input { position: absolute; opacity: 0; pointer-events: none; }
.segmented label { padding: 6px 14px; cursor: pointer; color: var(--ink-2); font-size: 13px; min-height: 34px; display: inline-flex; align-items: center; }
.segmented label + input + label, .segmented input + label:not(:first-of-type) { border-left: 1px solid var(--axis); }
.segmented input:checked + label { background: var(--accent-wash); color: var(--info-ink); font-weight: 600; }
.segmented input:focus-visible + label { outline: 2px solid var(--accent); outline-offset: -2px; }

/* forms */
form.form { max-width: 880px; }
fieldset { border: 1px solid var(--border); border-radius: var(--radius); padding: 14px 18px 16px; margin: 0 0 16px; background: var(--surface); min-width: 0; }
legend { font-weight: 650; padding: 0 6px; font-size: 15px; }
fieldset > .hint { margin-bottom: 10px; }
.grid-fields { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 12px 16px; }
.grid-fields .wide { grid-column: 1 / -1; }
.field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.field[hidden], .grid-fields[hidden] { display: none; }
.field > label { font-weight: 500; color: var(--ink); }
.field input:not([type="checkbox"]), .field select { width: 100%; }
.field .hint { font-size: 12px; color: var(--muted); }
.field-error { color: var(--critical-ink); font-size: 12px; min-height: 0; }
.field-error:empty { display: none; }
.field.check label { display: inline-flex; align-items: center; gap: 8px; color: var(--ink); font-weight: 500; cursor: pointer; }
.with-suffix { display: flex; align-items: stretch; }
.with-suffix input { border-top-right-radius: 0; border-bottom-right-radius: 0; min-width: 0; }
.with-suffix .suffix { display: inline-flex; align-items: center; padding: 0 9px; border: 1px solid var(--axis); border-left: 0; border-radius: 0 7px 7px 0; background: var(--surface-2); color: var(--ink-2); font-size: 13px; white-space: nowrap; }
.form-actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 8px; }
.copy-field { display: flex; gap: 8px; align-items: stretch; }
.copy-field input { flex: 1; min-width: 0; }
.confirm-wrap { display: inline-flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.confirm-q { color: var(--ink-2); font-size: 13px; }
/* "Connect my <vendor> account" (control settings, onboarding): the button with its hint, and the connected status. */
.oauth-connect .hint { margin: 6px 0 0; }
.oauth-status .alert { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; margin: 0; }
.oauth-status .alert .confirm-wrap { margin-left: auto; }
.grid-fields details.wide > .grid-fields { margin-top: 10px; }
/* PV geometry (js/pages/pvsettings.js): the compass beside the azimuth, the arrays and the preview. */
.pv-geometry[hidden], .pv-arrays[hidden] { display: none; }
.pv-geometry { border-top: 1px solid var(--border); padding-top: 12px; }
.pv-compass-row { display: flex; align-items: center; gap: 10px; margin-top: 2px; }
.pv-compass svg { display: block; overflow: visible; }
.pv-compass-ring { fill: var(--surface-2); stroke: var(--axis); stroke-width: 1; }
.pv-compass-letter { fill: var(--muted); font-size: 9px; font-weight: 600; }
.pv-compass-arrow line { stroke: var(--s3); stroke-width: 2.5; stroke-linecap: round; }
.pv-compass-arrow path { fill: var(--s3); }
.pv-direction { color: var(--ink-2); font-size: 13px; }
.pv-arrays { display: flex; flex-direction: column; gap: 8px; }
.pv-arrays-rows { display: flex; flex-direction: column; gap: 10px; }
.pv-array-row { padding: 10px 12px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface-2); }
.pv-array-remove { display: flex; align-items: flex-end; }
.pv-preview-summary { margin: 8px 0 4px; color: var(--ink-2); }

/* auth pages */
.auth-wrap { max-width: 420px; margin: 32px auto; }
.auth-wrap .card { padding: 28px; }
.auth-wrap h1 { margin-bottom: 6px; }
.auth-wrap form .field { margin-bottom: 14px; }
.auth-wrap form button[type="submit"] { width: 100%; min-height: 42px; }
.auth-links { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px; margin-top: 14px; font-size: 13px; }

/* ------------------------------------------------------------------ states */

.alert { border-radius: 8px; padding: 10px 14px; margin: 0 0 12px; border: 1px solid var(--border); background: var(--surface-2); color: var(--ink); }
.alert ul { margin: 4px 0 0; padding-left: 18px; }
.alert.error { border-color: color-mix(in srgb, var(--critical) 45%, transparent); background: color-mix(in srgb, var(--critical) 9%, var(--surface)); }
.alert.error strong { color: var(--critical-ink); }
.alert.warning { border-color: color-mix(in srgb, var(--warning) 60%, transparent); background: color-mix(in srgb, var(--warning) 12%, var(--surface)); }
.alert.success { border-color: color-mix(in srgb, var(--good) 45%, transparent); background: color-mix(in srgb, var(--good) 9%, var(--surface)); }
.alert.info { border-color: color-mix(in srgb, var(--accent) 35%, transparent); background: var(--accent-wash); }
.alert .actions { margin-top: 8px; }
.empty { text-align: center; padding: 28px 16px; color: var(--ink-2); border: 1px dashed var(--border-strong); border-radius: var(--radius); background: var(--surface-2); }
.empty p { margin: 0 auto; max-width: 52ch; }
.empty .actions { justify-content: center; margin-top: 12px; }
.loading-state { display: flex; align-items: center; gap: 10px; color: var(--ink-2); padding: 18px 4px; }
.spinner { width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--grid); border-top-color: var(--accent); animation: spin 0.8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration: 3s; } }
.is-loading .chart, .is-loading .tiles, .is-loading .bars, .is-loading .table-wrap { opacity: 0.45; transition: opacity 0.2s; }
.status-line { min-height: 1.5em; margin: 6px 0; color: var(--ink-2); font-size: 13px; }
.status-line.error { color: var(--critical-ink); }

.badge { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600; padding: 1px 8px 1px 6px; border-radius: 999px; border: 1px solid var(--border); background: var(--surface-2); color: var(--ink-2); white-space: nowrap; }
.badge-icon { font-size: 11px; line-height: 1; }
.badge.good { color: var(--good-ink); border-color: color-mix(in srgb, var(--good) 40%, transparent); background: color-mix(in srgb, var(--good) 8%, var(--surface)); }
.badge.warning { color: var(--warning-ink); border-color: color-mix(in srgb, var(--warning) 60%, transparent); background: color-mix(in srgb, var(--warning) 12%, var(--surface)); }
.badge.critical { color: var(--critical-ink); border-color: color-mix(in srgb, var(--critical) 45%, transparent); background: color-mix(in srgb, var(--critical) 8%, var(--surface)); }
.badge.info { color: var(--info-ink); border-color: color-mix(in srgb, var(--accent) 35%, transparent); background: var(--accent-wash); }
.pill { display: inline-block; font-size: 12px; padding: 0 7px; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--border); color: var(--ink-2); margin: 1px 4px 1px 0; white-space: nowrap; }

.toasts { position: fixed; right: 16px; bottom: 16px; z-index: 60; display: flex; flex-direction: column; gap: 8px; max-width: min(380px, calc(100vw - 32px)); }
.toast { background: var(--ink); color: var(--page); padding: 10px 14px; border-radius: 8px; box-shadow: var(--shadow); transition: opacity 0.3s, transform 0.3s; }
.toast.error { background: var(--critical); color: #fff; }
.toast.success { background: var(--good-ink); color: #fff; }
.toast.leaving { opacity: 0; transform: translateY(6px); }

.secret-box { border: 1px solid color-mix(in srgb, var(--warning) 60%, transparent); background: color-mix(in srgb, var(--warning) 10%, var(--surface)); border-radius: var(--radius); padding: 14px 16px; margin-bottom: 16px; }
.secret-box p { margin-bottom: 8px; }

/* ------------------------------------------------------------------ tables */

.table-wrap { overflow-x: auto; max-width: 100%; }
.table-wrap.scroll { max-height: 420px; overflow-y: auto; }
table { border-collapse: collapse; font-size: 13px; width: 100%; }
caption { text-align: left; }
th, td { padding: 8px 10px; text-align: left; border-bottom: 1px solid var(--grid); white-space: nowrap; vertical-align: middle; }
th { color: var(--ink-2); font-weight: 600; font-size: 12px; position: sticky; top: 0; background: var(--surface); z-index: 1; }
td.num, th.num, .align-right { text-align: right; font-variant-numeric: tabular-nums; }
td.wrap { white-space: normal; min-width: 18ch; }
tbody tr:hover td { background: color-mix(in srgb, var(--surface-2) 70%, transparent); }
tr.total td { font-weight: 650; border-top: 2px solid var(--axis); }
td a { font-weight: 500; }
td input[type="number"] { width: 7em; }
details { margin-top: 12px; }
summary { cursor: pointer; color: var(--ink-2); font-weight: 500; }
summary:hover { color: var(--ink); }

/* ------------------------------------------------------------------ charts */

.chart-title { font-size: 13px; font-weight: 600; margin: 18px 0 4px; color: var(--ink-2); }
.chart { position: relative; width: 100%; }
.chart svg { display: block; width: 100%; height: auto; overflow: visible; }
.chart svg:focus-visible { outline-offset: 4px; }
.chart text { fill: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums; }
.chart .band-label { fill: var(--ink-2); font-size: 11px; font-weight: 600; }
.chart .grid { stroke: var(--grid); stroke-width: 1; }
.chart .baseline { stroke: var(--axis); stroke-width: 1; }
.chart .crosshair { stroke: var(--muted); stroke-width: 1; }
.chart .band { fill: var(--band); }
.chart .hit { fill: transparent; }
.chart .col.dim { opacity: 0.5; }
/* the "now" line (docs/timelapse.md §1): moved by transform only, never redrawn */
.chart .now-line { stroke: var(--now); stroke-width: 2; }
.chart .now-wash { fill: var(--now-wash); }
.chart .now-label { fill: var(--ink-2); font-size: 11px; font-weight: 600; paint-order: stroke; stroke: var(--surface); stroke-width: 3px; stroke-linejoin: round; }
.chart .now.smooth .now-marker, .chart .now.smooth .now-wash { transition: transform var(--now-move, 1s) linear; }
@media (prefers-reduced-motion: reduce) { .chart .now .now-marker, .chart .now .now-wash { transition: none !important; } }

.legend { display: flex; flex-wrap: wrap; gap: 4px 16px; font-size: 12px; color: var(--ink-2); }
.legend:empty { display: none; }
.legend > span { display: inline-flex; align-items: center; gap: 6px; }
.key-line { width: 16px; height: 2px; border-radius: 1px; display: inline-block; flex: none; }
.key-rect { width: 10px; height: 10px; border-radius: 2px; display: inline-block; flex: none; }
.key-band { width: 12px; height: 10px; border-radius: 2px; display: inline-block; flex: none; }
.key-none { width: 16px; display: inline-block; }

.bars { display: grid; grid-template-columns: max-content 1fr max-content; gap: 8px 12px; align-items: center; margin-top: 8px; }
.bars .name { color: var(--ink-2); }
.bars .track { height: 16px; border-radius: 0 4px 4px 0; background: var(--grid); position: relative; }
.bars .fill { height: 100%; border-radius: 0 4px 4px 0; background: var(--s1); }
.bars .val { font-weight: 600; }
@media (max-width: 520px) { .bars { grid-template-columns: 1fr max-content; } .bars .track { grid-column: 1 / -1; order: 0; } }

.tooltip {
  position: fixed; pointer-events: none; z-index: 70; background: var(--surface); color: var(--ink);
  border: 1px solid var(--border-strong); border-radius: 8px; padding: 8px 10px; font-size: 12px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.14); min-width: 150px; max-width: 300px;
}
.tooltip .t-head { color: var(--ink); font-weight: 600; }
.tooltip .t-sub { color: var(--muted); margin-bottom: 4px; font-size: 11px; }
.tooltip .t-head + .t-row { margin-top: 4px; }
.tooltip .t-row { display: flex; align-items: center; gap: 8px; }
.tooltip .t-row strong { font-variant-numeric: tabular-nums; }
.tooltip .t-row span:last-child { color: var(--ink-2); }

/* ------------------------------------------------------------------ landing */

.landing-hero { padding: 40px 0 28px; display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 32px; align-items: center; }
.landing-hero h1 { font-size: 40px; line-height: 1.1; letter-spacing: -0.025em; margin-bottom: 14px; }
.landing-hero .lead { font-size: 17px; color: var(--ink-2); max-width: 54ch; margin-bottom: 20px; }
.landing-hero .actions { gap: 10px; }
.hero-figure { background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 18px; box-shadow: var(--shadow); }
.hero-figure .caption { font-size: 12px; color: var(--muted); margin-top: 6px; }
.features { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; margin: 8px 0 24px; }
.feature { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 18px; }
.feature h3 { margin: 0 0 6px; font-size: 15px; }
.feature p { color: var(--ink-2); margin: 0; }
.steps { counter-reset: step; list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.steps li { counter-increment: step; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 14px; }
.steps li::before { content: counter(step); display: inline-flex; width: 22px; height: 22px; border-radius: 50%; align-items: center; justify-content: center; background: var(--accent-wash); color: var(--info-ink); font-weight: 700; font-size: 12px; margin-bottom: 6px; }
.steps strong { display: block; }
.steps span { color: var(--ink-2); font-size: 13px; }
.cta-band { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; padding: 22px; border-radius: 14px; background: var(--accent-wash); margin: 24px 0; }
.cta-band h2 { font-size: 19px; }
@media (max-width: 860px) {
  .landing-hero { grid-template-columns: 1fr; padding-top: 16px; }
  .landing-hero h1 { font-size: 30px; }
  .features { grid-template-columns: 1fr; }
  .steps { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 480px) { .steps { grid-template-columns: 1fr; } }

.section-title { font-size: 19px; margin: 28px 0 12px; }
.footer { color: var(--muted); font-size: 12px; padding: 24px 0 8px; border-top: 1px solid var(--border); margin-top: 32px; display: flex; flex-wrap: wrap; gap: 6px 18px; }
.footer a { color: var(--ink-2); }

/* site list status dots etc. */
.site-name { font-weight: 600; }
.subtle-row { color: var(--ink-2); font-size: 12px; }
.list { list-style: none; margin: 0; padding: 0; }
.list li { display: flex; gap: 10px; align-items: flex-start; padding: 9px 0; border-bottom: 1px solid var(--grid); }
.list li:last-child { border-bottom: 0; }
.list .grow { flex: 1; min-width: 0; }
.list .meta { color: var(--muted); font-size: 12px; }
.toolbar { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center; margin-bottom: 14px; }
.toolbar .spacer { flex: 1; }
.logo-preview { max-height: 56px; max-width: 220px; border: 1px solid var(--border); border-radius: 6px; padding: 4px; background: #fff; }
.code-block { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; font-size: 12px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px; padding: 10px; overflow-x: auto; white-space: pre; }
.recovery { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 6px; }
.feed-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 10px; }
.feed { border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; background: var(--surface); }
.feed .t { font-weight: 600; }
.feed .m { color: var(--muted); font-size: 12px; }
.status-hero { display: flex; align-items: center; gap: 14px; padding: 18px 20px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--surface); margin-bottom: 16px; }
.status-hero .big { font-size: 20px; font-weight: 650; }
.status-dot { width: 14px; height: 14px; border-radius: 50%; flex: none; }
.status-dot.good { background: var(--good); }
.status-dot.warning { background: var(--warning); }
.status-dot.critical { background: var(--critical); }

.grid-reports { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 16px; align-items: start; }
.grid-reports > .card, .grid-reports > div > .card { margin: 0; }
@media (max-width: 980px) { .grid-reports { grid-template-columns: 1fr; } }
tr.current td { background: var(--accent-wash); }
.field-label { color: var(--ink); }

/* legal notice */
.legal-list { display: grid; grid-template-columns: minmax(140px, max-content) 1fr; gap: 8px 20px; margin: 0; }
.legal-list dt { color: var(--muted); }
.legal-list dd { margin: 0; }
@media (max-width: 560px) { .legal-list { grid-template-columns: 1fr; gap: 2px; } .legal-list dd { margin-bottom: 8px; } }

/* password fields: show / hide button */
.with-reveal { position: relative; display: flex; }
.with-reveal input { flex: 1; padding-right: 42px; }
.with-reveal .reveal { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); width: 34px; height: 30px;
  padding: 0; display: grid; place-items: center; background: transparent; border: 0; color: var(--muted); cursor: pointer; border-radius: 6px; }
.with-reveal .reveal:hover { color: var(--ink); background: var(--surface-2); }
.with-reveal .reveal:focus-visible { outline: 2px solid var(--accent, #2a78d6); outline-offset: 1px; }
.with-reveal .reveal svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

/* two-factor setup (pages/twofactor.js): the QR code stays black on white in both themes, for scanners */
.twofa-steps { padding-left: 18px; }
.twofa-steps > li + li { margin-top: 12px; }
.qr-wrap { margin: 10px 0; width: min(240px, 100%); }
.qr { display: block; width: 100%; height: auto; border-radius: 6px; border: 1px solid var(--border); }
.resend { margin-top: 10px; }
.resend .alert { margin-top: 10px; }

/* language picker (top bar) */
.lang-picker { width: auto; padding: 4px 6px; font-size: 13px; }

/* white-label logo, checkbox rows, API docs */
.sso-row { display: flex; align-items: center; gap: 12px; margin-top: 12px; }
.sso-row button { flex: 1; }
.brand-logo { height: 24px; max-width: 140px; object-fit: contain; }
.check-row { display: flex; flex-wrap: wrap; gap: 6px 18px; }
.check-row .check { display: inline-flex; align-items: center; gap: 6px; font-weight: 400; }
.api-op { border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; margin: 8px 0; background: var(--surface); }
.api-op summary { cursor: pointer; display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.api-method { font: 600 12px ui-monospace, "Cascadia Mono", Consolas, monospace; padding: 1px 6px; border-radius: 4px; background: var(--accent-wash); color: var(--info-ink); min-width: 52px; text-align: center; }
.api-path { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; font-size: 13px; }
.api-schema { margin: 4px 0 8px; padding-left: 16px; font-size: 13px; }

/* investor report builder */
#investor-results > .card { margin-top: 16px; }
tr.selected td { font-weight: 600; background: color-mix(in srgb, var(--s1) 10%, transparent); }

/* battery control (js/pages/control.js) */
.switch { display: inline-flex; align-items: center; gap: 10px; font-size: 14px; font-weight: 600; color: var(--ink); cursor: pointer; margin: 8px 0; }
.switch input[type="checkbox"] { appearance: none; width: 40px; height: 22px; border-radius: 999px; background: var(--axis); position: relative; cursor: pointer; transition: background 0.15s; }
.switch input[type="checkbox"]::after { content: ""; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%; background: var(--surface); transition: left 0.15s; }
.switch input[type="checkbox"]:checked { background: var(--good); }
.switch input[type="checkbox"]:checked::after { left: 21px; }
.switch input[type="checkbox"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.switch input[type="checkbox"]:disabled { opacity: 0.5; cursor: not-allowed; }
.control-badge { text-decoration: none; margin-left: 6px; }

/* ------------------------------------------------------------------ twin board (js/pages/fleet.js, twin.js, fleetactions.js) */
/* Controller-phase washes behind the day chart, and their stronger legend keys. They derive from the series
   tokens, so the light and dark palettes both apply. Strategy aqua, manual violet, safety amber, default grey. */
:root {
  --phase-strategy: color-mix(in srgb, var(--s3) 13%, transparent);
  --phase-manual: color-mix(in srgb, var(--s4) 14%, transparent);
  --phase-safety: color-mix(in srgb, var(--warning) 22%, transparent);
  --phase-default: color-mix(in srgb, var(--muted) 16%, transparent);
  --phase-strategy-key: color-mix(in srgb, var(--s3) 55%, transparent);
  --phase-manual-key: color-mix(in srgb, var(--s4) 55%, transparent);
  --phase-safety-key: color-mix(in srgb, var(--warning) 70%, transparent);
  --phase-default-key: color-mix(in srgb, var(--muted) 55%, transparent);
}

.fleet-filters { align-items: center; }
.fleet-filters .spacer { flex: 1; }
.fleet-filters label.select-all { flex-direction: row; align-items: center; gap: 8px; font-size: 13px; color: var(--ink); font-weight: 600; min-height: 36px; cursor: pointer; }

.park-group { margin-bottom: 22px; }
.group-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; }
.park-head { padding: 4px 0 10px; border-bottom: 1px solid var(--border); margin-bottom: 12px; }
.park-head h2 { font-size: 18px; margin: 0; }
.site-group { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 14px 16px; margin-bottom: 14px; box-shadow: var(--shadow); }
.site-head { margin-bottom: 12px; }
.site-head h3 { margin: 0; font-size: 15px; }
.site-head h3 a { color: var(--ink); text-decoration: none; }
.site-head h3 a:hover { text-decoration: underline; }
.group-totals { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-left: auto; font-size: 13px; color: var(--ink-2); align-items: center; }
.fig-label { color: var(--muted); font-size: 12px; }
.fig strong { font-weight: 600; color: var(--ink); }

.unit-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: 12px; }
.fleet-board.compact .unit-grid { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 8px; }
.unit-card { position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 10px 12px; align-items: start; padding: 12px 12px 12px 36px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--page); cursor: pointer; transition: border-color 0.12s, box-shadow 0.12s; }
.unit-card:hover { border-color: var(--border-strong); }
.unit-card.selected { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); background: var(--accent-wash); }
/* The card's own outline shows the selection: the drawing's highlight ring would be a second one inside it. */
.unit-card .battery-art .ba-ring { display: none; }
.unit-card.stale .unit-art { opacity: 0.6; }
.unit-check { position: absolute; left: 4px; top: 4px; width: 30px; height: 30px; display: grid; place-items: center; cursor: pointer; }
.unit-art { width: 112px; min-height: 112px; display: grid; place-items: center; color: var(--ink-2); }
.unit-art svg { max-width: 100%; height: auto; display: block; }
.fleet-board.compact .unit-art { width: 64px; min-height: 64px; }
.unit-body { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.unit-title { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
a.unit-name { color: var(--ink); font-weight: 650; font-size: 15px; text-decoration: underline; text-decoration-color: var(--border-strong); text-underline-offset: 3px; }
a.unit-name:hover { text-decoration-color: currentColor; }
.unit-make { color: var(--ink-2); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.unit-figures { display: flex; flex-wrap: wrap; gap: 2px 14px; align-items: baseline; }
.unit-figures .fig.big strong { font-size: 20px; }
.unit-control { display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: center; font-size: 12px; }
.unit-meta { display: flex; flex-wrap: wrap; gap: 2px 12px; font-size: 12px; color: var(--ink-2); }
.fleet-board.compact .unit-meta, .fleet-board.compact .unit-make { display: none; }
.fleet-board.compact .unit-card { padding: 8px 8px 8px 34px; gap: 8px; }
.warn-text { color: var(--warning-ink); font-weight: 600; }
/* State pills are neutral (an orange or blue wash read like a warning); only the arrow carries the colour. */
.badge.charging { color: var(--ink); border-color: var(--border-strong); background: var(--surface); }
.badge.discharging { color: var(--ink); border-color: var(--border-strong); background: var(--surface); }
.badge.charging .badge-icon { color: var(--s2); font-weight: 800; }
.badge.discharging .badge-icon { color: var(--s1); font-weight: 800; }
.art-missing { font-size: 40px; color: var(--muted); }

/* the sticky action bar */
.action-bar { position: sticky; bottom: 0; z-index: 25; margin: 16px -12px 0; padding: 10px 12px calc(10px + env(safe-area-inset-bottom, 0px)); background: color-mix(in srgb, var(--surface) 94%, transparent); backdrop-filter: blur(8px); border: 1px solid var(--border-strong); border-radius: var(--radius) var(--radius) 0 0; box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.10); }
.action-bar-inner { display: flex; gap: 12px; align-items: flex-start; }
.action-bar-inner > .action-panel { flex: 1; min-width: 0; }
.action-bar .action-stage, .action-bar .action-why { max-height: 40vh; overflow-y: auto; }
.action-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 16px; margin-bottom: 8px; }
.action-now { margin: 0; }
.action-row { display: flex; flex-wrap: wrap; align-items: stretch; gap: 10px 14px; }
.action-group { display: flex; flex-direction: column; gap: 6px; padding: 8px 12px 10px; border: 1px solid var(--border); border-radius: var(--radius); }
.action-group-title { font-size: 12px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.action-group-body { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px 14px; flex: 1; }
.action-buttons button { display: inline-flex; align-items: center; gap: 6px; }
.action-icon { font-weight: 700; }
.action-icon.charge { color: var(--s2); }
.action-icon.discharge { color: var(--s1); }
.action-icon.idle, .action-icon.default_mode { color: var(--muted); }
.action-icon.follow_strategy { color: var(--good-ink); }
.action-summary { margin: 0; font-weight: 600; }
.action-inputs input[type="number"] { width: 6.5em; }
.action-why .alert, .action-stage .alert { margin: 10px 0 0; }
.target-list { margin: 6px 0 8px; padding-left: 18px; }
.action-results .target-list { list-style: none; padding-left: 2px; }
.target-list li.ok .badge-icon { color: var(--good-ink); }
.target-list li.failed .badge-icon { color: var(--critical-ink); }
.action-panel.compact .action-summary { display: none; }
.action-panel.compact .action-group { padding: 6px 8px 8px; }

/* the unit page (#/fleet/units/{id}): the battery's twin filling the main area */
.twin-head { display: flex; flex-wrap: wrap; gap: 12px 16px; align-items: center; padding-bottom: 14px; margin-bottom: 6px; border-bottom: 1px solid var(--border); }
.twin-art { flex: none; width: 72px; display: grid; place-items: center; color: var(--ink-2); }
.twin-art svg { max-width: 100%; height: auto; }
.twin-title { flex: 1; min-width: 16ch; }
.twin-title h1 { font-size: 24px; margin: 0; }
.twin-title h1 .sim-tag { margin-left: 6px; vertical-align: middle; }
.twin-title .sub { font-size: 13px; margin: 2px 0 0; }
.twin-body h2 { font-size: 17px; margin: 24px 0 8px; }
.twin-body .insight-head h2 { margin: 0; font-size: 17px; }
.twin-body .rev-history h2, .twin-body .sim-card h2 { margin-top: 24px; }
.twin-body h3 { font-size: 15px; margin: 18px 0 8px; }
.twin-body h4 { font-size: 13px; margin: 0 0 6px; color: var(--ink-2); }
.twin-badges { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; margin-bottom: 10px; font-size: 13px; }
.twin-day { margin: 12px 0 4px; }
.twin-view.simulated .twin-art { border-radius: 8px; background: repeating-linear-gradient(135deg, var(--sim-hatch) 0 2px, transparent 2px 9px); }
.twin-view.simulated .twin-art svg .ba-device { filter: grayscale(0.55) sepia(0.2) hue-rotate(180deg) saturate(1.4) opacity(0.92); }
.twin-view.simulated .twin-art svg.is-dim .ba-device { filter: grayscale(0.9); opacity: 0.5; }
.twin-onboarding { margin-bottom: 8px; }
.twin-onboarding h2 { display: flex; align-items: baseline; gap: 10px; }

/* the detail drawer (the catalogue's model panel) */
body.drawer-open { overflow: hidden; }
.drawer-backdrop { position: fixed; inset: 0; z-index: 40; background: rgba(0, 0, 0, 0.32); }
.drawer { position: fixed; top: 0; right: 0; bottom: 0; z-index: 45; width: min(780px, 100vw); background: var(--surface); border-left: 1px solid var(--border-strong); box-shadow: -8px 0 32px rgba(0, 0, 0, 0.18); display: flex; flex-direction: column; }
.drawer-head { display: flex; gap: 12px; align-items: center; padding: calc(14px + env(safe-area-inset-top, 0px)) 18px 14px; border-bottom: 1px solid var(--border); }
.drawer-art { flex: none; width: 72px; display: grid; place-items: center; color: var(--ink-2); }
.drawer-art svg { max-width: 100%; height: auto; }
.drawer-title { flex: 1; min-width: 0; }
.drawer-title h2 { font-size: 19px; margin: 0; }
.drawer-title .sub { font-size: 13px; }
.drawer-close { font-size: 18px; min-width: 40px; }
.drawer-body { overflow-y: auto; padding: 14px 18px calc(28px + env(safe-area-inset-bottom, 0px)); flex: 1; }
.drawer-body h3 { font-size: 15px; margin: 18px 0 8px; }
.drawer-body h4 { font-size: 13px; margin: 0 0 6px; color: var(--ink-2); }
.health-row { display: flex; flex-wrap: wrap; gap: 8px 28px; align-items: center; }
.spark-figure { margin: 0; }
.spark-figure figcaption { font-size: 12px; color: var(--muted); }
.sparkline { width: 160px; height: 36px; display: block; overflow: visible; }
.spark-line { fill: none; stroke: var(--s1); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.spark-dot { fill: var(--s1); stroke: var(--surface); stroke-width: 2; }
.share-bar { display: flex; gap: 2px; height: 10px; border-radius: 4px; overflow: hidden; margin-bottom: 8px; background: var(--grid); }
.share-bar span { display: block; min-width: 2px; }
.share-list { font-size: 13px; gap: 3px 14px; }
.share-list dt { display: inline-flex; align-items: center; gap: 6px; }
.share-grid { margin-top: 8px; }
.twin-events li { font-size: 13px; }
.event-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--axis); margin-top: 6px; flex: none; }
.event-dot.bad { background: var(--critical); }
.twin-events .wrap { overflow-wrap: anywhere; }

/* parks and battery units (js/pages/parks.js, units.js) */
.inline-create { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.inline-create input { flex: 1; min-width: 12em; }
.rename-cell { display: inline-flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.park-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; max-width: 640px; }
.park-row .field { flex: 1; min-width: 220px; }
tr.inactive-row td { color: var(--muted); }
.small-note { font-size: 12px; }

@media (max-width: 640px) {
  .group-totals { margin-left: 0; width: 100%; }
  .unit-grid { grid-template-columns: 1fr; }
  .fleet-board.compact .unit-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .unit-art { width: 84px; min-height: 84px; }
  .action-bar { margin-inline: -16px; }
  .action-bar-inner { flex-direction: column; gap: 6px; }
  .drawer-head { padding-inline: 12px; }
  .twin-head { gap: 10px 12px; }
  .drawer-body { padding-inline: 12px; }
}
@media (prefers-reduced-motion: reduce) { .unit-card { transition: none; } }

/* ------------------------------------------------------------------ battery catalogue, onboarding and simulation
   (js/pages/catalog.js, onboarding.js, simulation.js; docs/onboarding.md). Simulated batteries are told apart by a
   text tag with an icon, a dashed border and a hatched "blueprint" drawing: never by colour alone. */
:root { --sim: color-mix(in srgb, var(--s1) 70%, var(--ink-2)); --sim-hatch: color-mix(in srgb, var(--s1) 10%, transparent); }

.sim-tag { display: inline-flex; align-items: center; gap: 4px; padding: 1px 8px 1px 6px; border: 1px dashed var(--sim); border-radius: 999px; color: var(--info-ink); background: var(--surface); font-size: 11px; font-weight: 650; letter-spacing: 0.04em; line-height: 18px; white-space: nowrap; vertical-align: middle; }
.sim-icon { width: 12px; height: 12px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
.sim-fig { display: inline-flex; align-items: center; gap: 5px; color: var(--info-ink); font-weight: 500; }

.unit-tag { position: absolute; top: 8px; right: 8px; }
.unit-tag:empty { display: none; }
.unit-card.simulated { border-style: dashed; border-color: color-mix(in srgb, var(--s1) 55%, var(--border-strong)); padding-top: 34px; }
.unit-card.simulated .unit-art { border-radius: 8px; background: repeating-linear-gradient(135deg, var(--sim-hatch) 0 2px, transparent 2px 9px); }
/* The blueprint tint is on the device only: the energy flow keeps its true colours (orange in, blue out). */
.unit-card.simulated .unit-art svg .ba-device { filter: grayscale(0.55) sepia(0.2) hue-rotate(180deg) saturate(1.4) opacity(0.92); }
.fleet-board.compact .unit-card.simulated { padding-top: 32px; }
.unit-card.commissioning .unit-art { opacity: 0.75; }
a.commissioning-link { display: flex; flex-direction: column; gap: 4px; min-width: 0; width: 100%; color: var(--info-ink); font-weight: 600; font-size: 13px; text-decoration: none; padding: 2px 0; }
a.commissioning-link:hover .commissioning-text { text-decoration: underline; }
a.commissioning-link progress, .onb-progress { width: 100%; max-width: 220px; height: 6px; accent-color: var(--accent); }
.kind-filter { display: flex; flex-direction: column; gap: 4px; font-size: 12px; }
.kind-filter .filter-label { color: var(--ink-2); }

.unit-card.simulated .unit-art svg.is-dim .ba-device { filter: grayscale(0.9); opacity: 0.5; }
.sim-banner { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; border-style: dashed; }

/* the form */
.kind-field select { max-width: 320px; }
.model-picker { grid-column: 1 / -1; }
.datasheet-box:empty { display: none; }
.datasheet { border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 14px 12px; background: var(--surface-2); }
.datasheet h4 { margin: 0 0 8px; font-size: 13px; }
.datasheet-kv { font-size: 13px; gap: 3px 16px; grid-template-columns: max-content minmax(0, 1fr); }
.datasheet-sources { margin: 8px 0 0; font-size: 12px; overflow-wrap: anywhere; }
.secondary-note { margin: 8px 0 0; color: var(--warning-ink); }
details.advanced { margin-top: 0; }
details.advanced > .grid-fields, details.advanced > .field { margin-top: 10px; }
.kind-mismatch .actions { margin-top: 8px; }
.status-cell { display: inline-flex; flex-wrap: wrap; gap: 4px 8px; align-items: center; }

/* the onboarding view */
.onb-tags { display: flex; flex-wrap: wrap; gap: 6px 8px; align-items: center; margin: -4px 0 14px; font-size: 13px; }
.onb-tags code { overflow-wrap: anywhere; }
.onb-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin-bottom: 12px; }
.onb-progress-text { font-weight: 600; }
:is(.stepper, .diag-steps) { list-style: none; margin: 0 0 12px; padding: 0; }
:is(.stepper, .diag-steps) .step { position: relative; display: flex; gap: 12px; padding: 0 0 14px; }
:is(.stepper, .diag-steps) .step:not(:last-child)::before { content: ""; position: absolute; left: 13px; top: 28px; bottom: 2px; width: 2px; background: var(--grid); }
:is(.stepper, .diag-steps) .step.done:not(:last-child)::before { background: color-mix(in srgb, var(--good) 55%, var(--grid)); }
.step-mark { flex: none; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; font-size: 14px; font-weight: 700; border: 2px solid var(--axis); background: var(--surface); color: var(--muted); }
.step.done .step-mark { border-color: var(--good); color: var(--good-ink); background: color-mix(in srgb, var(--good) 10%, var(--surface)); }
.step.current .step-mark { border-color: var(--accent); }
.step.current .step-mark .spinner { width: 14px; height: 14px; }
.step.failed .step-mark { border-color: var(--critical); color: var(--critical-ink); }
.step-body { min-width: 0; padding-top: 4px; }
.step-title { display: flex; flex-wrap: wrap; gap: 2px 10px; align-items: baseline; }
.step.pending .step-title strong { color: var(--ink-2); font-weight: 500; }
.step-time { font-size: 12px; }
.step-detail { font-size: 13px; color: var(--ink-2); overflow-wrap: anywhere; }
.step.just-done .step-mark { animation: step-pop 0.5s ease-out; }
@keyframes step-pop { 0% { transform: scale(0.6); } 60% { transform: scale(1.15); } 100% { transform: scale(1); } }
.onboarding.compact .stepper .step { padding-bottom: 8px; }

/* Guided connection diagnostics (docs/onboarding.md): the stepper's look under its own class (the onboarding page
   holds both lists, so neither is found by the other's selector), with a status badge, the figures, the remedy
   and one action per step. The remedy is a tinted box so a failed step's fix is the first thing the eye lands on. */
.diag-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin-bottom: 12px; font-size: 13px; }
.diag-steps .step { padding-bottom: 18px; }
.diag-steps .step-title .badge.diag-status { font-weight: 500; }
.diag-steps .step.warn .step-mark { border-color: var(--warning); color: var(--warning-ink); background: color-mix(in srgb, var(--warning) 12%, var(--surface)); }
.diag-steps .step.warn:not(:last-child)::before { background: color-mix(in srgb, var(--warning) 55%, var(--grid)); }
.diag-steps .step.skipped .step-mark { border-style: dashed; }
.diag-message { color: var(--ink); }
.diag-figures { font-variant-numeric: tabular-nums; }
.diag-remedy { margin-top: 6px; padding: 8px 10px; border-radius: 8px; font-size: 13px; line-height: 1.45; border: 1px solid var(--border); background: var(--surface-2); color: var(--ink); overflow-wrap: anywhere; }
.diag-remedy.fail { border-color: color-mix(in srgb, var(--critical) 45%, transparent); background: color-mix(in srgb, var(--critical) 7%, var(--surface)); }
.diag-remedy.warn { border-color: color-mix(in srgb, var(--warning) 60%, transparent); background: color-mix(in srgb, var(--warning) 10%, var(--surface)); }
.diag-action { margin-top: 8px; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.diag-action:empty { display: none; }
.diag-action .hint { margin: 0; }
.diag-wait { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; }
.diag-wait .spinner { width: 14px; height: 14px; }
.diag-virtual { border-style: dashed; border-color: var(--sim); color: var(--info-ink); }
.diag-foot { display: grid; gap: 8px; }
.diag-foot .hint { margin: 0; }
.diag-skip { display: grid; gap: 6px; }
/* A pass that proves less than the step's question (a vendor whose idle is not a hold): informative, not a warning. */
.diag-remedy.caveat { border-color: color-mix(in srgb, var(--info-ink) 45%, transparent); background: color-mix(in srgb, var(--info-ink) 8%, var(--surface)); }
/* The declared part of the watchdog step (edge-agent sites): the acknowledgement Renew cannot measure. */
.diag-declared { margin-top: 6px; padding: 8px 10px; border-radius: 8px; font-size: 13px; line-height: 1.45; border: 1px dashed var(--border); background: var(--surface-2); color: var(--ink); overflow-wrap: anywhere; }
.diag-declared.confirmed { border-style: solid; border-color: color-mix(in srgb, var(--good) 45%, transparent); background: color-mix(in srgb, var(--good) 7%, var(--surface)); }
.diag-declared .diag-action { margin-top: 6px; }
.diag-ack-form { display: grid; gap: 6px; margin-top: 8px; }
.diag-ack-form .field { margin: 0; }
.diag-ack-form .field-error:empty { display: none; }
.diag-ack-row { display: flex; flex-wrap: wrap; align-items: end; gap: 8px 12px; }
.diag-ack-row .field { flex: 0 1 160px; }
.diag-link { margin: 0 0 12px; }
@media (max-width: 480px) {
  .diag-steps .step { gap: 8px; }
  .diag-action { flex-direction: column; align-items: stretch; }
  .diag-action .confirm-wrap { display: grid; gap: 6px; }
  .diag-ack-row { flex-direction: column; align-items: stretch; }
  .diag-ack-row .field { flex: 1 1 auto; }
}
.onb-instructions { margin-top: 18px; }
.onb-instructions h3 { font-size: 15px; margin: 0 0 8px; }
.onb-howto { padding-left: 20px; margin: 0; }
.onb-howto > li { margin-bottom: 14px; }
.onb-howto p { margin: 0 0 6px; }
.code-wrap { position: relative; margin: 4px 0 8px; }
.code-wrap .code-block { margin: 0; padding-right: 76px; max-height: 360px; overflow: auto; }
.code-tools { position: absolute; top: 6px; right: 6px; z-index: 1; }
.onb-command .hint { margin: 4px 0 2px; }

/* the Simulation card */
.sim-card { border: 1px dashed color-mix(in srgb, var(--s1) 55%, var(--border-strong)); border-radius: var(--radius); padding: 2px 14px 14px; margin-top: 14px; }
.sim-card h3 { margin-top: 12px; }
.sim-card h4 { margin: 14px 0 6px; }
.sim-figs { display: flex; flex-wrap: wrap; gap: 4px 18px; font-size: 13px; }
.sim-state .hint { margin: 0 0 4px; }
.sim-events li { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; font-size: 13px; }
.sim-inject, .sim-settings { display: flex; flex-direction: column; gap: 8px; }
.sim-inject .hint, .sim-settings .hint { margin: 0; }
.sim-inject select { max-width: 280px; }
label.check-inline { display: inline-flex; flex-direction: row; align-items: center; gap: 8px; font-size: 13px; color: var(--ink); }
.sim-params:empty { display: none; }

@media (max-width: 640px) {
  .code-wrap .code-block { padding-right: 10px; padding-top: 40px; }
}
@media (prefers-reduced-motion: reduce) { .step.just-done .step-mark { animation: none; } }

/* the Catalogue section (js/pages/catalogpage.js) */
.catalog-filters { align-items: flex-end; }
.catalog-filters .spacer { flex: 1; }
.catalog-search input { min-width: 14em; }
.catalog-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 12px; }
.catalog-card { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 10px 12px; padding: 12px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow); cursor: pointer; }
.catalog-card:hover { border-color: var(--border-strong); }
.catalog-art { width: 88px; min-height: 88px; display: grid; place-items: center; align-self: start; color: var(--ink-2); }
button.catalog-name { align-self: flex-start; justify-content: flex-start; }
.catalog-art svg { max-width: 100%; height: auto; }
.catalog-card-body { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.catalog-make { font-size: 12px; }
.catalog-pills { display: flex; flex-wrap: wrap; gap: 4px 6px; align-items: center; font-size: 12px; }
.catalog-kv { font-size: 13px; gap: 2px 12px; margin-top: 4px; }
.catalog-conn { font-size: 12px; color: var(--ink-2); overflow-wrap: anywhere; }
.catalog-drawer .datasheet { margin-top: 8px; }
.catalog-price { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 6px; }
.catalog-price-amount { font-variant-numeric: tabular-nums; }
.badge.price-basis { cursor: help; }
.catalog-price-card { margin-top: 12px; }
.catalog-price-card h3 { margin: 0 0 6px; font-size: 14px; }
.catalog-price-head { margin: 0 0 8px; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: 15px; }
.catalog-price-card .hint { margin: 8px 0 0; }
.catalog-add { margin-top: 18px; padding-top: 4px; border-top: 1px solid var(--border); }
tr.default-row td { font-weight: 600; }
a.ext-link .ext-icon { font-size: 0.9em; }
.datasheet-notes { margin-top: 8px; font-size: 12px; }
.datasheet-notes p { margin: 6px 0 0; color: var(--ink-2); }
@media (max-width: 640px) {
  .catalog-grid { grid-template-columns: 1fr; }
  .catalog-search input { min-width: 0; width: 100%; }
}

/* the catalogue review (js/pages/catalogreview.js): curators' tab, candidates, pending changes; the add form's
   "Suggest this model to Renew" */
.catalog-tabs { display: flex; gap: 4px; margin: -4px 0 16px; border-bottom: 1px solid var(--border); }
.catalog-tabs .tab { padding: 8px 14px; color: var(--ink-2); text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.catalog-tabs .tab:hover { color: var(--ink); }
.catalog-tabs .tab.active { color: var(--info-ink); border-bottom-color: var(--accent); font-weight: 600; }
.catalog-tabs .tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.catalog-review-bar { margin-bottom: 14px; align-items: center; }
.review-item { padding: 12px 0; border-top: 1px solid var(--border); }
.review-item:first-of-type { border-top: 0; padding-top: 0; }
.review-item h3 { font-size: 15px; margin: 0 0 4px; }
.review-item h4 { font-size: 13px; margin: 10px 0 6px; color: var(--ink-2); }
.review-item .actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.review-specs { margin: 6px 0; font-size: 13px; }
.review-listings { margin: 6px 0; font-size: 13px; }
.review-link { margin-top: 10px; padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--page); }
.review-link p { margin: 0 0 6px; overflow-wrap: anywhere; }
.review-editor { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--border-strong); }
.review-editor textarea { width: 100%; }
.catalog-links { margin: 6px 0; padding-left: 18px; font-size: 13px; overflow-wrap: anywhere; }
.catalog-links s { color: var(--critical-ink); }
.suggest-model { margin-top: 6px; font-size: 13px; }

/* ------------------------------------------------------------------ revenue history (docs/timelapse.md §3) */

.rev-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 16px; margin: 16px 0 8px; }
.rev-head h2, .rev-head h3 { margin: 0; }
.rev-picker { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--ink-2); }
.rev-virtual { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; color: var(--ink-2); font-size: 13px; }
.rev-sub { display: flex; align-items: center; gap: 6px; margin: 22px 0 6px; padding-top: 12px; border-top: 1px solid var(--border); }
.rev-body.is-loading { opacity: 0.6; }
.rev-card .rev-head { margin-top: 0; }
.park-history { padding: 4px 16px 12px; margin: -4px 0 16px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
.park-history .rev-head { margin-top: 10px; }

/* ------------------------------------------------------------------ time-lapse (docs/timelapse.md §4) */

.timelapse-slot { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.timelapse-slot[hidden] { display: none; }
.tl-badge { text-decoration: none; font-variant-numeric: tabular-nums; }
.tl-badge:hover { text-decoration: underline; }
.tl-clock { padding: 6px 0 10px; }
.tl-clock-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 16px; }
.tl-clock-time { font-size: 44px; font-weight: 600; line-height: 1.1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.tl-clock-speed { font-size: 22px; font-weight: 600; color: var(--ink-2); }
.tl-progress { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin-top: 8px; font-size: 13px; }
.tl-progress progress { width: min(420px, 100%); height: 8px; accent-color: var(--now); }
.tl-controls { align-items: center; }

/* ------------------------------------------------------------------ track record (docs/track-record.md) */

.job-progress { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 4px 0 10px; }
.job-progress progress { width: min(420px, 100%); height: 8px; accent-color: var(--accent); }
/* A failed background report in a list: the badge, then its short reason (the whole error as the tooltip). */
.job-failed { display: inline-flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.job-reason { max-width: 36ch; white-space: normal; overflow-wrap: anywhere; }
.tr-headline .tiles { margin-bottom: 8px; }
.tr-headline .actions select { min-height: 36px; }
.shared-report .page-head { margin-top: 8px; }
/* Installer proposals (docs/installer-proposals.md) */
.brand-head { padding-bottom: 8px; margin-bottom: 8px; }
.proposal-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.proposal-row select, .proposal-row input { max-width: 100%; }
.proposal-sources { padding-left: 1.1em; margin: 8px 0 0; color: var(--muted, inherit); }
.inline-label { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; }
.tl-setup fieldset { border: 0; padding: 0; margin: 14px 0 6px; min-width: 0; }
.tl-setup legend { font-weight: 600; font-size: 13px; padding: 0; margin-bottom: 6px; }
.tl-modes { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 8px; }
.tl-modes legend { grid-column: 1 / -1; }
.radio-card { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); cursor: pointer; }
.radio-card:has(input:checked) { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.radio-card span { display: flex; flex-direction: column; gap: 2px; }
.tl-soc { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
.tl-soc input[type="number"] { width: 5.5em; }
.tl-units .unit-card { cursor: default; }
.tl-units .unit-name-text { font-size: 14px; }
.tl-picker { margin-bottom: 4px; }
@media (max-width: 520px) { .tl-clock-time { font-size: 34px; } }

/* Several days (docs/timelapse.md "Several days" and §6): the setup's durations, the problem notice, the viewport
   bar, the overview strip, the per-day revenue and the comparison of the two modes. */
.tl-when .controls { margin-top: 8px; }
.tl-when input[type="number"] { width: 5.5em; }
.tl-durations { margin-bottom: 4px; }
.tl-problem:empty { display: none; }
.tl-problem { margin: 6px 0; }
.tl-totals-card .tiles { margin-bottom: 4px; }
.tl-viewbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; margin: 6px 0 2px; }
.tl-viewbar[hidden] { display: none; }
.tl-view-nav { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tl-view-label { font-size: 13px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.tl-charts { touch-action: pan-y; } /* a horizontal swipe browses the session; the page still scrolls vertically */
.tl-charts.dragging { cursor: grabbing; user-select: none; }
.tl-charts.dragging .chart .hit { cursor: grabbing; }
.tl-overview { margin: 4px 0 2px; }
.tl-overview-svg { display: block; width: 100%; height: auto; overflow: visible; }
.tl-overview-svg .hit { fill: transparent; cursor: pointer; }
.tl-overview-svg .grid { stroke: var(--grid); stroke-width: 1; }
.tl-overview-svg .tl-day-sep { stroke: var(--axis); stroke-width: 1; stroke-dasharray: 2 3; }
.tl-overview-svg .tl-overview-soc { stroke: var(--s3); }
/* The viewport: a translucent wash under the state-of-charge curve, the frame and its handles above it. */
.tl-overview-svg .tl-viewport-wash { fill: var(--viewport-wash); pointer-events: none; }
.tl-overview-svg .tl-viewport { fill: none; stroke: var(--accent); stroke-width: 1.5; pointer-events: none; }
.tl-overview-svg .tl-viewport-handle { fill: var(--accent); stroke: var(--surface); stroke-width: 1; pointer-events: none; }
.tl-overview-svg .tl-overview-now { stroke: var(--now); stroke-width: 2; pointer-events: none; }
/* The time ruler under the strip: hours in the site's zone, the date under the midnight ticks. */
.tl-overview-svg .tl-ruler-tick { stroke: var(--axis); stroke-width: 1; }
.tl-overview-svg .tl-ruler-tick.major { stroke: var(--muted); }
.tl-overview-svg .tl-ruler-text { fill: var(--muted); font-size: 10px; font-variant-numeric: tabular-nums; }
.tl-overview-svg .tl-ruler-date { fill: var(--ink-2); font-weight: 600; }
.tl-overview-caption { margin: 2px 0 0; font-size: 12px; color: var(--muted); }
.tl-days-card .legend { margin-top: 0; }
.tl-days-table .total { font-weight: 600; border-top: 1px solid var(--axis); }
.tl-compare { margin: 14px 0 6px; padding: 10px 14px 4px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-2); }
.tl-compare h4 { margin: 0 0 4px; }
/* The dates under the midnight ticks (docs/timelapse.md §6): a second, smaller line. */
.chart .tick-day { font-weight: 600; fill: var(--ink-2); }
.chart .tick-sub { font-size: 10px; fill: var(--muted); }

/* ------------------------------------------------------------------ what's happening (js/pages/insight.js,
   docs/control-insight.md §5): the one-line insight on cards and headers, and the "What's happening" card. The phase
   is always said in words (and an icon); the colour only repeats it. */

.insight-line { display: grid; grid-template-columns: 16px minmax(0, 1fr); align-items: start; gap: 3px 6px; font-size: 12px; color: var(--ink-2); min-width: 0; }
.insight-line .insight-icon { flex: none; width: 16px; height: 16px; display: inline-grid; place-items: center; border-radius: 50%; font-size: 10px; font-weight: 700; line-height: 1; background: var(--surface-2); border: 1px solid var(--border); }
.insight-line.good .insight-icon { color: var(--good-ink); border-color: color-mix(in srgb, var(--good) 40%, transparent); }
.insight-line.warning .insight-icon { color: var(--warning-ink); border-color: color-mix(in srgb, var(--warning) 60%, transparent); background: color-mix(in srgb, var(--warning) 14%, var(--surface)); }
.insight-line.critical .insight-icon { color: var(--critical-ink); border-color: color-mix(in srgb, var(--critical) 45%, transparent); }
.insight-line.info .insight-icon { color: var(--info-ink); border-color: color-mix(in srgb, var(--accent) 35%, transparent); }
.insight-line.warning .insight-text { color: var(--warning-ink); font-weight: 600; }
.insight-text { min-width: 0; overflow-wrap: anywhere; }
.insight-mini { grid-column: 2; width: 100%; max-width: 160px; }
.insight-line .insight-icon { margin-top: 1px; }
/* The phase progress bars: a light track and the phase colour, the same in every browser and theme. */
.insight-mini, .insight-progress progress { appearance: none; -webkit-appearance: none; border: 0; border-radius: 999px; overflow: hidden; background: var(--grid); color: var(--accent); }
.insight-mini { height: 4px; }
.insight-mini::-webkit-progress-bar, .insight-progress progress::-webkit-progress-bar { background: var(--grid); border-radius: 999px; }
.insight-mini::-webkit-progress-value, .insight-progress progress::-webkit-progress-value { background: currentColor; border-radius: 999px; }
.insight-mini::-moz-progress-bar, .insight-progress progress::-moz-progress-bar { background: currentColor; border-radius: 999px; }
.insight-line.warning .insight-mini, .insight-card[data-phase="safety"] .insight-progress progress { color: color-mix(in srgb, var(--warning) 60%, var(--warning-ink)); }
.insight-line.good .insight-mini, .insight-card[data-phase="strategy"] .insight-progress progress { color: var(--good); }
.site-insight { flex-basis: 100%; order: 10; }
.site-insight:empty { display: none; }
.site-insight .insight-line { font-size: 13px; }
.unit-insight:empty { display: none; }

.insight-card { border: 1px solid var(--border); border-left: 4px solid var(--axis); border-radius: var(--radius); background: var(--surface); padding: 12px 14px 10px; margin: 0 0 14px; min-width: 0; }
.insight-card[data-phase="strategy"] { border-left-color: var(--good); }
.insight-card[data-phase="manual"], .insight-card[data-phase="onboarding"] { border-left-color: var(--accent); }
.insight-card[data-phase="safety"] { border-left-color: var(--warning); background: color-mix(in srgb, var(--warning) 5%, var(--surface)); }
.insight-card[data-phase="no_link"] { border-left-color: var(--critical); }
.insight-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin-bottom: 4px; }
.insight-head h3, .insight-head h2 { margin: 0; font-size: 15px; }
.insight-headline { margin: 0 0 4px; font-weight: 600; font-size: 15px; color: var(--ink); overflow-wrap: anywhere; }
.insight-detail, .insight-summary { margin: 0 0 6px; color: var(--ink-2); font-size: 13px; overflow-wrap: anywhere; }
.insight-events { list-style: none; margin: 4px 0 8px; padding: 0; display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
/* "Why this plan" (docs/plan-explanations.md): the plan's blocks as steps, the mark coloured by kind. */
.plan-why-section { margin: 6px 0 14px; }
.plan-why-section h3 { margin-bottom: 2px; }
.plan-why { margin: 8px 0 4px; }
.plan-why .step { padding-bottom: 8px; gap: 10px; }
.plan-why .step:not(:last-child)::before { left: 11px; top: 24px; }
.plan-why .step-mark { width: 24px; height: 24px; font-size: 12px; }
.plan-why .step-body { padding-top: 2px; }
.plan-why .step-title strong { font-weight: 500; }
.plan-why .step-time { font-variant-numeric: tabular-nums; white-space: nowrap; }
.plan-why .why-charge .step-mark { border-color: var(--s2); color: var(--s2); }
.plan-why .why-discharge .step-mark { border-color: var(--s1); color: var(--s1); }
.plan-why .why-minor .step-mark { border-color: var(--muted); color: var(--muted); }
.plan-why .why-curtail .step-mark { border-color: var(--s3); color: var(--s3); }
.plan-why .why-reserve .step-mark { border-color: var(--s4); color: var(--s4); }
.plan-why .why-end .step-mark { border-color: var(--accent); color: var(--accent); }
.plan-why .why-hold .step-mark { border-color: var(--warning); color: var(--warning-ink); }
.today-why { font-size: 13px; }
.today-why .plan-why { margin-top: 6px; }
.insight-steps { margin: 8px 0 4px; }
.insight-steps .step { padding-bottom: 8px; gap: 10px; }
.insight-steps .step:not(:last-child)::before { left: 11px; top: 24px; }
.insight-steps .step-mark { width: 24px; height: 24px; font-size: 12px; }
.insight-steps .step-body { padding-top: 2px; }
.insight-steps .step-status { font-size: 12px; color: var(--muted); }
.insight-steps .step.current .step-status { color: var(--info-ink); font-weight: 600; }
.insight-steps .step.failed .step-status { color: var(--critical-ink); font-weight: 600; }
.insight-progress { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; margin: 4px 0 8px; }
.insight-progress progress { width: min(320px, 100%); height: 8px; }
.insight-timing { margin: 0; font-size: 13px; color: var(--ink-2); display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.insight-when { font-variant-numeric: tabular-nums; color: var(--ink); }
.insight-basis { font-size: 12px; color: var(--muted); }
.insight-actions { margin-top: 4px; align-items: center; }
.insight-actions[hidden] { display: none; }
.insight-actions .hint { font-size: 12px; }
.insight-stage:empty { display: none; }
.insight-stage { margin-top: 8px; }
.insight-card[hidden], .insight-card [hidden] { display: none !important; }

/* Bold arrow icons in state pills (charging ↓ / discharging ↑). */
.badge-icon .badge-arrow { width: 0.95em; height: 0.95em; vertical-align: -0.12em; fill: none; stroke: currentColor;
  stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }

/* France (docs/france.md): the capacity stream in the settlement chart, and the connection's restrictions and the PP hours
   shaded on the plan chart. */
:root {
  --s5: #9a6a12;
  --band-grid: color-mix(in srgb, var(--critical) 11%, transparent);
  --band-grid-key: color-mix(in srgb, var(--critical) 55%, transparent);
  --band-pp: color-mix(in srgb, var(--s5) 15%, transparent);
  --band-pp-key: color-mix(in srgb, var(--s5) 60%, transparent);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --s5: #d6a440; }
}
:root[data-theme="dark"] { --s5: #d6a440; }
/* Local flexibility (docs/local-flexibility.md): its settlement stream, and the windows held and the activations on the
   plan chart. */
:root {
  --s6: #1f7a72;
  --band-flex: color-mix(in srgb, var(--s6) 12%, transparent);
  --band-flex-act: color-mix(in srgb, var(--s6) 28%, transparent);
  --band-flex-key: color-mix(in srgb, var(--s6) 60%, transparent);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --s6: #4fc2b6; }
}
:root[data-theme="dark"] { --s6: #4fc2b6; }
/* "Demande à Renew" (js/pages/assistant.js, docs/assistant.md): a launcher and a side panel on the site and
   portfolio pages. Text in text colours; the accent marks the user's own messages. */
.assistant-bar { display: flex; justify-content: flex-end; margin: -6px 0 6px; }
.assistant-launcher { display: inline-flex; align-items: center; gap: 8px; border-radius: 999px; padding: 6px 14px; }
.assistant-mark { font-size: 14px; line-height: 1; }
.assistant-panel { position: fixed; top: 0; right: 0; bottom: 0; z-index: 45; width: min(440px, 100vw); display: flex; flex-direction: column; background: var(--surface); border-left: 1px solid var(--border-strong); box-shadow: var(--shadow); padding: 12px 14px calc(12px + env(safe-area-inset-bottom, 0px)); gap: 8px; }
.assistant-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.assistant-title { display: inline-flex; align-items: center; gap: 8px; font-size: 16px; }
.assistant-title .assistant-mark { color: var(--accent); }
.assistant-close { font-size: 16px; min-width: 36px; }
.assistant-tools { display: flex; gap: 6px; align-items: center; }
.assistant-tools [hidden] { display: none; }
.assistant-history { flex: 1; min-width: 0; }
.assistant-note { margin: 0; font-size: 12px; color: var(--muted); }
.assistant-log { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 10px; padding: 4px 2px; min-height: 120px; }
.assistant-msg { border-radius: 10px; padding: 8px 12px; max-width: 92%; font-size: 14px; line-height: 1.45; color: var(--ink); }
.assistant-msg p { margin: 0 0 6px; white-space: pre-wrap; overflow-wrap: anywhere; }
.assistant-msg p:last-child { margin-bottom: 0; }
.assistant-msg ul { margin: 4px 0 6px; padding-left: 18px; }
.assistant-msg.user { align-self: flex-end; background: var(--accent-wash); border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent); }
.assistant-msg.bot { align-self: flex-start; background: var(--surface-2); border: 1px solid var(--border); }
.assistant-msg.pending { display: inline-flex; align-items: center; gap: 8px; color: var(--ink-2); }
.assistant-msg.error { border-color: color-mix(in srgb, var(--critical) 45%, transparent); color: var(--critical-ink); }
.assistant-sources-head { margin-top: 8px; font-size: 12px; font-weight: 600; color: var(--ink-2); }
.assistant-sources { margin: 2px 0 0; padding-left: 18px; font-size: 13px; }
.assistant-sources a { overflow-wrap: anywhere; }
.assistant-meta { margin: 6px 0 0; font-size: 12px; color: var(--muted); }
.assistant-suggestions { display: flex; flex-wrap: wrap; gap: 6px; }
.assistant-chip { background: var(--surface); color: var(--ink); border: 1px solid var(--border-strong); border-radius: 999px; padding: 6px 12px; font-size: 13px; font-weight: 400; text-align: left; white-space: normal; }
.assistant-chip:hover { background: var(--accent-wash); }
.assistant-form { display: flex; gap: 8px; align-items: flex-end; }
.assistant-form[hidden] { display: none; }
.assistant-form textarea { flex: 1; resize: vertical; min-height: 44px; max-height: 160px; }
@media (max-width: 520px) { .assistant-panel { width: 100vw; border-left: 0; } }

/* Comptabilité (js/pages/accounting.js) */
.filters.plain { background: none; border: 0; padding: 0; margin: 4px 0 10px; }
tr.flagged td { background: color-mix(in srgb, var(--warning) 7%, transparent); }
tr.total-row td { border-top: 1px solid var(--border-strong); }
/* ------------------------------------------------------------------ the phone (docs/mobile.md) */

/* Today: the compact home, laid out for ~400 px first. */
.today-head { margin-bottom: 12px; }
/* The summary table: a row per kind of site (real, virtual), a column per figure (realised, forecast, tomorrow); in
   each cell the € first and the energy sold and bought as a pair under it (side by side, stacked on a phone). The
   cells wrap rather than widen, so the table fits 400 px; .table-wrap scrolls sideways should it still overflow. */
.today-summary { margin-bottom: 14px; }
.today-table { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
.today-table table { table-layout: fixed; }
.today-table th, .today-table td { white-space: normal; vertical-align: top; padding: 8px 10px; position: static; }
.today-table th:first-child { width: 20%; }
.today-table tbody th { font-weight: 600; font-size: 13px; color: var(--ink); }
.today-table tbody th .badge { display: inline-flex; margin-top: 4px; }
.today-table tbody tr:last-child :is(th, td) { border-bottom: 0; }
.today-table tbody tr:hover td { background: transparent; }
.today-cell-eur { font-size: 20px; font-weight: 650; line-height: 1.2; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.today-cell-energy { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px 10px; margin-top: 4px; font-size: 12px; font-variant-numeric: tabular-nums; }
.today-cell-energy .lbl { display: block; font-size: 11px; color: var(--ink-2); }
.today-cell-energy .val { color: var(--ink); overflow-wrap: anywhere; }
.today-cell-note { margin-top: 4px; font-size: 11px; color: var(--muted); }
/* Under a site card's forecast: what the plan still holds, or why there is none. */
.today-money .today-sub { display: block; font-size: 11px; font-weight: 400; color: var(--muted); }
.today-sites { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr)); gap: 12px; }
.today-site { margin: 0; padding: 14px; display: flex; flex-direction: column; gap: 10px; }
.today-site-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.today-site-head :is(h2, h3) { margin: 0; font-size: 17px; flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.today-site-head :is(h2, h3) a { color: var(--ink); text-decoration: none; }
.today-site-head :is(h2, h3) a:hover { text-decoration: underline; }
.today-country + .today-country { margin-top: 20px; }
.today-country-title { margin: 0 0 10px; font-size: 15px; color: var(--ink-2); text-transform: uppercase; letter-spacing: .04em; }
/* A country heading row in a table of sites (the overview). */
tr.group-row td { background: var(--surface-2, transparent); padding-top: 14px; border-bottom-color: var(--border); }
.today-money { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; margin: 0; }
.today-money > div { min-width: 0; }
.today-money dt { font-size: 11px; color: var(--ink-2); }
.today-money dd { margin: 0; font-size: 17px; font-weight: 600; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.today-money dd .muted { font-size: 13px; font-weight: 400; }
.today-now { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; padding-top: 8px; border-top: 1px solid var(--grid); }
.today-headline { margin: 0; font-size: 14px; color: var(--ink); overflow-wrap: anywhere; }
.today-now .insight-line { width: 100%; }
.today-alerts { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
.today-site .hint { margin: 0; }
.today-actions .confirm-wrap { display: inline-flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.today-stage:empty { display: none; }
.today-stage .alert { margin: 8px 0 0; }
.today-stamp { margin-top: 12px; }
@media (max-width: 520px) {
  .today-table th, .today-table td { padding: 6px; }
  .today-table th:first-child { width: 22%; }
  .today-cell-eur { font-size: 15px; }
  .today-cell-energy { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .today-money dd { font-size: 15px; }
  .today-actions button, .today-actions .button { min-height: 40px; }
}

/* Offline: the banner over the app, and the page shown when the app isn't cached yet. */
.offline-banner { position: sticky; top: 0; z-index: 30; padding: 8px 16px; font-size: 13px; color: var(--ink);
  background: color-mix(in srgb, var(--warning) 22%, var(--surface)); border-bottom: 1px solid color-mix(in srgb, var(--warning) 60%, transparent); }
.update-banner { background: color-mix(in srgb, var(--accent) 14%, var(--surface)); border-bottom-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.update-banner .link { font-weight: 600; }
.offline-page { max-width: 560px; }
.offline-card h1 { margin-top: 0; font-size: 22px; }
.offline-card h2 { font-size: 15px; margin: 16px 0 4px; }

/* Notification settings. */
.push-prefs fieldset { border: 0; padding: 0; margin: 0 0 16px; min-width: 0; }
.push-prefs legend { font-weight: 600; margin-bottom: 6px; padding: 0; }
.push-check { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 2px 10px; align-items: start; padding: 6px 0; }
.push-check input { margin-top: 3px; width: 18px; height: 18px; }
.push-check label { display: flex; flex-direction: column; gap: 1px; }
.push-check .hint { font-size: 12px; }
.push-quiet { margin: 4px 0 6px 28px; }
.push-prefs [hidden] { display: none !important; }
.inline-field { display: inline-flex; align-items: center; gap: 8px; }
.push-recent li .badge { flex: none; }
/* The peer benchmark (docs/benchmark.md) */
.bm-cohort { margin: 0 0 12px; }
.bm-foot { margin-top: 16px; }
.bm-foot button { margin-top: 8px; }
.bm-card td.wrap { white-space: normal; max-width: 420px; }
/* Monthly statements and bankability (docs/monthly-statement.md, docs/bankability.md). */
.inline-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; margin-top: 14px; }
.inline-form .field { margin: 0; min-width: 0; }
.notable { margin: 0; padding-left: 1.2em; }
.notable li { margin: 0 0 8px; line-height: 1.5; }
.tr-headline .notice { margin-top: 10px; }
/* The what-if simulator and the offer comparator (docs/what-if.md, docs/offer-comparison.md). */
button[hidden], .button[hidden] { display: none; }
.whatif-summary { margin: 0; padding-left: 18px; display: grid; gap: 6px; font-size: 15px; }
td.strong { font-weight: 600; }
.apply-row { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 12px;
  padding: 10px 0; border-top: 1px solid var(--border); }
.apply-row:first-of-type { border-top: 0; }
.apply-row .hint { margin: 2px 0 0; }
.card.flat { box-shadow: none; background: var(--surface-2); }

/* Plan approval (docs/plan-approval.md): the panel on the site page and the waiting list on Today / the portfolio. */
.approval-status { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 6px; }
.approval-countdown { font-variant-numeric: tabular-nums; color: var(--ink-2); font-weight: 600; }
.approval-countdown.passed { color: var(--critical-ink); }
.approval-input { width: 6.5em; text-align: right; font-variant-numeric: tabular-nums; }
.approval-input.changed { border-color: var(--s2); background: color-mix(in srgb, var(--s2) 8%, var(--surface)); }
.approval-input.invalid { border-color: var(--critical); }
.approval-grid { max-height: 420px; }
.approval-issue { color: var(--critical-ink); white-space: nowrap; }
.approval-card .gain { color: var(--good-ink); }
.approval-card .loss { color: var(--critical-ink); }
.approval-decision { margin-top: 10px; }
.approval-comment { display: flex; flex-direction: column; gap: 4px; max-width: 640px; }
.approval-comment textarea { width: 100%; }

/* The phone's approval screen (docs/plan-approval.md "From the phone"): one column, thumb-sized buttons, the
   confirmation sheet under them. */
.approve-screen { max-width: 720px; }
.approve-screen .gain { color: var(--good-ink); }
.approve-screen .loss { color: var(--critical-ink); }
.approve-deadline { font-variant-numeric: tabular-nums; color: var(--ink-2); font-weight: 600; }
.approve-why > h2 { margin-top: 0; }
.approve-buttons { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 6px; }
.approve-buttons button { min-height: 48px; font-size: 16px; }
.approve-sheet:not(:empty) { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); }
.approve-confirm h3 { margin: 0 0 8px; }
.approve-confirm .field textarea, .approve-confirm .field input { width: 100%; }
.approve-stepup button:not(.ghost) { min-height: 48px; font-size: 16px; flex: 1 1 auto; }
.approve-code .form-actions button { min-height: 48px; font-size: 16px; width: 100%; }
.passkey-list { list-style: none; padding: 0; margin: 0 0 10px; display: flex; flex-direction: column; gap: 6px; }
.passkey-list li { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
@media (max-width: 520px) { .approve-buttons { grid-template-columns: 1fr; } }
.approval-history ol { margin: 6px 0 0; padding-left: 1.2em; font-size: 13px; }

/* Terms, privacy policy and DPA (docs/legal-pages.md) */
.legal-doc { line-height: 1.6; }
.legal-doc h2 { font-size: 17px; margin: 22px 0 8px; }
.legal-doc blockquote { margin: 0 0 16px; padding: 10px 14px; border-left: 4px solid var(--warning); background: var(--surface-2); border-radius: 4px; }
.legal-doc .table-wrap { overflow-x: auto; margin: 8px 0 16px; }
.legal-doc table { width: 100%; }
.sidenav .legal-links { display: flex; flex-wrap: wrap; gap: 4px 10px; }
.sidenav .legal-links a { color: var(--muted); }
.legal-rows { list-style: none; padding: 0; margin: 0; display: grid; gap: 12px; }
.legal-row .muted { font-size: 13px; margin: 2px 0 6px; }
.field.check a { text-decoration: underline; }

/* The Operate trial's "Get started" checklist (docs/trial.md) */
.trial-cta { margin-top: 12px; display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.trial-steps { list-style: none; padding: 0; margin: 10px 0; display: grid; gap: 8px; }
.trial-steps li { display: grid; grid-template-columns: 26px minmax(0, 1fr) auto; gap: 10px; align-items: start; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.trial-steps li p { margin: 2px 0 0; }
.trial-steps li.done strong { color: var(--ink-2); }
.trial-tick { display: inline-flex; width: 22px; height: 22px; border-radius: 50%; align-items: center; justify-content: center; border: 2px solid var(--border); font-weight: 700; font-size: 13px; }
.trial-steps li.done .trial-tick { background: var(--accent-wash); border-color: transparent; color: var(--info-ink); }
.trial-nudge { margin-top: 10px; }
.trial-nudge p { margin: 0 0 6px; }

/* Maintenance planner (docs/maintenance-planner.md): the site card's jobs and the calendar grid */
.mt-jobs { display: grid; gap: 16px; }
.mt-job { border-top: 1px solid var(--border); padding-top: 12px; }
.mt-job-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.mt-job-head h3 { margin: 0; font-size: 15px; }
.mt-units { display: flex; flex-wrap: wrap; gap: 6px 16px; border: 0; padding: 0; margin: 8px 0; }
.mt-units legend { font-weight: 600; margin-bottom: 4px; }
.mt-cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.mt-cal-head { font-size: 12px; font-weight: 600; color: var(--muted); text-align: center; }
.mt-cal-day { min-height: 68px; border: 1px solid var(--border); border-radius: 6px; padding: 4px; background: var(--surface); overflow: hidden; }
.mt-cal-day.today { border-color: var(--accent); }
.mt-cal-date { font-size: 11px; color: var(--muted); margin-bottom: 2px; }
.mt-cal-item { font-size: 11px; line-height: 1.3; padding: 1px 4px; margin-top: 2px; border-radius: 4px; background: var(--surface-2);
  border-left: 3px solid var(--s4); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mt-cal-item.job { border-left-color: var(--s2); }
@media (max-width: 640px) { .mt-cal-day { min-height: 44px; } .mt-cal-item { font-size: 10px; } }
/* The windows proposed on an alert and the O&M contact (docs/maintenance-planner.md "Windows proposed on an alert") */
.aw-block { margin-top: 8px; }
.aw-block .alert .actions, .aw-block .alert p { margin-top: 6px; margin-bottom: 0; }
.aw-defaults { margin: 0 0 8px; }
.aw-adjust { margin: 8px 0; }
.aw-adjust summary { cursor: pointer; color: var(--accent); font-weight: 600; }
.aw-adjust .mt-form { margin-top: 8px; }
.aw-facts { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.aw-contact { border-top: 1px solid var(--border); margin-top: 14px; padding-top: 10px; }
.aw-contact h3 { margin: 0 0 6px; font-size: 15px; }
.aw-contact-form { margin-top: 6px; }
.aw-open .mt-job:first-child { border-top: 0; padding-top: 0; }
/* The budget bridge waterfall (docs/budget-bridge.md) */
.waterfall-wrap { overflow-x: auto; }
.waterfall { width: 100%; min-width: 560px; height: auto; display: block; }
.waterfall rect:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
/* The REMIT assistant (docs/remit.md) */
.remit-card[hidden] { display: none; }
.remit-card { border-left: 4px solid var(--warning); }
.remit-pending + .remit-pending, .remit-draft + .remit-draft { border-top: 1px solid var(--border); padding-top: 12px; margin-top: 12px; }
.remit-draft-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.remit-draft-head h3 { margin: 0; font-size: 15px; }
.remit-facts { display: grid; grid-template-columns: max-content 1fr; gap: 4px 16px; margin: 12px 0; }
.remit-facts dt { color: var(--muted); }
.remit-facts dd { margin: 0; overflow-wrap: anywhere; }
.remit-note { white-space: pre-wrap; font-size: 12px; background: var(--surface-2); padding: 8px; overflow-x: auto; }
.remit-form { margin-top: 12px; }
@media (max-width: 640px) { .remit-facts { grid-template-columns: 1fr; } .remit-facts dd { margin-bottom: 6px; } }

/* the reseller console (js/pages/reseller.js, docs/reseller-console.md): its tabs, the delegated-access banner, the
   onboarding rows and the client's grants */
.reseller-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin: -4px 0 16px; border-bottom: 1px solid var(--border); }
.reseller-tabs a { padding: 8px 14px; color: var(--ink-2); text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.reseller-tabs a:hover { color: var(--ink); }
.reseller-tabs a[aria-current="page"] { color: var(--info-ink); border-bottom-color: var(--accent); font-weight: 600; }
.reseller-tabs a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.delegation-banner { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.delegation-banner button { margin-left: auto; }
.inline-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end; margin: 0; }
.inline-form .field { margin: 0; min-width: 160px; }
.onboarding-result .errors { margin: 0; padding-left: 18px; color: var(--critical-ink); }
.onboarding-result tr.row-error td { background: var(--surface-2); }
.delegation-grant { padding: 12px 0; border-bottom: 1px solid var(--border); }
.delegation-grant:last-child { border-bottom: 0; }
.delegation-grant h3 { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 4px; }
.delegation-grant blockquote { margin: 8px 0; padding: 6px 12px; border-left: 3px solid var(--border-strong); color: var(--ink-2); }
.reseller-clients .actions { flex-wrap: wrap; }
/* Balance of plant (docs/maintenance-bop.md): the battery health card's second section. */
.bop-section { margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--border); }
.bop-section .actions { flex-wrap: wrap; }
.alert-job { display: inline-block; overflow-wrap: anywhere; max-width: 24ch; }
/* docs/demo.md: the demo organisation's discreet banner, on every in-app page. */
.demo-banner { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin: 0 0 12px; padding: 6px 12px; border-radius: 8px; font-size: 13px; color: var(--ink-2); border: 1px dashed var(--border-strong); background: repeating-linear-gradient(135deg, transparent 0 10px, color-mix(in srgb, var(--warning) 7%, transparent) 10px 20px); }
.demo-banner strong { color: var(--ink); text-transform: uppercase; letter-spacing: 0.04em; }
/* Custom sign-in domain (docs/reseller-console.md §10): the DNS records, one block each. */
.dns-records { display: grid; gap: 12px; margin: 12px 0; }
.dns-record { border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; background: var(--surface); }
.dns-record-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.dns-record .hint { margin: 4px 0 8px; }
.dns-type { font-weight: 700; color: var(--ink); min-width: 4.5ch; }
.dns-name { overflow-wrap: anywhere; flex: 1 1 16ch; color: var(--ink); }

/* ------------------------------------------------------------------ "On this page" (docs/section-nav.md) */

/* The side list under the active entry: the page's sections, indented, with its own scroll when very long. */
/* The active entry's whole row folds or unfolds its sections (aria-expanded); the caret at its right is drawn by CSS. */
.sidenav li.has-secnav > a > .secnav-caret { margin-left: auto; width: 20px; text-align: center; }
.sidenav li.has-secnav > a > .secnav-caret::before { content: "▸"; font-size: 20px; line-height: 1; }
.sidenav li.has-secnav > a[aria-expanded="true"] > .secnav-caret::before { content: "▾"; }
.sidenav .secnav { list-style: none; margin: 2px 0 6px 16px; padding: 0 0 0 8px; border-left: 1px solid var(--border); display: flex; flex-direction: column; gap: 1px; max-height: 48vh; overflow-y: auto; overscroll-behavior: contain; }
.sidenav .secnav[hidden] { display: none; }
.sidenav .secnav a { display: block; padding: 4px 8px; border-radius: 6px; font-size: 13px; font-weight: 400; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidenav .secnav a:hover { background: var(--surface-2); color: var(--ink); }
.sidenav .secnav a[aria-current="location"] { color: var(--info-ink); font-weight: 600; background: none; box-shadow: inset 2px 0 var(--accent); }
/* Sub-sections (a site under its country) and the outline above the sections (country > site > sections). */
.sidenav .secnav-sub, .sidenav .secnav-sections { list-style: none; margin: 1px 0 4px 6px; padding: 0 0 0 8px; border-left: 1px solid var(--border); display: flex; flex-direction: column; gap: 1px; }
.sidenav .secnav[hidden], .sidenav .secnav-sub[hidden], .sidenav .secnav-sections[hidden] { display: none; } /* their display: flex would override [hidden] */
.sidenav .secnav-tree a[aria-current="page"] { color: var(--ink); font-weight: 600; background: var(--surface-2); }
.sidenav .secnav-group-toggle { display: flex; align-items: center; gap: 6px; width: 100%; min-height: 0; padding: 4px 8px; border-radius: 6px; font-size: 13px; font-weight: 600; color: var(--ink-2); text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; justify-content: flex-start; }
.sidenav .secnav-group-toggle .secnav-caret::before { content: "▸"; font-size: 10px; }
.sidenav .secnav-group-toggle[aria-expanded="true"] .secnav-caret::before { content: "▾"; }
.sidenav .secnav-group-toggle:hover { background: var(--surface-2); color: var(--ink); }
.sidenav .secnav .secnav-foldable { cursor: pointer; }
.sidenav .secnav .secnav-foldable .secnav-caret::before { content: "▸"; font-size: 10px; margin-right: 6px; }
.sidenav .secnav .secnav-foldable[aria-expanded="true"] .secnav-caret::before { content: "▾"; }
.secnav-compact-list .secnav-subitem a { padding-left: 22px; }
/* The heading a jump lands on stays below what sticks to the top (the top bar; the navigation row on a phone). */
main .secnav-target { scroll-margin-top: var(--secnav-offset, 72px); }
/* The compact box at the top of the page: phone widths only, where the side list has no room. */
.secnav-compact { display: none; margin: 0 0 14px; padding: 6px 12px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); max-width: 100%; min-width: 0; }
.secnav-compact[data-solo] { display: block; max-width: 48ch; } /* a page with no entry in the side navigation */
.secnav-compact summary { cursor: pointer; font-size: 13px; font-weight: 600; color: var(--ink-2); padding: 4px 0; }
.secnav-compact[open] summary { color: var(--ink); }
.secnav-compact-list { list-style: none; margin: 4px 0 2px; padding: 0; }
.secnav-compact-list a { display: block; padding: 7px 8px; border-radius: 6px; color: var(--ink-2); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.secnav-compact-list a:hover { background: var(--surface-2); color: var(--ink); }
.secnav-compact-list a[aria-current="location"] { color: var(--info-ink); font-weight: 600; box-shadow: inset 2px 0 var(--accent); }
@media (max-width: 860px) {
  .sidenav .secnav, .sidenav li.has-secnav > a > .secnav-caret { display: none; } /* the row's click opens the page */
  .secnav-compact { display: block; }
}

/* Plan-deviation episodes (docs/assets.md §5): the euro figure, the cause and the one-tap action, in Today's alert list,
   the twin and the site's alerts; and the confirm page a notification's button lands on. */
.deviation { display: flex; flex-direction: column; gap: 4px; margin-top: 4px; min-width: 0; }
.deviation-title { margin: 0; }
.deviation-line { margin: 0; color: var(--ink); font-size: 13px; overflow-wrap: anywhere; display: flex; flex-wrap: wrap; gap: 4px 6px; align-items: baseline; }
.deviation-cause { margin: 0; color: var(--ink-2); font-size: 13px; overflow-wrap: anywhere; }
.deviation-actions { margin-top: 2px; align-items: center; flex-wrap: wrap; }
.deviation-actions:empty { display: none; }
.deviation-advice { font-size: 13px; }
.deviation-stage:empty { display: none; }
.deviation-stage .alert { margin: 8px 0 0; }
.today-alerts .deviation { padding-left: 2px; }
.twin-deviation:empty { display: none; }
.twin-deviation .deviation-card { margin: 0 0 14px; }
.twin-deviation .deviation-card .deviation { margin-top: 0; }
.deviation-page .deviation-line { font-size: 15px; }

/* The revenue <-> longevity slider (docs/revenue-longevity.md): a range input over five positions, tick buttons under
   it (the keyboard works on the range, the mouse on either), the chosen position's figures, the five compared. */
.longevity-slider { max-width: 640px; margin: 4px 0 14px; }
.longevity-ends { display: flex; justify-content: space-between; font-size: 12px; font-weight: 600; color: var(--ink-2); margin-bottom: 2px; }
.longevity-range { display: block; width: 100%; margin: 0; accent-color: var(--accent); cursor: pointer; }
.longevity-range:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 4px; }
.longevity-ticks { display: grid; grid-template-columns: repeat(5, 1fr); margin-top: 2px; }
.longevity-tick { all: unset; display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 2px 0 4px; cursor: pointer; font-size: 12px; color: var(--ink-2); text-align: center; line-height: 1.2; border-radius: 6px; min-height: 34px; }
.longevity-tick:hover { color: var(--ink); }
.longevity-tick:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.longevity-tick[aria-pressed="true"] { color: var(--ink); font-weight: 600; }
.longevity-tick-mark { width: 2px; height: 8px; background: var(--axis); border-radius: 1px; }
.longevity-tick[aria-pressed="true"] .longevity-tick-mark { background: var(--accent); width: 3px; }
.longevity-tick-current { font-size: 11px; color: var(--s2); font-weight: 600; }
.longevity-figures h3 { margin: 10px 0 2px; }
.longevity-figures .badge { margin-top: 2px; }
.longevity-delta { margin: 4px 0 0; color: var(--ink-2); font-size: 13px; }
.longevity .form-actions { margin: 10px 0 12px; }
.longevity .table-wrap { margin-bottom: 8px; }
.pill.virtual, .pill.stale { color: var(--warning-ink); border-color: color-mix(in srgb, var(--warning) 60%, transparent); background: color-mix(in srgb, var(--warning) 12%, var(--surface)); font-weight: 600; }
.longevity-figures h3 .pill.stale { vertical-align: middle; font-size: 11px; margin-left: 6px; }
.longevity-badges { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 0; }
.longevity-cell-badges { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; } /* stacked: the column stays narrow */
.longevity.stale .longevity-figures .tiles, .longevity.stale .table-wrap { opacity: 0.72; } /* read as the past: the notice above says why */
.longevity .alert.info { margin-top: 0; }
/* Monthly recommendations (docs/recommendations.md): the site page's card, the Today list and the statement's line. */
.recommendation-card h3 { margin: 0 0 6px; }
.recommendation-sentence { margin: 0 0 10px; font-size: 16px; line-height: 1.4; }
.recommendation-changes { margin: 8px 0 4px; padding-left: 18px; color: var(--ink-2); font-size: 13px; }
.recommendation-card .form-actions { margin: 10px 0 12px; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.recommendation-method { margin-top: 8px; }
.recommendation-list { margin: 0; padding-left: 18px; }
.recommendation-list li { margin: 4px 0; line-height: 1.4; }
.recommendation-statement-card p { margin: 0 0 6px; }
@media (max-width: 520px) {
  .longevity-tick-label { display: none; }                      /* the two ends name the scale; the ticks stay as targets */
  .longevity-tick[aria-pressed="true"] .longevity-tick-label { display: block; }
  .longevity-tick { min-height: 40px; }
}
/* Data quality score (docs/data-quality.md): the site card's head, the issues table and each fix. */
.data-quality .dq-head { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 12px; }
.data-quality .dq-issues { table-layout: fixed; width: 100%; }
.data-quality .dq-issues th:first-child { width: 46%; }
.data-quality .dq-issues td { vertical-align: top; white-space: normal; overflow-wrap: anywhere; }
.data-quality .dq-fix p { margin: 0 0 6px; }
.data-quality .dq-fix .actions { margin-top: 4px; }
.data-quality h3 { margin-top: 18px; }
@media (max-width: 520px) {
  .data-quality .dq-issues thead { display: none; }
  .data-quality .dq-issues tr, .data-quality .dq-issues td { display: block; width: 100%; }
  .data-quality .dq-issues td:first-child { font-weight: 600; padding-bottom: 2px; border-bottom: 0; }
}

/* Remaining useful life and augmentation (docs/augmentation.md): the life tiles, the options table and the owner's inputs. */
.augmentation h3 { margin: 12px 0 4px; }
.augmentation-basis { margin: 6px 0 8px; font-size: 13px; }
.augmentation-verdict { margin: 6px 0 4px; font-size: 13px; }
.augmentation-options .table-wrap { margin-bottom: 4px; }
.augmentation-options .badge { margin-left: 4px; vertical-align: middle; }
.augmentation-settings { margin-top: 12px; }
.augmentation-method { margin-top: 8px; }
/* Scheduled reports (docs/scheduled-reports.md): the recipients editor and the plain lists of recipients and deliveries. */
ul.plain { list-style: none; margin: 0; padding: 0; }
ul.plain li { margin: 2px 0; }
.recipient-rows { display: flex; flex-direction: column; gap: 6px; }
.recipient-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.recipient-row input[name="r_email"] { flex: 2 1 220px; min-width: 0; }
.recipient-row input[name="r_label"] { flex: 1 1 160px; min-width: 0; }
.pill.warn { color: var(--warning-ink); border-color: color-mix(in srgb, var(--warning) 60%, transparent); background: color-mix(in srgb, var(--warning) 12%, var(--surface)); font-weight: 600; }
.pill.muted { color: var(--muted); }
.deliveries li { display: flex; flex-wrap: wrap; gap: 4px 6px; align-items: center; }
td .recipients, td .deliveries, td .schedule-cell { white-space: normal; min-width: 220px; max-width: 420px; overflow-wrap: anywhere; }
.run-failed td:first-child, .run-partial td:first-child { font-weight: 600; }
@media (max-width: 520px) {
  .scheduled-table thead { display: none; }
  .scheduled-table tr, .scheduled-table td { display: block; width: 100%; white-space: normal; }
  .scheduled-table tr { border-bottom: 1px solid var(--border); padding: 8px 0; }
  .scheduled-table td { border-bottom: 0; padding: 2px 0; }
  .scheduled-table td .recipients, .scheduled-table td .deliveries, .scheduled-table td .schedule-cell { max-width: none; min-width: 0; }
}
/* Forecast reliability (docs/forecast-reliability.md §5): « En savoir plus » under the tiles, the method in three short paragraphs. */
.forecast-reliability-method { margin: -4px 0 12px; }
.forecast-reliability-method p { max-width: 80ch; margin: 6px 0 0; }

/* "Try before connecting" (docs/trial.md "Try on a simulated twin"): the twin is unmistakably virtual, with text, a
   dashed border and the simulated tint (the same cues as the twin board's simulated cards). */
.twin-virtual-pill { border-style: dashed; border-color: var(--sim); color: var(--info-ink); background: var(--accent-wash); font-weight: 600; vertical-align: middle; }
h1 .twin-virtual-pill { font-size: 13px; }
.twin-trial-card, .twin-run-card, .twin-next-card { border-style: dashed; }
.twin-trial-card .actions, .twin-next-card .actions { margin-top: 8px; flex-wrap: wrap; }
.twin-run-card .status-line { margin: 0 0 8px; }
.twin-run-card .twin-charts { margin-top: 12px; }
/* Post-auction analysis (docs/post-auction.md): the month's takeaways and the verdict badges. */
.post-auction-card .takeaways ul { margin: 4px 0 12px; padding-left: 20px; }
.post-auction-card .takeaways li { margin: 4px 0; max-width: 80ch; }
.post-auction-card .badge.verdict { white-space: normal; text-align: left; }
.post-auction-card .verdict-extra { font-weight: 400; color: var(--muted); }
.post-auction-card .post-auction-curves { margin-top: 10px; }
.post-auction-card input[type="month"] { min-width: 10em; }
