/* Frontend/css/app.css — Mino app shell styles */

/* ── Theme tokens ── */
:root,
:root[data-theme="dark"] {
  --bg:      #0e1420;
  --panel:   rgba(255, 255, 255, 0.04);
  --border:  rgba(255, 255, 255, 0.10);
  --text:    #e2e8f0;
  --muted:   #94a3b8;
  --accent:  #00d4aa;
  --accent2: #3ba3ff;
  --accent-dim: #00a884;
  --accent-glow: rgba(0, 212, 170, 0.12);
  --red:     #ff4757;
  --amber:   #ffa502;
  --green:   #2ed573;
  /* Fields need a SOLID colour, and one per theme. A translucent black reads as depth on
     the dark page and as dirty grey on the light one — which is what it did. <option> is
     the other reason it must be solid: the platform paints the list on this colour, and a
     transparent value there renders white-on-white in several browsers. */
  --field:   #111a29;
}

:root[data-theme="light"] {
  --bg:      #f5f7fa;
  --panel:   #ffffff;
  --border:  rgba(0, 0, 0, 0.10);
  --text:    #1a2230;
  --muted:   #64748b;
  --accent:  #00b894;
  --accent2: #2d8fe6;
  --accent-dim: #008f72;
  --accent-glow: rgba(0, 184, 148, 0.12);
  --red:     #e84050;
  --amber:   #d97706;
  --green:   #16a34a;
  --field:   #ffffff;
}

/* ── Reset ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* ── Base ── */
html { font-size: 14px; scroll-behavior: smooth; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: system-ui, -apple-system, sans-serif;
  min-height: 100vh;
  overflow-x: hidden;
}
button { cursor: pointer; font-family: inherit; border: none; }
button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
input, select, textarea { font-family: inherit; }

/* The topbar was removed when the left rail took over navigation. Its rules went with
   it; the rail's own live in the App shell section above. */
.spacer { flex: 1; }

.theme-btn {
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--muted);
  font-size: 1rem;
  width: 34px;
  height: 34px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color 0.15s, color 0.15s;
  cursor: pointer;
  line-height: 1;
}
.theme-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* ── App shell ──
   NO overflow OTHER THAN visible on .app or .app-main. Any ancestor with a non-visible
   overflow becomes the scroll container for a descendant position:sticky, and the study
   pages' pinned section strip would then pin to the top of that box instead of to the
   viewport. The same warning is at the top of js/views/studyShell.js; this is the other
   half of it. */
.app { display: flex; min-height: 100vh; }
.app-main { flex: 1; min-width: 0; }

.rail {
  width: 236px;
  flex-shrink: 0;
  border-right: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.02);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  align-self: flex-start;
  height: 100vh;
  overflow-y: auto;
}
/* The sign-in gate is not part of the app: no rail, no navigation, nothing to click
   except the form. */
body[data-shell="off"] .rail { display: none; }

.rail-brand {
  height: 52px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 18px;
  border-bottom: 1px solid var(--border);
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: -0.3px;
  color: var(--text);
  flex-shrink: 0;
}
.rail-brand .mk {
  width: 28px; height: 28px;
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  border-radius: 7px;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.75rem; font-weight: 800; color: #0e1420;
  flex-shrink: 0;
}

