/* Frontend/css/app.css — VoltIQ 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;
}

: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;
}

/* ── 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; }

/* ── Topbar ── */
.topbar {
  height: 52px;
  background: var(--panel);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  padding: 0 24px;
  gap: 12px;
  position: sticky;
  top: 0;
  z-index: 100;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.logo {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: -0.3px;
  color: var(--text);
  text-decoration: none;
}

.logo .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;
}

.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);
}

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

/* ── Projects view ── */
.projects-wrap {
  max-width: 1100px;
  margin: 0 auto;
  padding: 32px 24px;
}

.projects-wrap h2 {
  font-size: 1.4rem;
  font-weight: 700;
  margin-bottom: 24px;
  color: var(--text);
}

.pcards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px;
}

/* Project card */
.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 */
.pcard.new {
  background: transparent;
  border: 2px dashed var(--border);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 148px;
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 500;
  transition: border-color 0.15s, color 0.15s, transform 0.15s;
}

.pcard.new:hover {
  border-color: var(--accent);
  color: var(--accent);
  transform: translateY(-3px);
  box-shadow: none;
}

.pcard.new .plus {
  font-size: 2rem;
  font-weight: 300;
  line-height: 1;
}

/* ── Mode strip ── */
.mode-strip {
  display: flex;
  flex-direction: row;
  gap: 12px;
  margin-bottom: 24px;
  flex-wrap: wrap;
}

.mode-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 16px;
  text-align: left;
  position: relative;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text);
  min-width: 160px;
  transition: border-color 0.15s, box-shadow 0.15s;
}

.mode-card.active {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent-glow), 0 0 8px var(--accent-glow);
}

.mode-card.active:hover {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-glow), 0 4px 16px var(--accent-glow);
}

.mode-card[data-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
}

.mode-go {
  display: block;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--accent);
  margin-top: 2px;
}

.mode-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.65rem;
  font-weight: 700;
  letter-spacing: 0.4px;
  padding: 2px 8px;
  margin-top: 4px;
  width: fit-content;
}

/* ── Utility ── */
.hidden { display: none; }

/* ── 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 */
.wizard-fields label {
  display: block;
  margin-bottom: 16px;
  font-size: 0.85rem;
  color: var(--muted);
  font-weight: 500;
}

.wizard-fields label input,
.wizard-fields label select,
.wizard-fields label textarea {
  display: block;
  width: 100%;
  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;
}

.wizard-fields label input:focus,
.wizard-fields label select:focus,
.wizard-fields label textarea:focus {
  outline: none;
  border-color: var(--accent2);
}

.wizard-fields textarea {
  min-height: 80px;
  resize: vertical;
}

/* Monthly demand entry — 12 small labelled inputs (energy step) */
.monthly-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px 10px;
  margin-bottom: 16px;
}
.monthly-grid label { margin-bottom: 0; }
/* Declared AFTER .monthly-grid so the toggle's .hidden still wins (see .modal-backdrop note) */
.monthly-grid.hidden { display: none; }

/* Tooltip hint */
.tip {
  color: var(--accent2);
  cursor: help;
  font-size: 0.85rem;
}

/* 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 */
.hero {
  display: grid;
  grid-template-columns: 220px 1fr;
  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 {
  min-height: 140px;
  align-self: start;
  background: linear-gradient(160deg, var(--accent-glow) 0%, rgba(59, 163, 255, 0.10) 100%);
  position: relative;
  overflow: hidden;
}

.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: 20px 20px 20px;
  border-left: 1px solid var(--border);
}

/* 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;
}

.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;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

/* 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);
}

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

.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; }
.bnd-bar { display: flex; align-items: center; gap: .6rem; padding: .45rem .7rem;
  font-size: .85rem; border-radius: 0 0 8px 8px; background: rgba(0,0,0,.25); }
.bnd-bar button { font-size: .8rem; padding: .25rem .6rem; cursor: pointer; }
.ghost-bar { background: rgba(255,211,77,.15); }
.bnd-error { background: rgba(255,80,80,.15); }
.bnd-stale { opacity: .8; }
.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;
  /* BELOW the app topbar, which is itself sticky at top:0 and 52px tall. Pinning the
     strip at 0 would cover the product's own navigation while a study is being read,
     and the z-index needed to do it would have to beat the topbar's 100. The scroll
     offset in studyShell.scrollToSection is STRIP_OFFSET_PX and must equal 52 plus
     this strip's own height, or a section heading lands underneath it. */
  top: 52px;
  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);
  width: 100vw;
  margin-left: calc(50% - 50vw);
  /* Aligns the buttons with the .sl content column (max-width 1200, padding 24). */
  padding: 15px max(24px, calc(50vw - 576px));
}

.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: 110px; /* 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); }