.rail-org { padding: 14px 12px 12px; border-bottom: 1px solid var(--border); }
.rail-org-cap {
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.6px;
  color: var(--muted); opacity: 0.75; padding: 0 6px 8px;
}
.rail-org-btn {
  width: 100%;
  display: flex; align-items: center; gap: 10px;
  background: var(--accent-glow);
  border: 1px solid var(--accent-dim);
  border-radius: 10px;
  padding: 11px;
  text-align: left;
  transition: border-color 0.15s;
}
.rail-org-btn:hover { border-color: var(--accent); }
.rail-org-chip {
  width: 30px; height: 30px; border-radius: 8px;
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  display: flex; align-items: center; justify-content: center;
  font-size: 0.72rem; font-weight: 800; color: #0e1420;
  flex-shrink: 0;
}
.rail-org-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.rail-org-name {
  font-size: 0.88rem; font-weight: 700; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rail-org-role { font-size: 0.68rem; font-weight: 600; color: var(--accent); }

.rail-nav { padding: 10px 12px; display: flex; flex-direction: column; gap: 2px; }
.rail-div { height: 1px; background: var(--border); margin: 8px 10px; }

.rail-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 9px 10px;
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  font-size: 0.88rem; font-weight: 500;
  text-align: left;
  transition: background 0.15s, color 0.15s;
}
.rail-item:hover { background: rgba(255, 255, 255, 0.04); color: var(--text); }
.rail-item.on { background: var(--accent-glow); color: var(--accent); font-weight: 600; }
.rail-lbl { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rail-ico { width: 16px; height: 16px; flex-shrink: 0; }
.rail-ico.sm { width: 13px; height: 13px; }
.rail-count { font-size: 0.72rem; color: var(--muted); flex-shrink: 0; }
.rail-item.on .rail-count { color: var(--accent); }
.rail-soon {
  font-size: 0.6rem; font-weight: 800; letter-spacing: 0.4px;
  padding: 1px 7px; border-radius: 20px;
  background: rgba(148, 163, 184, 0.12);
  color: var(--muted);
  border: 1px solid var(--border);
  flex-shrink: 0;
}

.rail-foot { margin-top: auto; padding: 12px; border-top: 1px solid var(--border); }
.rail-user {
  width: 100%;
  display: flex; align-items: center; gap: 9px;
  padding: 8px;
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  text-align: left;
  transition: background 0.15s, color 0.15s;
}
.rail-user:hover { background: rgba(255, 255, 255, 0.04); color: var(--text); }
.rail-user-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.rail-user-mail {
  font-size: 0.78rem; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rail-user-out { font-size: 0.68rem; color: var(--muted); }

/* The theme toggle lost its topbar. Pinned rather than placed, so it never competes
   with anything in the working area. */
.theme-btn { position: fixed; top: 11px; right: 16px; z-index: 200; }

/* ── The rail, inside a project ── */
.rail-prj { padding: 12px; border-bottom: 1px solid var(--border); }
.rail-back {
  display: flex; align-items: center; gap: 7px;
  background: transparent; color: var(--muted);
  font-size: 0.78rem; padding: 4px 4px 9px;
  transition: color 0.15s;
}
.rail-back:hover { color: var(--accent); }
.rail-prj-name {
  padding: 0 4px; font-size: 0.98rem; font-weight: 700; color: var(--text); line-height: 1.25;
}
.rail-prj-meta { padding: 3px 4px 0; font-size: 0.72rem; color: var(--muted); }
.rail-cap {
  font-size: 0.66rem; font-weight: 700; letter-spacing: 0.6px;
  color: var(--muted); opacity: 0.8; padding: 2px 10px 8px;
}
.rail-item.is-soon { cursor: default; opacity: 0.6; }
.rail-item.is-soon:hover { background: transparent; color: var(--muted); }

body[data-rail="collapsed"] .rail-prj-name,
body[data-rail="collapsed"] .rail-prj-meta,
body[data-rail="collapsed"] .rail-cap,
body[data-rail="collapsed"] .rail-back span { display: none; }
body[data-rail="collapsed"] .rail-prj { padding: 10px 0; display: flex; justify-content: center; }
body[data-rail="collapsed"] .rail-back { padding: 4px; }

/* ── The rail, folded ──
   Icons only at 64px. Everything that is a word is hidden rather than shrunk: a
   truncated label is harder to read than an icon, and slower. */
body[data-rail="collapsed"] .rail { width: 64px; }
body[data-rail="collapsed"] .rail-word,
body[data-rail="collapsed"] .rail-lbl,
body[data-rail="collapsed"] .rail-count,
body[data-rail="collapsed"] .rail-soon,
body[data-rail="collapsed"] .rail-org-cap,
body[data-rail="collapsed"] .rail-org-txt,
body[data-rail="collapsed"] .rail-org-btn > svg,
body[data-rail="collapsed"] .rail-user-txt { display: none; }
/* THE FOLD BUTTON STAYS. Hiding it left the rail with no way back out short of clearing
   storage — the control that put it away has to be the control that brings it back, and
   at 64px there is only room for one of them, so the mark goes and the button stays. */
body[data-rail="collapsed"] .rail-brand { padding: 0; justify-content: center; }
body[data-rail="collapsed"] .rail-brand .spacer,
body[data-rail="collapsed"] .rail-brand .mk { display: none; }
body[data-rail="collapsed"] .rail-mini { width: 34px; height: 34px; }
body[data-rail="collapsed"] .rail-org { padding: 12px 0; display: flex; justify-content: center; }
body[data-rail="collapsed"] .rail-org-btn { width: auto; padding: 6px; background: transparent; border-color: transparent; }
body[data-rail="collapsed"] .rail-nav { padding: 10px 8px; }
body[data-rail="collapsed"] .rail-item,
body[data-rail="collapsed"] .rail-user { justify-content: center; padding: 10px 0; }
body[data-rail="collapsed"] .rail-div { margin: 8px 6px; }

.rail-mini {
  background: transparent; border: none; color: var(--muted);
  width: 26px; height: 26px; border-radius: 7px;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.15s, color 0.15s;
}
.rail-mini:hover { background: rgba(255, 255, 255, 0.06); color: var(--text); }
.rail-brand .spacer { flex: 1; }

/* ── Mino's dock ── */
.mino-dock {
  position: fixed;
  right: 26px;
  bottom: 26px;
  z-index: 150;
  width: 54px;
  height: 54px;
  border-radius: 999px;
  background: var(--bg);
  border: 1.5px solid var(--accent-dim);
  color: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0 0 6px var(--accent-glow), 0 10px 30px rgba(0, 0, 0, 0.35);
  transition: transform 0.15s, border-color 0.15s;
}
.mino-dock:hover { transform: translateY(-2px); border-color: var(--accent); }
.mino-dock .rail-ico { width: 30px; height: 30px; }
body[data-shell="off"] .mino-dock { display: none; }

/* Mino's panel. FIXED, so nothing on the page moves when it opens — the whole reason it
   is an overlay rather than a docked rail. */
.mino-panel {
  position: fixed;
  right: 26px;
  bottom: 94px;
  z-index: 150;
  width: 384px;
  max-width: calc(100vw - 52px);
  max-height: min(560px, calc(100vh - 140px));
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--accent-dim);
  border-radius: 14px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
  overflow: hidden;
  /* The panel sits on the app background rather than borrowing it: --panel is a
     translucent white in dark mode, and the page would show through the conversation. */
  background-color: var(--bg);
}
.mino-head {
  display: flex; align-items: center; gap: 11px;
  padding: 13px 14px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.mino-head-ico { color: var(--accent); display: flex; }
.mino-head-ico .rail-ico { width: 26px; height: 26px; }
.mino-head-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.mino-head-name { font-size: 0.88rem; font-weight: 700; color: var(--text); }
.mino-head-ctx {
  font-size: 0.7rem; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mino-body { padding: 16px 14px; overflow-y: auto; flex: 1; }
.mino-msg {
  background: var(--accent-glow);
  border: 1px solid var(--accent-dim);
  border-radius: 12px 12px 12px 4px;
  padding: 12px 14px;
  font-size: 0.85rem; color: var(--text); line-height: 1.6;
  margin-bottom: 18px;
}
.mino-cap {
  font-size: 0.66rem; font-weight: 700; letter-spacing: 0.5px;
  color: var(--muted); margin-bottom: 10px;
}
.mino-sugs { display: flex; flex-direction: column; gap: 8px; }
.mino-sug {
  border: 1px solid var(--border); border-radius: 10px;
  padding: 9px 12px;
  font-size: 0.82rem; color: var(--muted); line-height: 1.45;
}
.mino-foot { padding: 12px 14px 14px; border-top: 1px solid var(--border); flex-shrink: 0; }
.mino-input {
  border: 1px dashed var(--border); border-radius: 10px;
  padding: 11px 13px; margin-bottom: 9px;
  font-size: 0.84rem; color: var(--muted); opacity: 0.8;
}
.mino-dock.on { border-color: var(--accent); box-shadow: 0 0 0 6px var(--accent-glow), 0 10px 30px rgba(0, 0, 0, 0.45); }
body[data-shell="off"] .mino-panel { display: none; }

/* The floating theme button belongs to the sign-in screen only; the rail owns the
   control everywhere else, because there is nowhere over a full-bleed hero for a pinned
   button to sit without landing on top of it. */
body[data-shell="on"] .theme-btn { display: none; }

/* ── New study ── */
.newstudy { max-width: 1180px; margin: 0 auto; padding: 44px 28px 48px; }
.ns-head { margin-bottom: 26px; max-width: 720px; }
.ns-head h1 { font-size: 1.8rem; font-weight: 700; color: var(--text); margin-bottom: 8px; }
.ns-head p { font-size: 0.95rem; color: var(--muted); line-height: 1.65; }

/* ── Project overview ── */
.results { max-width: 1180px; margin: 0 auto; padding: 24px 28px 48px; }
.rp-hdr { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.rp-proj { font-size: 1.5rem; font-weight: 700; color: var(--text); }
.rp-mode { font-size: 0.82rem; color: var(--muted); margin-top: 3px; }

.ov-verdict {
  border: 1px solid var(--accent-dim);
  border-radius: 16px;
  background: linear-gradient(135deg, var(--accent-glow), rgba(59, 163, 255, 0.04));
  padding: 20px 22px 16px;
  margin-bottom: 20px;
}
.ov-verdict-head { display: flex; align-items: center; gap: 10px; margin-bottom: 9px; flex-wrap: wrap; }
.ov-mino { width: 24px; height: 24px; color: var(--accent); flex-shrink: 0; }
.ov-verdict-name { font-size: 1.02rem; font-weight: 700; color: var(--text); }
.ov-soon {
  font-size: 0.62rem; font-weight: 800; letter-spacing: 0.5px;
  padding: 2px 9px; border-radius: 20px;
  background: rgba(148, 163, 184, 0.14); color: var(--muted); border: 1px solid var(--border);
  flex-shrink: 0;
}
.ov-verdict-body { font-size: 0.9rem; color: var(--muted); line-height: 1.6; max-width: 740px; }

/* The caveats live inside the recommendation, separated by a rule rather than by a gap
   and a second border. Boxes inside boxes is what made the top of this page feel loose. */
.ov-verdict-foot {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 8px;
}
.ov-verdict-foot .ov-entry {
  background: transparent;
  border-color: transparent;
  padding: 9px 11px;
}
.ov-verdict-foot .ov-entry:hover { background: rgba(255, 255, 255, 0.045); border-color: var(--border); }
.ov-verdict-foot .ov-entry.warn { background: transparent; border-color: transparent; }
.ov-verdict-foot .ov-entry.warn:hover { background: rgba(255, 165, 2, 0.08); border-color: rgba(255, 165, 2, 0.35); }

.ov-entry {
  display: flex; align-items: center; gap: 12px; text-align: left;
  border: 1px solid var(--border); background: var(--panel);
  border-radius: 10px; padding: 13px 16px;
  transition: border-color 0.15s, background 0.15s;
}
.ov-entry:hover { border-color: var(--accent); }
.ov-entry.warn { border-color: rgba(255, 165, 2, 0.35); background: rgba(255, 165, 2, 0.06); }
.ov-entry.warn .ov-ico, .ov-entry.warn .ov-entry-go { color: var(--amber); }
/* Not built: it must look unavailable, so nobody spends a click finding out. */
.ov-entry.is-soon { cursor: default; opacity: 0.72; }
.ov-entry.is-soon:hover { background: transparent; border-color: transparent; }
.ov-ico { width: 18px; height: 18px; color: var(--muted); flex-shrink: 0; }
.ov-entry-txt { flex: 1; min-width: 0; }
.ov-entry-t { display: block; font-size: 0.88rem; font-weight: 700; color: var(--text); }
.ov-entry-b {
  display: block; font-size: 0.78rem; color: var(--muted); margin-top: 1px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ov-entry-go { font-size: 0.82rem; font-weight: 700; color: var(--accent); flex-shrink: 0; }

.ov-previews { display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 16px; margin-bottom: 26px; }
.ov-card { border: 1px solid var(--border); border-radius: 14px; background: var(--panel); overflow: hidden; display: flex; flex-direction: column; }
.ov-card-hd { display: flex; align-items: center; gap: 10px; padding: 13px 18px; border-bottom: 1px solid var(--border); }
.ov-card-t { font-size: 0.92rem; font-weight: 700; color: var(--text); }
.ov-card-ft {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px;
  padding: 16px 18px; border-top: 1px solid var(--border); margin-top: auto;
}
.ov-bat { flex: 1; display: flex; align-items: center; justify-content: center; padding: 26px 20px; min-height: 200px; }
.ov-bat-empty, .ov-bat-done { text-align: center; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.ov-bat-empty-t { font-size: 0.95rem; font-weight: 700; color: var(--text); }
.ov-bat-empty-b { font-size: 0.83rem; color: var(--muted); line-height: 1.55; max-width: 320px; margin-bottom: 6px; }
.ov-bat-big { font-size: 2rem; font-weight: 800; color: var(--accent); line-height: 1.1; }
.ov-bat-big small { font-size: 0.78rem; font-weight: 500; color: var(--muted); display: block; margin-top: 5px; }
.ov-bat-note { font-size: 0.83rem; color: var(--muted); line-height: 1.55; max-width: 340px; }
.btn-primary.sm { font-size: 0.85rem; padding: 9px 18px; }

/* The BESS drawing on the overview's battery card. A fixed width rather than 100%:
   it is a diagram of an object, and an object that grows with the card it sits in
   reads as a background pattern rather than a thing. The card opposite is a satellite
   photo, which is the one image on this row that SHOULD fill its box. */
.bess { width: 190px; max-width: 100%; height: auto; display: block; }

.recs-note { font-size: 0.82rem; color: var(--muted); }

/* ── Compare ── */
.cmp { border: 1px solid var(--border); border-radius: 14px; overflow: hidden; background: var(--panel); }
.cmp-hd, .cmp-row {
  display: grid; grid-template-columns: 2fr 1fr 1.2fr 1.2fr; gap: 16px;
  align-items: center; padding: 14px 18px;
}
.cmp-hd {
  border-bottom: 1px solid var(--border); background: rgba(0, 0, 0, 0.14);
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.5px; color: var(--muted);
}
.cmp-row { border-bottom: 1px solid var(--border); }
.cmp-name { font-size: 0.9rem; font-weight: 700; color: var(--text); }
.cmp-sub { display: block; font-size: 0.74rem; font-weight: 400; color: var(--muted); margin-top: 2px; }
.cmp-num { text-align: right; font-size: 0.85rem; color: var(--text); font-variant-numeric: tabular-nums; }
.cmp-save { font-size: 0.98rem; font-weight: 700; }
.cmp-none { color: var(--muted); opacity: 0.6; }
.cmp-foot { padding: 14px 18px; font-size: 0.8rem; color: var(--muted); line-height: 1.6; }
.cmp-foot b { color: var(--text); }

/* ── Organisations ── */
.orgs { max-width: 1180px; margin: 0 auto; padding: 32px 28px 48px; }
.orgs-lede { font-size: 0.9rem; color: var(--muted); line-height: 1.65; max-width: 820px; margin-bottom: 24px; }
.org-rows { display: flex; flex-direction: column; gap: 14px; }
.org-row {
  display: flex; align-items: center; gap: 22px;
  border: 1px solid var(--border); border-radius: 14px;
  background: var(--panel);
  padding: 20px 22px;
  flex-wrap: wrap;
}
.org-row.on { border-color: var(--accent-dim); background: var(--accent-glow); }
.org-row.ro .org-chip { background: rgba(255, 165, 2, 0.14); color: var(--amber); border-color: var(--amber); }
.org-chip {
  width: 48px; height: 48px; border-radius: 12px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.95rem; font-weight: 800; color: #0e1420;
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  border: 1px solid transparent;
}
.org-id { width: 280px; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.org-name { display: flex; align-items: center; gap: 9px; font-size: 1.05rem; font-weight: 700; color: var(--text); flex-wrap: wrap; }
.org-role {
  font-size: 0.64rem; font-weight: 800; letter-spacing: 0.4px;
  padding: 2px 9px; border-radius: 20px;
  background: var(--accent-glow); color: var(--accent); border: 1px solid var(--accent-dim);
}
.org-row.ro .org-role { background: rgba(255, 165, 2, 0.10); color: var(--amber); border-color: var(--amber); }
.org-note { font-size: 0.8rem; color: var(--muted); }
.org-stats { flex: 1; min-width: 260px; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; }
.org-stat { display: flex; flex-direction: column; gap: 3px; }
.org-stat i { font-style: normal; font-size: 0.7rem; color: var(--muted); letter-spacing: 0.3px; }
.org-stat b { font-size: 1.05rem; font-weight: 700; color: var(--text); }
.org-here { font-size: 0.82rem; font-weight: 700; color: var(--accent); flex-shrink: 0; }
.btn-ghost.sm { font-size: 0.84rem; padding: 9px 17px; }
.org-invite {
  margin-top: 16px;
  border: 1px solid var(--border); border-radius: 14px;
  padding: 20px 22px;
  display: flex; flex-direction: column; gap: 3px;
}
.org-invite-t { font-size: 0.92rem; font-weight: 600; color: var(--muted); }
.org-invite-b { font-size: 0.82rem; color: var(--muted); opacity: 0.85; line-height: 1.55; }

/* ── Coming soon ── */
.cswrap { max-width: 780px; margin: 0 auto; padding: 56px 24px; }
.cs-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.cs-head h1 { font-size: 1.7rem; font-weight: 700; color: var(--text); }
.cs-badge {
  font-size: 0.64rem; font-weight: 800; letter-spacing: 0.5px;
  padding: 3px 10px; border-radius: 20px;
  background: rgba(148, 163, 184, 0.12);
  color: var(--muted);
  border: 1px solid var(--border);
}
.cs-lede { font-size: 1rem; color: var(--muted); line-height: 1.65; margin-bottom: 24px; }
.cs-points { list-style: none; display: flex; flex-direction: column; gap: 11px; margin-bottom: 26px; }
.cs-points li {
  position: relative; padding-left: 22px;
  font-size: 0.9rem; color: var(--text); line-height: 1.55;
}
.cs-points li::before {
  content: ''; position: absolute; left: 4px; top: 8px;
  width: 6px; height: 6px; border-radius: 999px; background: var(--accent);
}
.cs-note {
  border: 1px solid var(--border);
  border-left: 3px solid var(--amber);
  border-radius: 10px;
  background: var(--panel);
  padding: 16px 18px;
  font-size: 0.88rem; color: var(--muted); line-height: 1.65;
}
.cs-note b { color: var(--text); }
.cs-open { margin-top: 22px; }
.cs-open-cap {
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.5px;
  color: var(--muted); margin-bottom: 10px;
}
.cs-open ul { list-style: none; display: flex; flex-direction: column; gap: 8px; }
.cs-open li {
  position: relative; padding-left: 18px;
  font-size: 0.86rem; color: var(--muted); line-height: 1.5;
}
.cs-open li::before {
  content: ''; position: absolute; left: 3px; top: 8px;
  width: 5px; height: 5px; border-radius: 999px; background: var(--muted); opacity: 0.6;
}

/* ── Dashboard ── */
.dash { max-width: 1180px; margin: 0 auto; padding: 24px 28px 48px; }

.hero-slider {
  position: relative;
  display: flex;
  border: 1px solid var(--border);
  border-radius: 18px;
  overflow: hidden;
  background:
    radial-gradient(120% 140% at 12% 8%, var(--accent-glow) 0%, rgba(59, 163, 255, 0.05) 42%, transparent 78%),
    var(--panel);
  min-height: 380px;
  margin-bottom: 30px;
}
.hero-text {
  width: 47%;
  flex-shrink: 0;
  padding: 42px 0 40px 42px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.hero-kicker {
  display: inline-flex; align-items: center; gap: 7px;
  width: fit-content;
  background: var(--accent-glow);
  border: 1px solid var(--accent-dim);
  border-radius: 20px;
  padding: 4px 12px;
  margin-bottom: 18px;
  font-size: 0.7rem; font-weight: 800; letter-spacing: 0.6px;
  color: var(--accent);
}
.hero-kicker .dot { width: 5px; height: 5px; border-radius: 999px; background: var(--accent); }
.hero-text h1 {
  font-size: 2.4rem; font-weight: 800; letter-spacing: -1.1px; line-height: 1.09;
  color: var(--text); margin-bottom: 13px; text-wrap: pretty;
}
.hero-text p {
  font-size: 1rem; color: var(--muted); line-height: 1.6;
  margin-bottom: 25px; max-width: 460px; text-wrap: pretty;
}
.hero-cta { display: flex; gap: 11px; align-items: center; flex-wrap: wrap; }
.hero-figure { flex: 1; min-width: 0; display: flex; align-items: center; justify-content: center; padding: 12px; }
.hero-art { width: 100%; height: 320px; display: block; }
.hero-nav { position: absolute; right: 22px; bottom: 20px; display: flex; align-items: center; gap: 9px; }
.hero-dot { width: 5px; height: 5px; border-radius: 999px; background: rgba(148, 163, 184, 0.4); transition: width 0.2s; }
.hero-dot.on { width: 22px; background: var(--accent); }
.hero-arrow {
  width: 32px; height: 32px; border-radius: 8px;
  background: var(--bg); border: 1px solid var(--border); color: var(--text);
  display: flex; align-items: center; justify-content: center;
  transition: border-color 0.15s, color 0.15s;
}
.hero-arrow svg { width: 15px; height: 15px; }
.hero-arrow:hover { border-color: var(--accent); color: var(--accent); }

.btn-ghost {
  background: transparent; border: 1px solid var(--border); color: var(--text);
  font-size: 0.88rem; font-weight: 600; padding: 12px 20px; border-radius: 10px;
  transition: border-color 0.15s, color 0.15s;
}
.btn-ghost:hover { border-color: var(--accent); color: var(--accent); }
.btn-hint {
  display: flex; align-items: center; gap: 8px;
  background: rgba(59, 163, 255, 0.08);
  border: 1px solid rgba(59, 163, 255, 0.35);
  color: var(--accent2);
  font-size: 0.82rem; font-weight: 700; padding: 8px 15px; border-radius: 9px;
}
.btn-hint svg { width: 15px; height: 15px; }
.btn-hint:hover { background: rgba(59, 163, 255, 0.14); }
.linkish { background: none; color: var(--accent); font-size: 0.85rem; font-weight: 600; padding: 0; }
.linkish:hover { color: var(--accent-dim); }
.spacer { flex: 1; }

/* ── The study ladder ── */
.ladder {
  border: 1px solid var(--border); border-radius: 16px;
  background: var(--panel); padding: 26px 26px 24px; margin-bottom: 30px;
}
.ladder-head { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; flex-wrap: wrap; }
.ladder-head h2 { font-size: 1.35rem; font-weight: 700; color: var(--text); }
.ladder-sub { font-size: 0.84rem; color: var(--muted); }

.tier-tabs {
  display: inline-flex; background: var(--bg);
  border: 1px solid var(--border); border-radius: 12px;
  padding: 4px; gap: 4px; margin-bottom: 20px; flex-wrap: wrap;
}
.tier-tab {
  display: flex; align-items: center; gap: 8px;
  background: transparent; border: 1px solid transparent; border-radius: 9px;
  padding: 9px 17px; font-size: 0.88rem; font-weight: 500; color: var(--muted);
  transition: background 0.15s, color 0.15s;
}
.tier-tab:hover { color: var(--text); }
.tier-tab.on { background: rgba(255, 255, 255, 0.07); border-color: var(--border); color: var(--text); font-weight: 700; }
.tier-pill {
  font-size: 0.6rem; font-weight: 800; letter-spacing: 0.4px;
  padding: 1px 7px; border-radius: 20px;
  background: rgba(255, 255, 255, 0.04); color: var(--muted); border: 1px solid var(--border);
}
.tier-tab.on .tier-pill { background: var(--accent-glow); color: var(--accent); border-color: var(--accent-dim); }

.tier-card {
  border: 1px solid var(--border); border-radius: 14px;
  background: rgba(255, 255, 255, 0.02); padding: 24px 26px 22px;
}
.tier-card.live {
  border-color: var(--accent-dim);
  background: linear-gradient(150deg, var(--accent-glow) 0%, rgba(59, 163, 255, 0.04) 55%, transparent 100%);
}
.tier-top { display: flex; align-items: flex-start; gap: 20px; margin-bottom: 20px; flex-wrap: wrap; }
.tier-top > div:first-child { flex: 1; min-width: 260px; }
.tier-title {
  display: flex; align-items: center; gap: 11px; flex-wrap: wrap;
  font-size: 1.45rem; font-weight: 800; letter-spacing: -0.5px; color: var(--muted); margin-bottom: 7px;
}
.tier-card.live .tier-title { color: var(--text); }
.tier-badge {
  font-size: 0.66rem; font-weight: 800; letter-spacing: 0.6px;
  padding: 3px 10px; border-radius: 20px;
  background: rgba(148, 163, 184, 0.10); color: var(--muted); border: 1px solid var(--border);
}
.tier-card.live .tier-badge { background: var(--accent-glow); color: var(--accent); border-color: var(--accent-dim); }
.tier-blurb { font-size: 0.92rem; color: var(--muted); line-height: 1.55; max-width: 620px; }
.tier-meta { text-align: right; flex-shrink: 0; }
.tier-meta-l { font-size: 0.7rem; color: var(--muted); letter-spacing: 0.3px; margin-bottom: 3px; }
.tier-meta-v { font-size: 1.05rem; font-weight: 700; color: var(--muted); }
.tier-card.live .tier-meta-v { color: var(--accent); }

.tier-steps {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 14px;
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
  padding: 20px 0 18px; margin-bottom: 20px;
}
.tier-step { display: flex; flex-direction: column; align-items: center; gap: 9px; text-align: center; }
.tier-step-n {
  width: 27px; height: 27px; border-radius: 999px;
  background: var(--bg); border: 1.5px solid var(--accent-dim); color: var(--accent);
  font-size: 0.78rem; font-weight: 800;
  display: flex; align-items: center; justify-content: center;
}
.tier-step-t { font-size: 0.9rem; font-weight: 700; color: var(--text); }
.tier-step-b { font-size: 0.78rem; color: var(--muted); line-height: 1.45; max-width: 230px; }
.tier-step-x { font-size: 0.72rem; color: var(--muted); opacity: 0.75; font-weight: 600; }

.tier-bul-cap { font-size: 0.74rem; font-weight: 700; letter-spacing: 0.5px; color: var(--muted); margin-bottom: 12px; }
.tier-bullets {
  list-style: none; display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 10px 26px; margin-bottom: 22px;
}
.tier-bullets li {
  position: relative; padding-left: 24px;
  font-size: 0.86rem; color: var(--muted); line-height: 1.5;
}
.tier-card.live .tier-bullets li { color: var(--text); }
.tier-bullets li::before {
  content: ''; position: absolute; left: 4px; top: 7px;
  width: 6px; height: 6px; border-radius: 999px; background: var(--muted); opacity: 0.5;
}
.tier-card.live .tier-bullets li::before { background: var(--accent); opacity: 1; }
.tier-caveat {
  font-size: 0.8rem;
  color: var(--muted);
  opacity: 0.85;
  padding: 10px 0 0;
  margin: -8px 0 18px;
  border-top: 1px solid var(--border);
}

.tier-foot { display: flex; align-items: center; gap: 13px; flex-wrap: wrap; }
.tier-note { font-size: 0.8rem; color: var(--muted); }

/* ── Attention ── */
.attn {
  display: flex; align-items: center; gap: 16px;
  border: 1px solid rgba(255, 165, 2, 0.35);
  background: rgba(255, 165, 2, 0.06);
  border-radius: 12px; padding: 15px 20px; margin-bottom: 30px;
}
.attn-ico { width: 19px; height: 19px; color: var(--amber); flex-shrink: 0; }
.attn-txt { flex: 1; min-width: 0; }
.attn-t { font-size: 0.92rem; font-weight: 700; color: var(--text); margin-bottom: 2px; }
.attn-b { font-size: 0.82rem; color: var(--muted); }
.attn-btn {
  background: transparent; border: 1px solid rgba(255, 165, 2, 0.5); color: var(--amber);
  font-size: 0.82rem; font-weight: 700; padding: 8px 16px; border-radius: 8px; flex-shrink: 0;
}
.attn-btn:hover { background: rgba(255, 165, 2, 0.12); }

.recent-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 14px; }
.recent-head h2 { font-size: 1.35rem; font-weight: 700; color: var(--text); }

@media (max-width: 900px) {
  .hero-slider { flex-direction: column; min-height: 0; }
  .hero-text { width: auto; padding: 32px 24px 24px; }
  .hero-figure { padding: 0 16px 56px; }
  .hero-art { height: 240px; }
}

/* ── Screens ── */
.screen { display: none; }
.screen.active { display: block; }

/* ── Projects view ── */
.projects-wrap {
  max-width: 1180px;
  margin: 0 auto;
  padding: 32px 28px 48px;
}
.ph { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; }
.ph h1 { font-size: 1.7rem; font-weight: 700; color: var(--text); }
.btn-primary.sm { font-size: 0.85rem; padding: 9px 16px; }

.vtogs {
  display: flex; gap: 2px; padding: 2px;
  background: var(--bg); border: 1px solid var(--border); border-radius: 9px;
}
.vtog {
  width: 32px; height: 28px; border-radius: 7px;
  background: transparent; color: var(--muted);
  display: flex; align-items: center; justify-content: center;
  transition: background 0.15s, color 0.15s;
}
.vtog svg { width: 15px; height: 15px; }
.vtog:hover { color: var(--text); }
.vtog.on { background: var(--accent-glow); color: var(--accent); }

.pfilters { display: flex; align-items: center; gap: 8px; margin-bottom: 18px; flex-wrap: wrap; }
.chip {
  display: inline-flex; align-items: center; gap: 7px;
  border-radius: 20px; font-size: 0.78rem; font-weight: 600;
  padding: 5px 14px;
  background: transparent; border: 1px solid var(--border); color: var(--muted);
  transition: border-color 0.15s, color 0.15s;
}
.chip:hover { border-color: var(--accent-dim); color: var(--text); }
.chip.on { background: var(--accent-glow); border-color: var(--accent-dim); color: var(--accent); font-weight: 700; }
.chip-n { opacity: 0.75; font-variant-numeric: tabular-nums; }
.pcontext { font-size: 0.78rem; color: var(--muted); }

/* ── The table ── */
.projects-table {
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  background: var(--panel);
}
.pth, .ptr {
  display: grid;
  grid-template-columns: 2.2fr 1.6fr 0.9fr 1fr;
  gap: 16px;
  align-items: center;
  padding: 13px 18px;
}
.pth {
  border-bottom: 1px solid var(--border);
  background: rgba(0, 0, 0, 0.12);
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.5px; color: var(--muted);
}
.ptr {
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.12s;
}
.ptr:last-child { border-bottom: none; }
.ptr:hover { background: rgba(255, 255, 255, 0.03); }
.ptd { font-size: 0.85rem; color: var(--muted); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ptd-name { display: flex; align-items: center; gap: 11px; }
.ptd-txt { font-size: 0.9rem; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ptd-thumb {
  width: 32px; height: 32px; border-radius: 8px; flex-shrink: 0;
  background: linear-gradient(135deg, var(--accent-glow) 0%, rgba(59, 163, 255, 0.12) 100%);
  border: 1px solid var(--border);
}
.ptd-size { text-align: right; font-variant-numeric: tabular-nums; color: var(--text); }

.pempty {
  border: 2px dashed var(--border);
  border-radius: 12px;
  padding: 56px 24px;
  display: flex; flex-direction: column; align-items: center; gap: 9px;
}
.pempty-t { font-size: 1rem; font-weight: 700; color: var(--text); }
.pempty-b { font-size: 0.85rem; color: var(--muted); margin-bottom: 8px; }

.pcards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px;
}
.pcard {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  cursor: pointer;
  transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s;
}

.pcard:hover {
  transform: translateY(-3px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
  border-color: var(--accent);
}

/* Roof-image placeholder thumbnail */
.pcard-thumb {
  height: 74px;
  background: linear-gradient(135deg, var(--accent-glow) 0%, rgba(59, 163, 255, 0.12) 100%);
  border-bottom: 1px solid var(--border);
  position: relative;
  overflow: hidden;
}

.pcard-thumb::after {
  content: '';
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    -45deg,
    transparent,
    transparent 8px,
    rgba(255, 255, 255, 0.03) 8px,
    rgba(255, 255, 255, 0.03) 9px
  );
}

.pcard-body {
  padding: 12px 14px 14px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pcard-name {
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pcard-meta {
  font-size: 0.78rem;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-height: 1.2em;
}

/* Badge */
.pcard-badge {
  display: inline-block;
  margin-top: 6px;
  padding: 2px 8px;
  border-radius: 20px;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.3px;
  background: var(--accent-glow);
  color: var(--accent);
  border: 1px solid var(--accent-dim);
  width: fit-content;
}

.pcard-badge.draft {
  background: rgba(255, 165, 2, 0.10);
  color: var(--amber);
  border-color: var(--amber);
}

/* New project card */
/* ── Mode strip ── */
/* ── Utility ── */
/* !important, deliberately. .hidden is a utility that has to beat whatever display a
   component sets on itself, and CSS resolves an equal-specificity tie by source order —
   so any rule written LATER in this file silently defeated it. That is not hypothetical:
   .other-reveal sets display:flex four hundred lines below, and the net-zero box was
   therefore never hidden at all. A utility used by twenty components cannot depend on
   staying last in the file. */
.hidden { display: none !important; }

/* ── Wizard ── */
.wizard {
  max-width: 680px;
  margin: 40px auto;
  padding: 0 24px 48px;
}

/* Stepper */
.stepper {
  display: flex;
  gap: 0;
  margin-bottom: 8px;
}

.seg {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  position: relative;
}

.seg::before {
  content: '';
  position: absolute;
  top: 9px;
  left: calc(50% + 9px);
  right: calc(-50% + 9px);
  height: 2px;
  background: var(--border);
}

.seg:last-child::before { display: none; }

.seg .dot {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid var(--border);
  background: var(--bg);
  z-index: 1;
  transition: background 0.2s, border-color 0.2s;
}

.seg.done .dot {
  background: var(--accent);
  border-color: var(--accent);
}

.seg.cur .dot {
  background: var(--accent2);
  border-color: var(--accent2);
  box-shadow: 0 0 0 3px rgba(59, 163, 255, 0.25);
}

.seg .lbl {
  font-size: 0.68rem;
  color: var(--muted);
  text-align: center;
  white-space: nowrap;
}

.seg.cur .lbl {
  color: var(--accent2);
  font-weight: 600;
}

.pctline {
  font-size: 0.75rem;
  color: var(--accent);
  text-align: right;
  margin-bottom: 28px;
  font-weight: 500;
}

/* Step card */
.wizard-step {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 32px 36px 28px;
}

.wizard-step h2 {
  font-size: 1.35rem;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 24px;
}

/* Fields */
/* ── The questionnaire's rhythm ──
   ONE GAP, SET ON THE CONTAINER. This used to style `label` children with a bottom
   margin, which was right when every field was a <label>. The fields are now a mix of
   wrappers, chip grids and revealed blocks, so half of them had no spacing rule and the
   other half kept a margin nothing else matched — which is why it read as random. Every
   direct child of a field container is spaced by the same gap and nothing sets its own. */
.wizard-fields,
.wizard-fields > [data-demand],
.wizard-fields > [data-tariff],
.upload-block {
  display: flex;
  flex-direction: column;
  gap: 22px;
}
.wizard-fields > * { margin: 0; }

/* The monthly grid is still made of labels, and they are the one place a label is the
   field rather than a wrapper around one. */
.monthly-grid label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 0.78rem;
  color: var(--muted);
  margin: 0;
}

/* ── The explanation on a question ──
   Replaces the native `title` attribute, which could not be fixed: its delay and its tiny
   system font belong to the operating system, it never appears on a touch screen, and a
   span cannot be focused. This is a button, so hover, focus and tap all reach it — and it
   is CSS-only, so it survives every re-render the wizard does with nothing to re-wire. */
.tipwrap { position: relative; display: inline-block; vertical-align: middle; margin-left: 6px; }

.tipdot {
  display: flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; padding: 0;
  border-radius: 999px;
  background: transparent;
  border: 1px solid var(--accent2);
  color: var(--accent2);
  font-size: 0.62rem; font-weight: 800; font-family: inherit;
  line-height: 1;
  transition: background 0.12s, color 0.12s;
}
.tipdot:hover, .tipwrap:focus-within .tipdot { background: var(--accent2); color: var(--bg); }

.tipbox {
  position: absolute;
  left: -8px;
  top: calc(100% + 9px);
  z-index: 60;
  width: 300px;
  max-width: 78vw;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
  /* No delay. The whole complaint about the old one was the wait. */
  opacity: 0;
  visibility: hidden;
  transform: translateY(-3px);
  transition: opacity 0.12s, transform 0.12s, visibility 0.12s;
  text-align: left;
  white-space: normal;
}
.tipwrap:hover .tipbox,
.tipwrap:focus-within .tipbox { opacity: 1; visibility: visible; transform: translateY(0); }

.tipbox::before {
  content: '';
  position: absolute; left: 13px; top: -5px;
  width: 9px; height: 9px;
  background: var(--bg);
  border-left: 1px solid var(--border);
  border-top: 1px solid var(--border);
  transform: rotate(45deg);
}
.tip-body { font-size: 0.83rem; color: var(--text); line-height: 1.6; font-weight: 400; }
.tip-foot {
  font-size: 0.78rem; color: var(--muted); line-height: 1.55; font-weight: 400;
  padding-top: 8px; border-top: 1px solid var(--border);
}

/* ── The questionnaire's fields ── */
.wfield { display: flex; flex-direction: column; gap: 8px; }
.wlabel { font-size: 0.88rem; font-weight: 600; color: var(--text); display: flex; align-items: center; }
.whint { font-size: 0.8rem; color: var(--muted); line-height: 1.55; }
.whint b { color: var(--text); }
.two-up { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 14px; }

/* Choices as buttons. See fields.js for why a native multi-select had to go. */
.chip-group { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 9px; }
.chip-btn {
  display: flex; align-items: center; gap: 10px;
  text-align: left;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  font-size: 0.88rem; font-weight: 600;
  color: var(--muted);
  transition: border-color 0.14s, background 0.14s, color 0.14s;
}
.chip-btn:hover { border-color: rgba(255, 255, 255, 0.22); color: var(--text); }
.chip-btn.on { background: var(--accent-glow); border-color: var(--accent-dim); color: var(--text); }
.chip-note {
  margin-left: auto;
  font-size: 0.58rem; font-weight: 800; letter-spacing: 0.4px;
  padding: 2px 7px; border-radius: 20px;
  background: var(--accent-glow); color: var(--accent);
  border: 1px solid var(--accent-dim);
  flex-shrink: 0;
}
.chip-btn:not(.on) .chip-note {
  background: rgba(148, 163, 184, 0.12); color: var(--muted); border-color: var(--border);
}

.chip-box {
  width: 15px; height: 15px; border-radius: 4px; flex-shrink: 0;
  border: 1.5px solid rgba(255, 255, 255, 0.22);
  transition: background 0.14s, border-color 0.14s;
}
.chip-btn.on .chip-box {
  background: var(--accent); border-color: var(--accent);
  /* The tick, drawn as a mask so it takes the token colour rather than a fixed one. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230e1420' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
  background-size: 11px; background-repeat: no-repeat; background-position: center;
}

/* The Other pattern: tied to the answer above it by a rule, not floating below as a
   second question. */
.other-reveal {
  padding-left: 14px;
  border-left: 2px solid var(--accent-dim);
  display: flex; flex-direction: column; gap: 7px;
}
.other-reveal label { display: flex; flex-direction: column; gap: 7px; font-size: 0.85rem; color: var(--muted); }

/* ── The address, and what we know about it ── */
.addr-row { display: flex; gap: 9px; }
.addr-row input { flex: 1; }
.addr-state {
  display: flex; align-items: flex-start; gap: 10px;
  border-radius: 10px; padding: 12px 14px;
  border: 1px solid var(--border);
}
.addr-state svg { width: 16px; height: 16px; flex-shrink: 0; margin-top: 2px; }
.addr-state.ok { border-color: var(--accent-dim); background: var(--accent-glow); color: var(--accent); }
.addr-state.bad { border-color: rgba(255, 71, 87, 0.4); background: rgba(255, 71, 87, 0.06); color: var(--red); }
.addr-state.warn { border-color: rgba(255, 165, 2, 0.4); background: rgba(255, 165, 2, 0.06); color: var(--amber); }
.addr-state.busy { color: var(--muted); font-size: 0.86rem; }
.addr-t { font-size: 0.86rem; font-weight: 700; color: var(--text); }
.addr-b { font-size: 0.83rem; color: var(--muted); margin-top: 3px; line-height: 1.55; }

.derived {
  display: flex; align-items: center; gap: 10px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--border);
  border-radius: 10px; padding: 12px 14px;
  font-size: 0.92rem; color: var(--text);
}
.derived-tag {
  font-size: 0.6rem; font-weight: 800; letter-spacing: 0.4px;
  padding: 2px 8px; border-radius: 20px;
  background: var(--accent-glow); color: var(--accent); border: 1px solid var(--accent-dim);
}
.derived.warn .derived-tag { background: rgba(255, 165, 2, 0.12); color: var(--amber); border-color: var(--amber); }

/* ── Rates ── */
.rate-input { display: flex; align-items: stretch; border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }
.rate-input input { border: none !important; border-radius: 0 !important; background: var(--field); }
.rate-input input:focus { box-shadow: none !important; }
.rate-input:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-glow); }
.rate-unit {
  display: flex; align-items: center; padding: 0 14px;
  background: rgba(255, 255, 255, 0.05);
  border-left: 1px solid var(--border);
  font-size: 0.85rem; font-weight: 600; color: var(--muted); white-space: nowrap;
}

.note-blue {
  border: 1px solid rgba(59, 163, 255, 0.30);
  background: rgba(59, 163, 255, 0.05);
  border-radius: 10px; padding: 12px 14px;
  font-size: 0.84rem; color: var(--text); line-height: 1.6;
}
.nav-block { font-size: 0.82rem; color: var(--amber); margin-top: 10px; text-align: right; }

/* ── The uploads, explained before the file dialog ── */
.upload-block {
  border: 1px solid var(--accent-dim);
  background: rgba(0, 212, 170, 0.05);
  border-radius: 13px; padding: 20px 22px;
  display: flex; flex-direction: column; gap: 16px;
}
.upload-block.slim { border-color: var(--border); background: rgba(255, 255, 255, 0.03); }
.upload-head { font-size: 0.95rem; font-weight: 700; color: var(--text); }
.upload-lede { font-size: 0.85rem; color: var(--muted); line-height: 1.6; margin-top: -8px; }
.upload-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 18px; }
.upload-cap { font-size: 0.66rem; font-weight: 700; letter-spacing: 0.6px; color: var(--muted); margin-bottom: 10px; }
.upload-list { list-style: none; display: flex; flex-direction: column; gap: 9px; }
.upload-list li {
  position: relative; padding-left: 20px;
  font-size: 0.84rem; color: var(--text); line-height: 1.55;
}
.upload-list li::before {
  content: ''; position: absolute; left: 3px; top: 8px;
  width: 6px; height: 6px; border-radius: 999px; background: var(--accent);
}
.upload-example {
  border: 1px solid var(--border); border-radius: 9px; overflow: hidden;
  font-family: ui-monospace, SFMono-Regular, monospace; font-size: 0.76rem;
}
.uex-row {
  display: grid; grid-template-columns: 1.6fr 1fr; gap: 10px;
  padding: 7px 12px; color: var(--text);
  border-top: 1px solid var(--border);
}
.uex-row span:last-child { text-align: right; }
.uex-row.uex-head { background: var(--field); color: var(--muted); border-top: none; }
.uex-row.uex-more { color: var(--muted); opacity: 0.7; display: block; }
.btn-secondary.sm { font-size: 0.82rem; padding: 8px 14px; width: 100%; margin-top: 10px; }

.drop {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  border: 2px dashed var(--border); border-radius: 11px;
  padding: 22px; cursor: pointer;
  font-size: 0.88rem; color: var(--muted);
  transition: border-color 0.15s, color 0.15s;
}
.drop:hover { border-color: var(--accent); color: var(--accent); }
.drop input { display: none; }

/* ── The summary ── */
.sum-lede { font-size: 0.9rem; color: var(--muted); line-height: 1.65; margin-bottom: 18px; }
.sum-flags { display: flex; flex-direction: column; gap: 10px; margin-bottom: 22px; }
.sum-flag {
  display: flex; gap: 12px; align-items: flex-start;
  border-radius: 11px; padding: 14px 16px;
  border: 1px solid var(--border);
}
.sum-flag svg { width: 17px; height: 17px; flex-shrink: 0; margin-top: 1px; }
.sum-flag.warn { border-color: rgba(255, 165, 2, 0.35); background: rgba(255, 165, 2, 0.06); color: var(--amber); }
.sum-flag.note { border-color: rgba(59, 163, 255, 0.28); background: rgba(59, 163, 255, 0.05); color: var(--accent2); }
.sum-flag-t { font-size: 0.88rem; font-weight: 700; color: var(--text); margin-bottom: 3px; }
.sum-flag-b { font-size: 0.83rem; color: var(--muted); line-height: 1.6; }

.sum-group {
  border: 1px solid var(--border); border-radius: 12px;
  background: var(--panel); padding: 16px 18px 8px; margin-bottom: 14px;
}
.sum-head { display: flex; align-items: center; gap: 10px; padding-bottom: 8px; font-size: 0.92rem; font-weight: 700; color: var(--text); }
.sum-head .linkish { margin-left: auto; }
.sum-row { display: grid; grid-template-columns: 1fr 1.3fr; gap: 16px; padding: 9px 0; border-top: 1px solid var(--border); }
.sum-k { font-size: 0.83rem; color: var(--muted); }
.sum-v { font-size: 0.85rem; color: var(--text); line-height: 1.5; }
.sum-v.none { color: var(--muted); opacity: 0.55; }
.sum-foot { font-size: 0.82rem; color: var(--muted); line-height: 1.6; padding: 14px 2px 0; }

/* ── The questionnaire's controls ──
   Native <select>, restyled. A hand-built listbox would look the same and throw away the
   keyboard behaviour, the mobile picker and the screen-reader support — not a trade worth
   making for a chevron.

   `input:not([type="file"])` AND NOT `input[type="text"]`: an <input> with no type
   attribute defaults to text but does not MATCH [type="text"], and half the fields in
   this questionnaire are written without one. They rendered as untouched browser
   controls — white boxes on a dark page — which is exactly what it looked like. */
.wizard-fields input:not([type="file"]),
.wizard-fields select,
.wizard-fields textarea {
  width: 100%;
  background: var(--field);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  font-size: 0.92rem;
  color: var(--text);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.wizard-fields input:not([type="file"]):hover,
.wizard-fields select:hover,
.wizard-fields textarea:hover { border-color: rgba(148, 163, 184, 0.45); }
.wizard-fields input:not([type="file"]):focus,
.wizard-fields select:focus,
.wizard-fields textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-glow);
}
.wizard-fields input::placeholder,
.wizard-fields textarea::placeholder { color: var(--muted); opacity: 0.7; }
.wizard-fields select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 38px;
  /* The chevron, drawn rather than fetched: the CSP is script-src 'self' and there is no
     image pipeline, and an inline SVG data URI needs neither. currentColor cannot be used
     inside a data URI, so the stroke is the muted token's value. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 13px center;
  cursor: pointer;
}
/* The option list is the platform's own and cannot be styled beyond these two. They are
   the two that matter: without them a dark page renders the list white-on-white, and a
   light page renders it on whatever the UA feels like. */
.wizard-fields select option { background: var(--field); color: var(--text); }
.wizard-fields textarea { min-height: 84px; resize: vertical; line-height: 1.6; }

/* Nav row */
.wizard-nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 28px;
}

.btn-primary {
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  color: #0e1420;
  font-weight: 700;
  font-size: 0.9rem;
  padding: 10px 24px;
  border-radius: 8px;
  border: none;
  transition: opacity 0.15s, transform 0.15s;
}

.btn-primary:hover { opacity: 0.88; transform: translateY(-1px); }

.btn-secondary {
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--muted);
  font-size: 0.9rem;
  font-weight: 500;
  padding: 10px 20px;
  border-radius: 8px;
  transition: border-color 0.15s, color 0.15s;
}

.btn-secondary:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
}

.btn-secondary:disabled {
  opacity: 0.35;
  cursor: default;
}

/* ── Results view ── */
.results {
  max-width: 1160px;
  margin: 0 auto;
  padding: 24px 24px 56px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* Header bar */
.rp-hdr {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.rp-proj {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text);
}

.rp-mode {
  font-size: 0.78rem;
  color: var(--muted);
  margin-top: 2px;
}

.rp-btn {
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--muted);
  font-size: 0.82rem;
  padding: 6px 14px;
  border-radius: 8px;
  transition: border-color 0.15s, color 0.15s;
}

.rp-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* Hero 2-col grid */
/* THE MAP LEADS, AND THE FIGURES SIT UNDER IT.
   This was a two-column grid, and the column of KPIs is always taller than a satellite
   crop — so the grid row took its height from the figures and the space under the image
   showed the hero's own background. That is the void.
   Stretching the map to fill the row is not available: paintComposite lays an SVG panel
   overlay across the whole box, so cropping or letterboxing the image slides every panel
   off the roof it is drawn on. The image has to keep its aspect ratio, which means the
   ROW has to follow the image rather than the other way round. Stacking is the only
   arrangement where that is true at every width — and it is what the canvas showed. */
.hero {
  display: flex;
  flex-direction: column;
  gap: 0;
  background: var(--panel);
  border: 1px solid var(--accent);
  border-radius: 14px;
  overflow: hidden;
  position: relative;
}

.hero-badge {
  position: absolute;
  top: 14px;
  left: 14px;
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  color: #0e1420;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.6px;
  padding: 4px 10px;
  border-radius: 20px;
  z-index: 2;
}

/* Map placeholder */
.sat {
  /* A placeholder height for the moment before the image arrives, and nothing else: the
     box is the picture as soon as there is one. */
  min-height: 140px;
  display: block;
  background: linear-gradient(160deg, var(--accent-glow) 0%, rgba(59, 163, 255, 0.10) 100%);
  position: relative;
  overflow: hidden;
}

/* ONCE THERE IS A PICTURE, THE BOX IS THE PICTURE. min-height is for the empty state;
   left in place it padded a wide, shallow satellite crop with a strip of gradient
   underneath — which reads as a white gap below the image on a light page. */
.sat:has(img) { min-height: 0; }

.sat::after {
  content: '';
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    -45deg,
    transparent,
    transparent 10px,
    rgba(255, 255, 255, 0.03) 10px,
    rgba(255, 255, 255, 0.03) 11px
  );
}

.sat-tag {
  position: absolute;
  bottom: 12px;
  left: 12px;
  background: rgba(14, 20, 32, 0.72);
  color: var(--text);
  font-size: 0.75rem;
  padding: 4px 10px;
  border-radius: 6px;
  backdrop-filter: blur(4px);
  z-index: 1;
}

/* Hero sidebar */
.hero-side {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 18px 20px 20px;
  /* Under the map now, not beside it. */
  border-top: 1px solid var(--border);
}
/* The four figures read as a row beneath the picture rather than a column beside it. */
.hero-side .kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px;
}
.hero-side .cta { align-self: flex-start; }

/* East-west toggle */
.ew-toggle {
  display: flex;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}

.ew-toggle button {
  flex: 1;
  background: transparent;
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 500;
  padding: 7px 10px;
  border: none;
  transition: background 0.15s, color 0.15s;
}

.ew-toggle button.on {
  background: var(--accent-glow);
  color: var(--accent);
  font-weight: 600;
}

/* KPI grid */
.kpis {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.kpi {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
}

.kpi .l {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 4px;
}

.kpi .v {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text);
  line-height: 1.2;
}

.kpi .v small {
  font-size: 0.72rem;
  font-weight: 400;
  color: var(--muted);
}

/* CTA button */
.cta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  color: #0e1420;
  font-size: 0.88rem;
  font-weight: 700;
  padding: 12px 16px;
  border-radius: 10px;
  border: none;
  text-align: left;
  line-height: 1.3;
  transition: opacity 0.15s, transform 0.15s;
  width: 100%;
}

.cta:hover { opacity: 0.88; transform: translateY(-1px); }

.cta small {
  font-size: 0.72rem;
  font-weight: 400;
  opacity: 0.8;
  margin-top: 3px;
  display: block;
}

/* Flag alert */
.flag-alert {
  background: transparent;
  border: 1px solid var(--amber);
  color: var(--amber);
  font-size: 0.78rem;
  font-weight: 500;
  padding: 8px 12px;
  border-radius: 8px;
  text-align: left;
  width: 100%;
  transition: background 0.15s;
}

.flag-alert:hover {
  background: rgba(255, 165, 2, 0.08);
}

/* Recommendations section */
.recs-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 13px;
}
/* Every block on the overview is separated by the same distance, so the page has one
   rhythm rather than four accidental ones. */
.results .cards { margin-bottom: 26px; }

.recs-head h3 {
  font-size: 1rem;
  font-weight: 700;
  color: var(--text);
  flex: 1;
}

.rtabs {
  display: flex;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}

.rtabs button {
  background: transparent;
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 500;
  padding: 6px 14px;
  border: none;
  border-left: 1px solid var(--border);
  transition: background 0.15s, color 0.15s;
}

.rtabs button:first-child { border-left: none; }

.rtabs button.on {
  background: var(--accent-glow);
  color: var(--accent);
  font-weight: 600;
}

/* Config cards */
.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

.card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.card.live {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent-glow);
}

.badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 20px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.4px;
  width: fit-content;
}

.b-live {
  background: var(--accent-glow);
  color: var(--accent);
  border: 1px solid var(--accent-dim);
}

.b-soon {
  background: rgba(148, 163, 184, 0.10);
  color: var(--muted);
  border: 1px solid var(--border);
}

.card h4 {
  font-size: 1rem;
  font-weight: 700;
  color: var(--text);
}

.sub {
  font-size: 0.8rem;
  color: var(--muted);
}

/* `.open` is now rendered on its own — the "Run study →" button on a battery card that
   has not been run. It therefore needs a resting appearance of its own; `.open-live`
   follows and still wins for the gradient variant. */
.open {
  margin-top: auto;
  padding: 9px 16px;
  border-radius: 8px;
  font-size: 0.85rem;
  font-weight: 600;
  width: 100%;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  transition: opacity 0.15s, transform 0.15s, border-color 0.15s, color 0.15s;
}

.open:hover { border-color: var(--accent); color: var(--accent); }

.open-live {
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  color: #0e1420;
  border: none;
}

.open-live:hover { opacity: 0.88; transform: translateY(-1px); color: #0e1420; }

/* Comparison chart panel */
.cmp {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 20px;
}

.note {
  font-size: 0.75rem;
  color: var(--muted);
  margin-top: 10px;
  font-style: italic;
}

/* Loading / error states */
.loading {
  text-align: center;
  padding: 80px 24px;
  font-size: 1rem;
  color: var(--muted);
}

.loading #loadState {
  color: var(--accent);
  font-weight: 600;
}

.error {
  max-width: 520px;
  margin: 60px auto;
  background: var(--panel);
  border: 1px solid var(--red);
  border-radius: 12px;
  padding: 32px 36px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.error h3 {
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--red);
}

.error p {
  font-size: 0.9rem;
  color: var(--text);
}

.hint {
  font-size: 0.82rem;
  color: var(--muted);
  font-style: italic;
}

/* ── Responsive: stack hero on narrow screens ── */
@media (max-width: 720px) {
  .hero {
    grid-template-columns: 1fr;
  }
  .hero-side {
    border-left: none;
    border-top: 1px solid var(--border);
  }
  .cards {
    grid-template-columns: 1fr;
  }
  .kpis {
    grid-template-columns: 1fr 1fr;
  }
}

/* Summary */
.summary ul {
  list-style: none;
  margin-bottom: 16px;
}

.summary ul li {
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
  font-size: 0.9rem;
  color: var(--text);
}

.summary ul li b {
  color: var(--muted);
  margin-right: 6px;
}

.summary p {
  font-size: 0.85rem;
  color: var(--muted);
  margin-top: 12px;
}

/* ── Solar Layout view ── */

/* Generic card panel (used throughout layout view) */
.panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 18px 20px;
}

.panel h4 {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 14px;
}

/* A chart heading that follows a KPI row (the Generation section) sat hard against
   the tiles above it, so it read as part of them rather than as the start of the
   next thing. The gap belongs to the heading, not to an empty spacer element. */
.panel .kpis + h4 { margin-top: 20px; }

/* Outer container */
.sl {
  max-width: 1200px;
  margin: 0 auto;
  padding: 24px 24px 56px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* Top bar: back | title | spacer | ew-toggle */
.sl-top {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

/* A <span> on the review page and a <button> on the battery study page, so the
   UA button styling has to be cleared here rather than assumed away. */
.sl-back {
  background: transparent;
  border: none;
  padding: 0;
  color: var(--muted);
  cursor: pointer;
  font-size: 0.85rem;
  transition: color 0.15s;
  white-space: nowrap;
}

.sl-back:hover { color: var(--accent); }

.sl-title {
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--text);
  line-height: 1.2;
}

.sl-sub {
  font-size: 0.78rem;
  color: var(--accent2);
  margin-top: 2px;
}

/* Which resolution the financial model actually ran at (matching_resolution). */
.res-badge {
  display: inline-block;
  background: rgba(148, 163, 184, 0.10);
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 20px;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.4px;
  padding: 2px 8px;
  white-space: nowrap;
}

/* Intro banner */
.intro {
  background: var(--accent-glow);
  border: 1px solid var(--accent2);
  border-radius: 10px;
  padding: 12px 16px;
  font-size: 0.88rem;
  color: var(--text);
  line-height: 1.5;
}

.intro .more {
  color: var(--accent2);
  cursor: pointer;
  font-weight: 500;
}

/* Hero: 2-col map | metricstack */
.sl-hero {
  display: grid;
  grid-template-columns: 1fr 360px;
  gap: 16px;
  align-items: start;
}

/* Map container */
.map#layoutMap {
  min-height: 340px;
  border-radius: 12px;
  border: 1px solid var(--border);
  overflow: hidden;
  background: linear-gradient(160deg, var(--accent-glow) 0%, rgba(59,163,255,0.10) 100%);
  position: relative;
}

/* Metric stack right column */
.metricstack {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* South vs EW comparison table */
.cmp-tbl {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.82rem;
}

.cmp-tbl th,
.cmp-tbl td {
  padding: 6px 8px;
  text-align: right;
  border-bottom: 1px solid var(--border);
  color: var(--text);
}

.cmp-tbl th { color: var(--muted); font-weight: 600; }
.cmp-tbl td:first-child,
.cmp-tbl th:first-child { text-align: left; }

.cmp-tbl .win {
  color: var(--accent);
  font-weight: 700;
}

/* Refine panel */
.refine-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}

.refine-head h4 {
  margin-bottom: 0;
  flex: 1;
}

.opt-pill {
  background: var(--accent-glow);
  color: var(--accent);
  border: 1px solid var(--accent-dim);
  border-radius: 20px;
  font-size: 0.68rem;
  font-weight: 700;
  padding: 3px 10px;
  white-space: nowrap;
}

.reset {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  font-size: 0.78rem;
  padding: 5px 12px;
  border-radius: 7px;
  transition: border-color 0.15s, color 0.15s;
}

.reset:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.rsub {
  font-size: 0.78rem;
  color: var(--muted);
  margin-bottom: 14px;
  line-height: 1.5;
}

/* Param sliders grid */
.params {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px 20px;
  margin-bottom: 16px;
}

.p label {
  display: block;
  font-size: 0.78rem;
  color: var(--muted);
  font-weight: 500;
  margin-bottom: 6px;
}

.ctl {
  display: flex;
  align-items: center;
  gap: 8px;
}

.ctl input[type="range"] {
  flex: 1;
  accent-color: var(--accent2);
  cursor: pointer;
}

.val {
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--text);
  min-width: 36px;
  text-align: right;
}

/* Refine action buttons */
.refine-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.btn-calc {
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  color: #0e1420;
  font-size: 0.88rem;
  font-weight: 700;
  padding: 10px 22px;
  border-radius: 8px;
  border: none;
  transition: opacity 0.15s, transform 0.15s;
}

.btn-calc:hover:not(:disabled) { opacity: 0.88; transform: translateY(-1px); }
.btn-calc:disabled { opacity: 0.45; cursor: default; }

.btn-redetect {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 500;
  padding: 10px 18px;
  border-radius: 8px;
  transition: border-color 0.15s, color 0.15s;
}

.btn-redetect:hover {
  border-color: var(--accent2);
  color: var(--accent2);
}

.redetect-notes {
  flex: 1;
  min-width: 220px;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  font-size: 0.85rem;
  padding: 10px 12px;
  border-radius: 8px;
}

.redetect-notes::placeholder { color: var(--muted); }

/* Info row: monthly | flags | coming-next */
.inforow {
  display: grid;
  /* Two panels now, not three: the financial summary moved to the page it belongs on.
     The chart takes the width that freed up, because a twelve-bar chart in a third of a
     row is a sparkline. */
  grid-template-columns: 2fr 1fr;
  gap: 16px;
  align-items: start;
}

/* Loss stack rows */
.loss {
  display: flex;
  justify-content: space-between;
  font-size: 0.78rem;
  color: var(--muted);
  padding: 3px 0;
  border-bottom: 1px solid var(--border);
}

.pnote {
  font-size: 0.78rem;
  color: var(--muted);
  margin-top: 10px;
  font-style: italic;
}

.muted {
  color: var(--muted);
}

/* Where a price figure's prices came from. Four sentences share .price-provenance and
   read as an ordinary footnote, because three of the four are simply true and need no
   emphasis. THE BENCHMARK IS THE ONE A READER MUST NOT SKIM: those prices are somebody
   else's published tariff standing in for this customer's, and a reader who misses the
   sentence budgets against a contract they do not have. It wears the same amber left
   rule as .flag-inline.flag-caution, so "read this before you quote it" looks the same
   everywhere in the product. The class is set from the machine-readable provenance
   (financialSpine.renderPriceProvenance), never from the words. */
.price-provenance-caveat {
  border-left: 3px solid var(--amber);
  background: color-mix(in srgb, var(--amber) 9%, var(--bg));
  padding: 6px 10px;
  border-radius: 4px;
  font-style: normal;
}

/* Flags panel. The amber dress is the WARNING, so it is worn only when there is
   something to warn about — a clean run in an amber box reads as a problem at a
   glance and the reader has to stop and read it to find out it is the opposite. */
.panel.flags {
  background: rgba(255, 165, 2, 0.06);
  border-color: var(--amber);
}

/* A panel holding nothing but ungraded notes. Amber on this container means "read this
   before you quote it" and is set from the severity, never from the fact that flags
   exist -- see batteryFlags.flagsForBlock and solarSolutionView.flagsSection. */
.panel.flags.notes { background: var(--panel); border-color: var(--border); }

.panel.flags.clean { background: var(--panel); border-color: var(--line); }
.panel.flags.clean .flag-inline { border-color: var(--line); color: var(--muted); }

/* ONE FLAG CONTAINER, ONE SET OF SPACINGS. The battery page's rows moved inside the
   solar page's panel, so the first row must not double the panel's own top padding. */
.panel.flags > .flag-inline:first-of-type { margin-top: 2px; }
.panel.flags > h4 { margin-bottom: 10px; }

.flag-item {
  font-size: 0.82rem;
  color: var(--amber);
  padding: 5px 0;
  border-bottom: 1px solid rgba(255, 165, 2, 0.15);
}

.flag-item:last-of-type { border-bottom: none; }

.src {
  font-size: 0.72rem;
  color: var(--muted);
  margin-top: 10px;
  font-style: italic;
}

/* Coming-next placeholder panel */
.panel.soon {
  border-style: dashed;
  border-color: var(--border);
  background: transparent;
}

.badge-soon {
  display: inline-block;
  background: rgba(148, 163, 184, 0.10);
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 20px;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.4px;
  padding: 2px 8px;
  vertical-align: middle;
  margin-left: 6px;
}

.ph {
  min-height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  font-size: 0.82rem;
  border: 1px dashed var(--border);
  border-radius: 8px;
  padding: 16px;
  text-align: center;
}

/* ── Responsive: Solar Layout ── */
@media (max-width: 900px) {
  .sl-hero {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 720px) {
  .params {
    grid-template-columns: repeat(2, 1fr);
  }
  .inforow {
    grid-template-columns: 1fr;
  }
}

/* ── Solar Solution page: demand/supply panel ── */
.ds-panel { margin: 16px 0; }
.ds-panel h4 { margin-bottom: 10px; }

/* ── Solar Solution page: section title + bigger tab toggle ── */
.ss-tab-bar { display: flex; align-items: center; gap: 16px; margin: 34px 0 18px; padding-top: 22px; border-top: 1px solid var(--border); }
.ss-section-title { font-size: 1.45rem; font-weight: 800; }
.ss-section-sub { font-size: 0.78rem; color: var(--muted); margin-top: 2px; }
.rtabs-lg button { padding: 10px 22px; font-size: 0.85rem; }

/* ── Solar Solution page: demand/supply split ── */
.ds-split { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-bottom: 18px; }

/* ── Financial spine: chart rows (ported from demo_2.html, same 18px rhythm) ── */
.chart-row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-bottom: 18px; }
.chart-row-2 .chart-card { margin-bottom: 0; }
.chart-card { background: var(--panel); border: 1px solid var(--border); border-radius: 12px; padding: 18px; margin-bottom: 18px; }
.chart-card-title { font-size: 0.82rem; font-weight: 700; margin-bottom: 4px; }
.chart-card-sub { font-size: 0.72rem; color: var(--muted); margin-bottom: 14px; }
.sensitivity-placeholder { opacity: 0.7; border-style: dashed; }

/* Chart.js runs with maintainAspectRatio:false so a chart fills the box it is given —
   which means it needs a box. Without a bounded height the canvas grows to whatever
   the layout allows, and a twelve-bar monthly chart ends up a full viewport tall.
   The canvas `height` attribute is only the initial backing-store size; it does not
   constrain a responsive chart. */
.chart-card canvas,
.panel canvas { max-height: 260px; }
.day-card canvas { max-height: 120px; }

/* ── Study shell: the scoping controls between the view title and the strip ──
   One quiet, wrapping row of switches — not a section. Everything in it is sized to
   its content: a full-width bar here reads as page content and competes with the
   section titles below, which is exactly what it must not do. */
.ss-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.ss-controls .ppa-selector { margin: 0; }

/* Segmented switch. Same visual language as .ew-toggle but WITHOUT its `flex: 1` —
   ew-toggle fills the narrow hero column it belongs to, and that stretch is wrong
   for an inline control.

   NAMED .ctl-seg, NOT .seg: `.seg` was already taken, by the wizard's stepper about a
   thousand lines up, which is `flex-direction: column; flex: 1` and owns `.seg .dot`
   and `.seg .lbl` besides. Declaring `display: inline-flex` later did not undo the
   column direction or the stretch — properties the second block never mentions are
   simply inherited from the first — so the switch rendered as a full-width stack. */
.ctl-seg {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}

.ctl-seg button {
  background: transparent;
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 500;
  padding: 6px 14px;
  border: none;
  white-space: nowrap;
  transition: background 0.15s, color 0.15s;
}

.ctl-seg button:hover { color: var(--text); }
.ctl-seg button.on { background: var(--accent-glow); color: var(--accent); font-weight: 600; }

/* ── Financial spine: PPA structure selector (pills, replaces the old accordion) ── */
.ppa-selector { display: flex; gap: 8px; flex-wrap: wrap; margin: 14px 0; }
.ppa-pill { padding: 6px 14px; border-radius: 16px; border: 1px solid var(--border); background: var(--panel); color: var(--text); font-size: 0.78rem; font-weight: 600; }
.ppa-pill.on { background: var(--accent); color: #0f1923; border-color: var(--accent); }
.ppa-pill:disabled { opacity: 0.5; cursor: not-allowed; }

/* ── Financial spine: detailed tables (ported from demo_2.html) ── */
.table-scroll { overflow-x: auto; margin-bottom: 18px; }
.data-table { width: 100%; border-collapse: collapse; font-size: 0.76rem; }
.data-table th { padding: 8px 11px; text-align: right; color: var(--muted); font-weight: 600; border-bottom: 1px solid var(--border); white-space: nowrap; }
.data-table th:first-child { text-align: left; }
.data-table td { padding: 6px 11px; text-align: right; border-bottom: 1px solid var(--border); }
.data-table td:first-child { text-align: left; }
.data-table .group-header td { font-size: 0.68rem; font-weight: 700; color: var(--accent); text-transform: uppercase; letter-spacing: 0.5px; padding-top: 12px; border-bottom: 1px solid var(--border); }
.data-table .total-row td { font-weight: 700; color: var(--accent); border-top: 1px solid var(--border); background: var(--accent-glow); }
.two-col-tables { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-bottom: 18px; }
.capex-table { width: 100%; border-collapse: collapse; font-size: 0.76rem; }
.capex-table th { padding: 7px 10px; text-align: left; color: var(--muted); font-weight: 600; font-size: 0.7rem; border-bottom: 1px solid var(--border); }
.capex-table td { padding: 6px 10px; border-bottom: 1px solid var(--border); font-size: 0.76rem; }
.capex-table td:not(:first-child) { text-align: right; }
.capex-table .total-row td { font-weight: 700; color: var(--accent); border-top: 1px solid var(--border); }

/* ── Financial spine v2: KPI hierarchy ── */
.kpis-primary { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin-bottom: 14px; }
.kpis-primary .kpi { padding: 16px 18px; }
.kpis-primary .kpi .v { font-size: 1.55rem; }

.more-kpis { border: 1px solid var(--border); border-radius: 12px; background: var(--panel); margin-bottom: 18px; }
.more-kpis summary { cursor: pointer; padding: 11px 16px; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.5px; text-transform: uppercase; color: var(--muted); list-style: none; }
.more-kpis summary::-webkit-details-marker { display: none; }
.more-kpis summary::after { content: '▴ hide'; float: right; font-size: 0.66rem; }
.more-kpis:not([open]) summary::after { content: '▾ show'; }
.kpis-secondary { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; padding: 0 16px 16px; }
.kpis-secondary .kpi .v { font-size: 0.92rem; }
.kpi-note { font-size: 0.62rem; color: var(--muted); margin-top: 4px; }

.kpis-capex { padding: 0; margin-top: 10px; }

.summary-table-bar { display: flex; align-items: center; justify-content: space-between; margin: 28px 0 10px; }
.summary-table-label { color: var(--muted); font-size: 0.7rem; font-weight: 700; letter-spacing: 0.5px; }
.detail-link { background: none; border: none; color: var(--accent); font-size: 0.78rem; font-weight: 700; cursor: pointer; padding: 0; }
.detail-link:hover { text-decoration: underline; }

/* ── Financial spine v2: full-detail modal ── */
.modal-backdrop { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.55); display: flex; align-items: center; justify-content: center; z-index: 1000; padding: 24px; outline: none; }
/* The global .hidden rule (line ~316) is declared EARLIER than .modal-backdrop, so at
   equal specificity the backdrop's display:flex would win and the overlay could never
   close. The compound selector outranks both regardless of source order. */
.modal-backdrop.hidden { display: none; }
.modal-panel { background: var(--bg); border: 1px solid var(--border); border-radius: 14px; max-width: 1100px; width: 100%; max-height: 85vh; overflow-y: auto; padding: 22px; }
.modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 14px; }
.modal-title { font-size: 1.05rem; font-weight: 800; }
.modal-sub { font-size: 0.74rem; color: var(--muted); margin-top: 2px; }
.modal-head-actions { display: flex; align-items: center; gap: 10px; }
.btn-csv { padding: 6px 12px; border-radius: 8px; border: 1px solid var(--border); background: var(--panel); color: var(--muted); font-size: 0.74rem; font-weight: 700; }
.btn-csv:disabled { opacity: 0.55; cursor: not-allowed; }
.modal-close { background: none; border: none; color: var(--muted); font-size: 1.35rem; cursor: pointer; line-height: 1; padding: 0 4px; }
.modal-tabs { margin-bottom: 14px; display: inline-flex; }
/* Day/week HH explorer popup: control row above the chart. */
.hh-explorer-controls { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.hh-explorer-controls input[type="date"] { background: var(--panel); color: var(--text); border: 1px solid var(--border); border-radius: 8px; padding: 6px 10px; font-size: 0.78rem; }
.hh-explorer-label { font-size: 0.82rem; font-weight: 700; margin-left: auto; }

/* ── Financial spine v2.1: bordered table cards + fill-height chart cards ── */
.table-panel { margin: 28px 0 18px; }
.table-panel .summary-table-bar { margin: 0 0 12px; }
.table-panel .table-scroll { margin-bottom: 0; }
.table-panel .pnote { margin-top: 10px; margin-bottom: 0; }
.chart-card-fill { display: flex; flex-direction: column; }
.chart-fill-box { position: relative; flex: 1; min-height: 160px; }

/* ── Boundary editor ── */
.mapwrap { position: relative; }
/* The strip under the map: where the boundary came from, and what can be done about it.
   It was a translucent black bar with a bold word in it — dark-mode only, no relation to
   any other control in the app, and its buttons were the browser's. */
.bnd-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px;
  font-size: 0.82rem; color: var(--muted);
  background: var(--panel);
  border-top: 1px solid var(--border);
  border-radius: 0 0 11px 11px;
  flex-wrap: wrap;
}
.bnd-bar b {
  color: var(--text); font-weight: 600;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 2px 10px;
  font-size: 0.76rem;
  letter-spacing: 0.2px;
}
.bnd-bar button {
  font-size: 0.78rem; font-weight: 600;
  padding: 5px 12px; border-radius: 7px;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  transition: border-color 0.15s, color 0.15s;
}
.bnd-bar button:hover { border-color: var(--accent); color: var(--accent); }
.ghost-bar { background: rgba(255, 62, 165, 0.08); border-top-color: rgba(255, 62, 165, 0.35); }
.bnd-error { background: rgba(255, 71, 87, 0.08); border-top-color: rgba(255, 71, 87, 0.4); }
.bnd-error b { color: var(--red); border-color: var(--red); }
.bnd-stale b { color: var(--amber); border-color: var(--amber); }

/* The intro's "New to solar?" was a span that looked like a link and did nothing. */
.intro .more {
  background: transparent; border: none; padding: 0;
  color: var(--accent); font-size: inherit; font-weight: 600;
}
.intro .more:hover { color: var(--accent-dim); text-decoration: underline; }

/* A note that says a thing is not built yet, distinct from a note that says a fact. */
.pnote.soon {
  border-left: 2px solid var(--border);
  padding-left: 11px;
  margin-top: 12px;
  color: var(--muted);
  line-height: 1.6;
}
.bnd-warn { color: #ff6b6b; }
.edit-toolbar { position: absolute; top: .5rem; left: .5rem; z-index: 2; display: flex;
  gap: .5rem; align-items: center; padding: .35rem .6rem; border-radius: 8px;
  background: rgba(0,0,0,.55); color: #fff; font-size: .85rem; }
.edit-area { font-variant-numeric: tabular-nums; }

/* Apply = primary CTA (matches .btn-calc); Cancel = outline on the dark toolbar */
.edit-toolbar .btn-apply {
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  color: #0e1420;
  font-size: 0.88rem;
  font-weight: 700;
  padding: 8px 20px;
  border-radius: 8px;
  border: none;
  transition: opacity 0.15s, transform 0.15s;
}
.edit-toolbar .btn-apply:hover:not(:disabled) { opacity: 0.88; transform: translateY(-1px); }
.edit-toolbar .btn-apply:disabled { opacity: 0.45; cursor: default; }
.edit-toolbar .btn-cancel {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.35);
  color: #fff;
  font-size: 0.85rem;
  padding: 8px 14px;
  border-radius: 8px;
  transition: border-color 0.15s;
}
.edit-toolbar .btn-cancel:hover { border-color: #fff; }

/* Edit/Draw = secondary outline buttons (matches .btn-redetect) */
.btn-edit {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 500;
  padding: 10px 18px;
  border-radius: 8px;
  transition: border-color 0.15s, color 0.15s;
}
.btn-edit:hover:not(:disabled) { border-color: var(--accent2); color: var(--accent2); }
.btn-edit:disabled { opacity: 0.45; cursor: default; }

/* ══════════════════════════════════════════════════════════════════════════
   Study shell: the pinned section strip
   ══════════════════════════════════════════════════════════════════════════
   .subnav is position:sticky, so NO ancestor of it may carry an overflow other
   than visible — the first one that does becomes its scroll container and the
   strip then pins to the top of that box instead of to the viewport. Its
   ancestors are .sl / .results / .screen / main / body; none set overflow, and
   body's overflow-x:hidden propagates to the viewport rather than making body a
   scroll container. Check this before adding overflow anywhere above here.

   The strip's own overflow-x:auto is fine: an element is not its own ancestor.

   WHY top:0 AND ABOVE THE TOPBAR. studyShell.js scrolls a clicked section to
   58px from the viewport top, so nothing opaque may sit below that line. The
   strip therefore takes the top 58px for itself and covers .topbar while a study
   is being read — which is also why the condensed strip grows its own
   Financial/Technical toggle: the control that matters here never disappears.
   It is full-bleed so it covers the topbar completely rather than leaving the
   logo peeking out at the sides on a wide window. */
.subnav {
  position: sticky;
  /* PINS TO THE VIEWPORT. It used to pin at 52px, below a sticky topbar that has since
     been replaced by the left rail — leaving the strip floating with a gap above it that
     content scrolled through. Nothing sticky is above it now, so it clears nothing.
     studyShell.STRIP_OFFSET_PX must stay equal to this top plus the strip's own height,
     or a clicked section heading lands underneath it; Frontend/js/__tests__/studyShell.test.js
     asserts the pair across both files, because neither half can see the other. */
  top: 0;
  z-index: 99;
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  /* NOT FULL-BLEED ANY MORE. It used to be 100vw with a negative margin so that it
     covered the sticky topbar completely. That topbar was replaced by a LEFT RAIL, and a
     100vw element inside the main column starts at the viewport's left edge — so the
     strip ran straight over the rail, and its viewport-centred padding pushed the buttons
     out of line with the content by the rail's width. It is the width of its own column
     now, which is what it should have become when the topbar went. */
  margin-left: 0;
  padding: 15px 24px;
}

.subnav::-webkit-scrollbar { display: none; }

.subnav > button {
  background: transparent;
  border: none;
  color: var(--muted);
  font-size: 0.82rem;
  font-weight: 500;
  padding: 7px 12px;
  border-radius: 8px;
  white-space: nowrap;
  flex-shrink: 0;
  transition: background 0.15s, color 0.15s;
}

.subnav > button:hover { color: var(--text); background: var(--panel); }

.subnav > button.on {
  color: var(--accent);
  background: var(--accent-glow);
  font-weight: 700;
}

/* The Financial / Technical toggle, pinned in the strip at every scroll position.
   It is the coarser of the two navigations, so it sits to the LEFT of the section
   names and is separated from them by a rule — the eye reads view, then section. */
.vb-views {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  margin-right: 10px;
  padding-right: 10px;
  border-right: 1px solid var(--border);
  gap: 2px;
}

.vb-views button {
  background: transparent;
  border: none;
  border-radius: 7px;
  color: var(--muted);
  font-size: 0.82rem;
  font-weight: 600;
  padding: 6px 14px;
  white-space: nowrap;
  transition: background 0.15s, color 0.15s;
}

.vb-views button:hover { color: var(--text); }

.vb-views button.on {
  background: var(--accent);
  color: #0e1420;
}

.rtabs-sm {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: 7px;
  overflow: hidden;
}

.rtabs-sm button {
  background: transparent;
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 600;
  padding: 5px 11px;
  border: none;
  border-left: 1px solid var(--border);
  white-space: nowrap;
  transition: background 0.15s, color 0.15s;
}

.rtabs-sm button:first-child { border-left: none; }
.rtabs-sm button.on { background: var(--accent-glow); color: var(--accent); }

/* The "this section has notes" mark in the strip. */
.sect-flag { color: var(--amber); font-size: 0.85em; }

/* The point wireShell measures the title row against; it must take no space. */
#navAnchor { height: 0; }

/* ── Study shell: the sections themselves ── */
.sections {
  display: flex;
  flex-direction: column;
  gap: 34px;
}

/* 64px, against a strip of about 58: a heading reached by an anchor jump lands
   just below the strip rather than underneath it. */
.sect { scroll-margin-top: 58px; /* matches STRIP_OFFSET_PX in studyShell.js */ }
.sect > * { margin-bottom: 14px; }
.sect > :last-child { margin-bottom: 0; }

.sect-h {
  font-size: 1.15rem;
  font-weight: 800;
  color: var(--text);
}
.sect > .sect-h { margin-bottom: 4px; }

.sect-q {
  font-size: 0.85rem;
  color: var(--muted);
  line-height: 1.5;
  max-width: 78ch;
}
.sect > .sect-q { margin-bottom: 16px; }

/* ══════════════════════════════════════════════════════════════════════════
   Results page: battery card states
   ══════════════════════════════════════════════════════════════════════════ */
.card.is-running { border-color: var(--accent2); }
.card.is-failed { border-color: var(--red); }

.card.is-unavailable {
  border-style: dashed;
  opacity: 0.62;
}

/* Progress bar; the fill's width is set inline by resultsView. */
.card-bar {
  height: 6px;
  border-radius: 20px;
  background: var(--border);
  overflow: hidden;
}

.card-bar i {
  display: block;
  height: 100%;
  border-radius: 20px;
  background: linear-gradient(90deg, var(--accent), var(--accent2));
  transition: width 0.3s;
}

.card-figure {
  font-size: 1.65rem;
  font-weight: 800;
  color: var(--accent);
  line-height: 1.15;
}

.card-figure small {
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--muted);
}

.card-note {
  font-size: 0.82rem;
  color: var(--muted);
  line-height: 1.5;
}

/* The engine's own wording, written for a customer — worth reading, not greying out. */
.card.is-failed .card-note { color: var(--text); }

.card-hint {
  font-size: 0.78rem;
  color: var(--amber);
  line-height: 1.5;
}

/* ══════════════════════════════════════════════════════════════════════════
   Flags
   ══════════════════════════════════════════════════════════════════════════
   Severity must survive being read in greyscale, so colour is never the only
   difference: the .flag-sev pill spells the severity out in words, and the left
   border steps 5px / 3px / 1px from critical down to info. */
.flag-banner {
  border: 1px solid var(--border);
  border-left: 5px solid var(--muted);
  border-radius: 10px;
  padding: 14px 18px;
  background: var(--panel);
}

.flag-banner.flag-critical {
  border-color: var(--red);
  background: color-mix(in srgb, var(--red) 10%, var(--bg));
}

.flag-banner-title {
  font-size: 0.95rem;
  font-weight: 800;
  color: var(--red);
  margin-bottom: 8px;
  line-height: 1.35;
}

.flag-line {
  font-size: 0.85rem;
  color: var(--text);
  line-height: 1.55;
}

.flag-line + .flag-line { margin-top: 6px; }

.flag-inline {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  border: 1px solid var(--border);
  border-left: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 13px;
  background: var(--panel);
}

.flag-inline + .flag-inline { margin-top: 8px; }

.flag-sev {
  flex-shrink: 0;
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  white-space: nowrap;
  padding: 3px 9px;
  border: 1px solid currentColor;
  border-radius: 20px;
  color: var(--muted);
  line-height: 1.4;
}

.flag-text {
  font-size: 0.82rem;
  color: var(--text);
  line-height: 1.55;
}

.flag-inline.flag-critical {
  border-left: 5px solid var(--red);
  border-color: var(--red);
  background: color-mix(in srgb, var(--red) 10%, var(--bg));
}
.flag-inline.flag-critical .flag-sev { color: var(--red); }

.flag-inline.flag-caution {
  border-left: 3px solid var(--amber);
  background: color-mix(in srgb, var(--amber) 9%, var(--bg));
}
.flag-inline.flag-caution .flag-sev { color: var(--amber); }

.flag-inline.flag-info { border-left: 1px solid var(--border); }
.flag-inline.flag-info .flag-sev { color: var(--muted); }

/* ══════════════════════════════════════════════════════════════════════════
   Battery study sections
   ══════════════════════════════════════════════════════════════════════════ */
/* The one figure the financial tab exists to state. */
.hero-figure {
  border-color: var(--accent);
  background: var(--accent-glow);
}

.hero-figure .l {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 6px;
}

.hero-figure .big {
  font-size: 2.2rem;
  font-weight: 800;
  color: var(--accent);
  line-height: 1.1;
}

/* What changes on the bill. */
.bill-lines {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}

.bill-lines td,
.bill-lines th {
  padding: 8px 0;
  text-align: left;
  font-weight: 400;
  color: var(--text);
  border-bottom: 1px solid var(--border);
}

.bill-lines td:last-child,
.bill-lines th:last-child {
  text-align: right;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.bill-lines .net th {
  border-bottom: none;
  border-top: 1px solid var(--border);
  padding-top: 11px;
  font-size: 0.95rem;
  font-weight: 800;
  color: var(--accent);
}

/* Chart cards inside a section title themselves with an h4 (financialSpine uses
   .chart-card-title instead, and is untouched by this). */
.chart-card h4 {
  font-size: 0.88rem;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 12px;
}

/* Dispatch: three days side by side, each drawn as three stacked strips. */
.day-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

.day-row .chart-card { margin-bottom: 0; }
.day-card h4 { margin-bottom: 2px; }

.day-date {
  font-size: 0.72rem;
  color: var(--muted);
  margin-bottom: 12px;
  font-variant-numeric: tabular-nums;
}

/* "See the day that earns it →" — a jump across the tab boundary, so it reads as
   a link rather than as another action on the figures above it. */
.crosslink {
  align-self: flex-start;
  width: fit-content;
  background: transparent;
  border: 1px dashed var(--border);
  border-radius: 8px;
  color: var(--accent2);
  font-size: 0.85rem;
  font-weight: 600;
  padding: 10px 16px;
  text-align: left;
  transition: border-color 0.15s, background 0.15s;
}

.crosslink:hover {
  border-color: var(--accent2);
  background: var(--panel);
}

.crosslink small {
  display: block;
  margin-top: 3px;
  font-size: 0.74rem;
  font-weight: 400;
  color: var(--muted);
}

/* ══════════════════════════════════════════════════════════════════════════
   Review page
   ══════════════════════════════════════════════════════════════════════════ */
.review-lede {
  font-size: 0.88rem;
  color: var(--muted);
  line-height: 1.6;
  max-width: 74ch;
}

.review-layout-panel,
.review-battery-panel { max-width: 760px; }

/* The connection-terms explainer sits between a heading and the next field, so it
   needs the bottom half of its spacing that .pnote (a trailing footnote elsewhere)
   never has. */
.review-battery-panel .pnote {
  margin-bottom: 16px;
  max-width: 72ch;
}

.review-cfg-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 16px;
}

.review-cfg-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px;
  text-align: left;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  transition: border-color 0.15s, box-shadow 0.15s;
}

.review-cfg-card:hover { border-color: var(--accent); }

.review-cfg-card.on {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent-glow);
  background: var(--accent-glow);
}

.review-cfg-label {
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--text);
}

.review-cfg-card.on .review-cfg-label { color: var(--accent); }

/* Boxed KPI tiles would sit on the same colour as the card they are in, so inside
   a config card they flatten to label/value rows. */
.review-cfg-card .kpis { grid-template-columns: 1fr; gap: 7px; }

.review-cfg-card .kpi {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 0;
  background: transparent;
  border: none;
}

.review-cfg-card .kpi .l { margin-bottom: 0; }
.review-cfg-card .kpi .v { font-size: 0.92rem; }

.review-field {
  display: block;
  margin-bottom: 14px;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--muted);
}

.review-field input {
  display: block;
  width: 100%;
  max-width: 260px;
  margin-top: 6px;
  padding: 9px 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  font-size: 0.9rem;
  transition: border-color 0.15s;
}

.review-field input:focus { outline: none; border-color: var(--accent2); }

.review-suggest {
  display: block;
  margin: -6px 0 4px;
  font-size: 0.78rem;
  color: var(--muted);
}

/* "optional" sits ON the label, quieter than the field name but not hidden — a user who
   does not know the number should be able to see that before they start guessing. */
.review-optional {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.3px;
  text-transform: uppercase;
  color: var(--muted);
  opacity: 0.75;
}

/* What a blank actually does, under the field it belongs to. */
.review-blank {
  display: block;
  max-width: 460px;
  margin: -8px 0 14px;
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--muted);
}

.review-subhead {
  margin: 22px 0 10px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--muted);
}

/* "A battery may earn little here" — a warning above inputs that still render,
   not a reason the study cannot run. */
.review-warning {
  color: var(--amber);
  font-style: normal;
  border-left: 3px solid var(--amber);
  padding-left: 11px;
  margin-bottom: 14px;
}

.review-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.review-actions .cta { width: auto; }

/* ══════════════════════════════════════════════════════════════════════════
   Responsive: study shell + review
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 900px) {
  .day-row { grid-template-columns: 1fr; }
}

@media (max-width: 720px) {
  .review-cfg-grid { grid-template-columns: 1fr; }
  .review-field input { max-width: none; }
}


/* --- sign-in gate -----------------------------------------------------------------
   Deliberately minimal: this exists so the app is usable, and is expected to be
   restyled with the rest of the interface. */
.authwrap { max-width: 26rem; margin: 4rem auto; display: flex; flex-direction: column; gap: 0.9rem; }
.authwrap h1 { margin: 0 0 0.4rem; font-size: 1.4rem; }
.authwrap label { display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.9rem; }
.authwrap input { padding: 0.55rem 0.7rem; font: inherit; }
.authwrap small { opacity: 0.7; font-size: 0.8rem; }
.authwrap button { padding: 0.6rem 1rem; font: inherit; cursor: pointer; }
.authwrap button[disabled] { opacity: 0.6; cursor: default; }
.authwrap ul { margin: 0; padding-left: 1.2rem; font-size: 0.9rem; }
.authswap { font-size: 0.85rem; opacity: 0.85; }
.autherr { color: #b3261e; font-size: 0.9rem; }
.authok  { color: #0b6e4f; font-size: 0.9rem; }
/* ── Spec §7: a stale study ──────────────────────────────────────────────────
   The result is shown, not hidden. Dimming says "this answers the earlier
   question" without taking the figure away — the user changed an input and
   would otherwise be left with a card emptier than before they touched it.
   Opacity only: no grey-out of the text colour, because these numbers still
   have to be readable. */
.is-stale { opacity: 0.55; transition: opacity 0.2s; }
.is-stale:hover { opacity: 0.8; }

/* The bar itself is NOT dimmed — it is the one thing on the page that is
   current, and the button in it is the way out. */
.stale-bar {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  background: rgba(255, 165, 2, 0.08);
  border: 1px solid var(--amber);
  border-radius: 10px;
  padding: 12px 16px;
  margin-bottom: 18px;
  font-size: 0.85rem;
  color: var(--text);
}
.stale-bar > div { flex: 1; min-width: 260px; }
.stale-bar .btn-primary { white-space: nowrap; }

/* The results card. The figure stays put; the amber edge and the second button
   are what change. */
.card.is-stale { border-color: var(--amber); opacity: 1; }
.card.is-stale .card-figure { opacity: 0.55; }

.card-rerun {
  display: block;
  width: 100%;
  margin-top: 8px;
  padding: 8px 10px;
  background: transparent;
  border: 1px solid var(--amber);
  border-radius: 8px;
  color: var(--amber);
  font-size: 0.78rem;
  font-weight: 600;
  transition: background 0.15s;
}
.card-rerun:hover { background: rgba(255, 165, 2, 0.12); }


/* ── The battery savings headline ─────────────────────────────────────────────────
   Its own class, because `.hero-figure` is the DASHBOARD carousel's and centring this
   panel's label over its figure in a 12px flex box is what made it read as an
   afterthought. The figure leads; the two facts that qualify it sit beside it rather
   than three scrolls further down, because "saved £X" and "after £Y of wear" are one
   sentence and separating them is how a number gets quoted without its basis. */
.bat-headline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px 32px;
  padding: 20px 24px;
}
.bat-headline .hf-main { flex: 1 1 240px; min-width: 0; }
.bat-headline .hf-main .l {
  font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.09em;
  color: var(--muted); font-weight: 700;
}
.bat-headline .hf-main .big {
  font-size: 2.4rem; font-weight: 800; line-height: 1.12; color: var(--text);
  margin-top: 4px; font-variant-numeric: tabular-nums;
}
.bat-headline .hf-side {
  flex: 0 1 auto;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 14px 26px;
  padding-left: 26px; border-left: 1px solid var(--border);
}
@media (max-width: 640px) {
  .bat-headline .hf-side { padding-left: 0; border-left: none; border-top: 1px solid var(--border); padding-top: 14px; width: 100%; }
}

/* The array drawing on the battery page's Layout section. Same painter and same
   one-to-one overlay as the solar page, so it inherits `.sat` rather than restating it;
   only the room it is given here is this page's business. */
#btMap { margin: 12px 0 4px; border-radius: 10px; overflow: hidden; }

/* ── Shading-scene verification (Stage 5) — the section under the boundary bar,
   the caster table, the per-kind completeness row, and the status chips that
   also appear on the results page. Same visual family as .bnd-bar: this is the
   next step of the same map, not a separate feature's island. */
.scene-section {
  padding: 12px 14px;
  background: var(--panel);
  border-top: 1px solid var(--border);
  border-radius: 0 0 11px 11px;
  font-size: 0.82rem; color: var(--muted);
}
.scene-section h3 { font-size: 0.9rem; color: var(--text); margin: 0 0 8px; }
.scene-section h3 .muted { font-weight: 400; font-size: 0.78rem; }
.scene-section .muted { color: var(--muted); }
.scene-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 10px 0 2px; }
.scene-section button {
  font-size: 0.78rem; font-weight: 600;
  padding: 5px 12px; border-radius: 7px;
  background: transparent; border: 1px solid var(--border); color: var(--muted);
  transition: border-color 0.15s, color 0.15s;
}
.scene-section button:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.scene-section button:disabled { opacity: 0.45; cursor: default; }
.scene-section button.primary { border-color: var(--accent); color: var(--accent); }
.scene-chip {
  display: inline-block; margin: 6px 0;
  padding: 6px 12px; border-radius: 20px;
  font-size: 0.78rem; font-weight: 600;
  border: 1px solid var(--border); color: var(--muted);
}
.scene-chip.verified { border-color: rgba(63, 157, 97, 0.6); color: #6fcf97; background: rgba(63, 157, 97, 0.08); }
.scene-chip.stale    { border-color: rgba(255, 165, 2, 0.5);  color: var(--amber); background: rgba(255, 165, 2, 0.06); }
.scene-chip.none     { border-color: var(--border); }
.ov-card .scene-chip { display: block; margin: 10px 14px 0; }
.scene-table { width: 100%; border-collapse: collapse; margin: 8px 0; font-size: 0.78rem; }
.scene-table th {
  text-align: left; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.06em; font-size: 0.68rem;
  padding: 4px 8px; border-bottom: 1px solid var(--border);
}
.scene-table td { padding: 5px 8px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.scene-table tr.sel td { background: rgba(0, 212, 170, 0.06); }
.scene-table .dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 6px; }
.scene-table .ok { color: #6fcf97; font-weight: 700; margin-right: 8px; }
.scene-table select, .scene-table input[type="number"] {
  background: transparent; color: var(--text);
  border: 1px solid var(--border); border-radius: 6px;
  padding: 3px 6px; font-size: 0.78rem;
}
.scene-table input[type="number"] { width: 64px; }
.scene-claims { margin: 12px 0 4px; }
.scene-claims b { display: block; color: var(--text); font-size: 0.8rem; margin-bottom: 6px; }
.scene-claim {
  display: inline-flex; align-items: center; gap: 6px;
  margin: 0 12px 8px 0; padding: 4px 10px;
  border: 1px solid var(--border); border-radius: 20px; font-size: 0.76rem;
}
.scene-claim.done { border-color: rgba(63, 157, 97, 0.6); color: #6fcf97; }
.scene-claim.todo { border-color: rgba(255, 165, 2, 0.5); color: var(--amber); }
.scene-claim select {
  background: transparent; color: inherit;
  border: none; font-size: 0.76rem; font-weight: 600;
}
.error-bar { background: rgba(255, 71, 87, 0.08); border: 1px solid rgba(255, 71, 87, 0.4); border-radius: 8px; margin-bottom: 8px; }

/* Scene table ↔ map linkage: rows are clickable and numbered to match the map badges. */
.scene-table tbody tr[data-id] { cursor: pointer; }
.scene-table tbody tr[data-id]:hover td { background: rgba(255, 255, 255, 0.03); }
.scene-table .scene-num { font-weight: 700; color: var(--text); width: 30px; }

/* The background-study progress banner — same family as .bnd-bar, amber accent. */
.study-progress { border-top-color: rgba(255, 165, 2, 0.4); color: var(--text); }

/* The build stamp — deliberately unobtrusive, deliberately always present. */
#buildStamp {
  position: fixed; right: 6px; bottom: 4px; z-index: 5;
  font-size: 0.62rem; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: 0.04em; color: var(--muted); opacity: 0.45;
  pointer-events: none; user-select: text;
}
