/* ============================================================================
   Store Energy — Deal Calculator restyle
   Drop-in stylesheet. Restyles the EXISTING markup in src/web/*.html and adds
   a small set of new component classes for the new patterns.

   Nothing here changes behavior. No JS, no ids, no name attributes, no form
   wiring. Apply classes, delete the old inline <style> blocks, keep your
   handlers exactly as they are.

   Theme: dark is the default (:root), light is the [data-theme="light"]
   override — the same contract the app already uses. Every color routes
   through a variable; there are no raw hex values below the token blocks.
   ========================================================================== */

/* --- Optional. Only needed if the team adopts Archivo. ------------------- */
@import url("https://fonts.googleapis.com/css2?family=Archivo:wght@400;500;600;700;800&display=swap");

/* ============================================================================
   1. TOKENS — DARK (default)
   ========================================================================== */
:root {
  /* ---- Existing app tokens (unchanged names, so your current CSS keeps
          resolving). Two have new VALUES — see the note on --accent below. -- */
  --bg:            #0f172a;
  --panel:         #1e293b;
  --line:          #334155;
  --text:          #e2e8f0;
  --dim:           #94a3b8;
  --input:         #0b1220;
  --shadow:        0 1px 3px rgba(0, 0, 0, .4);

  /* ---- Accent. IMPORTANT: --accent is now the FILL color in both themes
          (the brand green), and --accent-text is the text-safe step. Your
          light theme previously overloaded --accent for both, which is why
          links and buttons had to share one value. Splitting them is what
          lets the brand green appear as a fill on light backgrounds while
          text still clears 4.5:1. ------------------------------------------ */
  --accent:        #3ebe91;   /* fills, 2px emphasis borders */
  --accent-ink:    #06281c;   /* text/icons placed ON --accent */
  --accent-hover:  #56cea3;   /* fill hover */
  --accent-text:   #5fd3a9;   /* accent at body/label text sizes */
  --accent-tint:   #0f2a22;   /* expanded panels, group washes */
  --accent-tint-2: #16362b;   /* one step up: chips, hover on tinted rows */
  --accent-border: #2a6e57;   /* borders on tinted surfaces */

  /* ---- Status ---- */
  --good:          #4ade80;
  --bad:           #f87171;
  --warn:          #facc15;
  --danger:        #f87171;   /* the "deal is short" band, Disable actions */
  --danger-strong: #fca5a5;   /* headline weight of the same message */
  --danger-tint:   #2a1517;
  --danger-border: #7f2d2d;

  /* ---- Surfaces & rules ---- */
  --surface-2:     #172033;   /* recessed blocks: margin block, action bars */
  --emphasis-row:  #24324a;   /* the one highlighted row (Gross Margin) */
  --rule:          #cbd5e1;   /* the strong 2px structural rule */
  --rule-w:        2px;
  --hairline:      var(--line);

  /* ---- Geometry. Set --radius to 6px to keep the app's current softness;
          0 is the Modernist direction shown in the mocks. ----------------- */
  --radius:        0px;
  --radius-sm:     0px;

  /* ---- Type ---- */
  --font:          "Archivo", system-ui, -apple-system, sans-serif;
  --font-mono-num: tabular-nums;

  /* ---- Spacing ---- */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-8: 32px;
}

/* ============================================================================
   2. TOKENS — LIGHT
   ========================================================================== */
:root[data-theme="light"] {
  --bg:            #f2f5f7;
  --panel:         #ffffff;
  --line:          #d8dfe6;
  --text:          #182230;
  --dim:           #5b6672;
  --input:         #ffffff;
  --shadow:        0 1px 3px rgba(16, 24, 40, .08);

  --accent:        #3ebe91;
  --accent-ink:    #0d3527;
  --accent-hover:  #2f9c76;
  --accent-text:   #127a58;
  --accent-tint:   #edf9f4;
  --accent-tint-2: #d3efe4;
  --accent-border: #a4e0c8;

  --good:          #15803d;
  --bad:           #dc2626;
  --warn:          #a16207;
  --danger:        #9e3526;
  --danger-strong: #71261b;
  --danger-tint:   #fff2ef;
  --danger-border: #ffc4b9;

  --surface-2:     #eaeef1;
  --emphasis-row:  #f2f5f7;
  --rule:          #182230;
}

/* ============================================================================
   3. BASE — restyles existing element selectors
   ========================================================================== */
* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 500 13px/1.45 var(--font);
  text-wrap: pretty;
}

a { color: var(--accent-text); text-decoration: none; }
a:hover { color: var(--accent); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

::selection { background: var(--accent-tint-2); }

/* ---- Header bar (existing <header>) ---- */
header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: 14px var(--sp-6);
  background: var(--panel);
  border-bottom: var(--rule-w) solid var(--rule);
}
header h1 {
  margin: 0;
  font: 800 17px/1 var(--font);
  letter-spacing: -.02em;
}
header .sub { margin-top: var(--sp-1); font: 500 11.5px/1.4 var(--font); color: var(--dim); }
.brand { display: flex; align-items: center; gap: var(--sp-4); }
.brand .logo { height: 30px; width: auto; display: block; }
/* The 2px keyline between logo and wordmark. */
.brand-rule { width: 2px; height: 32px; background: var(--rule); flex: none; }
.header-actions { display: flex; align-items: center; gap: 14px; position: relative; }

/* ---- Main grid (existing <main>) ---- */
main {
  display: grid;
  grid-template-columns: 420px 1fr;
  align-items: start;
  gap: 0;
  max-width: 1400px;
  margin: 0 auto;
}
.col-inputs { border-right: var(--rule-w) solid var(--rule); }
@media (max-width: 900px) {
  main { grid-template-columns: 1fr; }
  .col-inputs { border-right: 0; border-bottom: var(--rule-w) solid var(--rule); }
}

/* ---- Cards (existing .card) ---- */
.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--sp-4);
}
.card h2,
.section-label {
  margin: 0 0 10px;
  font: 700 11px var(--font);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text);
}
/* A section header that spans the column, with an optional right-side note. */
.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: 13px var(--sp-5);
  border-bottom: var(--rule-w) solid var(--rule);
}
.section-head .note { font: 500 10.5px var(--font); color: var(--dim); }

/* ============================================================================
   4. FORMS — existing .field / fieldset / legend markup
   ========================================================================== */
.field { display: block; margin-bottom: var(--sp-3); }
.field:last-child { margin-bottom: 0; }

.field label,
label.field-label {
  display: block;
  margin-bottom: 5px;
  font: 600 10px var(--font);
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--dim);
}
/* Lowercase qualifier inside an uppercase label, e.g. "— set by installer" */
.field label .qualifier {
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  opacity: .8;
}

.field input,
.field select,
.input {
  width: 100%;
  height: 36px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--input);
  color: var(--text);
  font: 500 13px var(--font);
}
.field select { padding: 0 8px; }
.field input:hover,
.field select:hover { border-color: var(--accent-border); }
.field input::placeholder { color: var(--dim); }

/* The one emphasised money input (Loan Amount). */
.input-emphasis {
  height: 42px;
  border: var(--rule-w) solid var(--accent);
  font: 700 17px var(--font);
}

/* Read-only, server-derived value shown in a field slot (Lender). */
.input-readonly {
  display: flex;
  align-items: center;
  height: 36px;
  padding: 0 10px;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  background: var(--surface-2);
  font: 600 13px var(--font);
  color: var(--text);
}

.cols2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
.cols2 > .span2 { grid-column: span 2; }

/* Checkboxes / radios */
.check {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-bottom: 7px;
  font: 500 12.5px var(--font);
  color: var(--text);
}
.check:last-child { margin-bottom: 0; }
.check input { accent-color: var(--accent-text); width: 15px; height: 15px; }

/* Explanatory note under a group — replaces guesswork with a stated rule. */
.field-note {
  margin-top: 10px;
  padding-left: 9px;
  border-left: 2px solid var(--accent-border);
  font: 500 11px/1.5 var(--font);
  color: var(--dim);
}

/* ---- Collapsible input group. Native <details>; OPEN BY DEFAULT. --------- */
.group {
  border-bottom: 1px solid var(--hairline);
}
.group > summary {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 14px var(--sp-5);
  cursor: pointer;
  list-style: none;
}
.group > summary::-webkit-details-marker { display: none; }
.group > summary:hover { background: var(--accent-tint); }
.group-title {
  font: 700 10px var(--font);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent-text);
}
.chev {
  display: inline-block;
  font-size: 9px;
  line-height: 1;
  color: var(--accent-text);
  transition: transform .15s ease;
}
details[open] > summary .chev { transform: rotate(90deg); }
.group-body { padding: 0 var(--sp-5) var(--sp-4); }
.group-tinted { background: var(--accent-tint); }

/* An ungrouped block of fields (the customer/deal block, the loan-amount block) */
.block {
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--hairline);
}

/* Existing fieldset/legend, kept for the dim-on-inapplicable behavior */
fieldset {
  margin: 0 0 var(--sp-3);
  padding: 10px var(--sp-3) var(--sp-1);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
fieldset legend {
  padding: 0 5px;
  font: 700 10px var(--font);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent-text);
}
fieldset.off { opacity: .35; pointer-events: none; }

/* ============================================================================
   5. BUTTONS — existing button / button.ghost
   ========================================================================== */
button,
.btn {
  border: 0;
  border-radius: var(--radius);
  padding: 9px 14px;
  background: var(--accent);
  color: var(--accent-ink);
  font: 600 12px var(--font);
  /* Modernist: labels are flush left, never centered, even in wide buttons. */
  text-align: left;
  cursor: pointer;
}
button:hover, .btn:hover { background: var(--accent-hover); }
button:disabled { opacity: .45; cursor: default; }

button.ghost, .btn-ghost {
  background: transparent;
  color: var(--text);
  border: var(--rule-w) solid var(--rule);
  padding: 7px 12px;
}
button.ghost:hover, .btn-ghost:hover { background: var(--accent-tint-2); }

button.danger, .btn-danger {
  background: transparent;
  color: var(--danger);
  border: 1px solid var(--danger-border);
}
button.danger:hover, .btn-danger:hover { background: var(--danger-tint); }

.btn-sm { padding: 6px 10px; font-size: 11px; }
.btn-row { display: flex; gap: var(--sp-2); }
.btn-row > * { flex: 1; }

/* Bottom action bar of the inputs column */
.action-bar {
  display: flex;
  gap: 10px;
  padding: var(--sp-4) var(--sp-5);
  background: var(--surface-2);
  border-top: var(--rule-w) solid var(--rule);
}

/* ============================================================================
   6. PILLS, CHIPS, BADGES — existing .pill
   ========================================================================== */
.pill {
  padding: 4px var(--sp-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font: 600 10px var(--font);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dim);
}
.pill.off { color: var(--danger); border-color: var(--danger-border); }
.pill-accent {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}
.pill-danger {
  color: var(--danger);
  border-color: var(--danger-border);
  background: var(--danger-tint);
}

/* Capability badge, e.g. "financials:view · Owner" */
.badge-cap {
  padding: 4px var(--sp-2);
  border-radius: var(--radius);
  background: var(--accent);
  color: var(--accent-ink);
  font: 600 9.5px var(--font);
  letter-spacing: .08em;
  text-transform: uppercase;
}

/* Input-provenance chips inside an expanded output row */
.chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-3); }
.chip {
  padding: 4px var(--sp-2);
  border: 1px solid var(--accent-border);
  border-radius: var(--radius);
  font: 600 10px var(--font);
  color: var(--accent-text);
}

/* Yes/No state cell */
.flag { padding: 3px var(--sp-2); border: 1px solid var(--line); border-radius: var(--radius);
        font: 600 11px var(--font); color: var(--dim); }
.flag-on { background: var(--accent-text); border-color: var(--accent-text); color: var(--panel); }

/* ============================================================================
   7. STATUS BAND — replaces the engine's emoji marginStatus
   ========================================================================== */
.status-band {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-6);
  border-bottom: var(--rule-w) solid var(--rule);
}
.status-band .lead { display: flex; align-items: center; gap: 10px; }
.status-band .dot { width: 9px; height: 9px; display: block; flex: none; }
.status-band .msg { font: 700 12px var(--font); }
.status-band .sub { font: 500 12px var(--font); }
.status-band .meta { font: 500 10.5px var(--font); color: var(--dim); }

.status-ok { background: var(--accent-tint); }
.status-ok .dot { background: var(--accent-text); }
.status-ok .msg { color: var(--accent-text); }
.status-ok .sub { color: var(--accent-text); }

.status-short { background: var(--danger-tint); }
.status-short .dot { background: var(--danger); }
.status-short .msg { color: var(--danger-strong); }
.status-short .sub { color: var(--danger); }

/* ============================================================================
   8. KPI STRIP — Contract Total / Monthly Payment / Commission
   ========================================================================== */
.kpi-strip {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-bottom: var(--rule-w) solid var(--rule);
}
.kpi { padding: 18px var(--sp-6); border-right: 1px solid var(--hairline); }
.kpi:last-child { border-right: 0; }
.kpi .k-label {
  font: 600 10px var(--font);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--dim);
}
.kpi .k-value {
  margin-top: var(--sp-2);
  font: 800 38px/1 var(--font);
  letter-spacing: -.03em;
  font-variant-numeric: var(--font-mono-num);
}
.kpi .k-sub { margin-top: 6px; font: 500 11px var(--font); color: var(--dim); }

/* Commission is the one filled tile — it stays visible to every role. */
.kpi-accent { background: var(--accent); border-right: 0; }
.kpi-accent .k-label,
.kpi-accent .k-value,
.kpi-accent .k-sub { color: var(--accent-ink); }

/* ============================================================================
   9. OUTPUTS LEDGER — replaces table.out
   Rows are flex, not table cells, so an expandable row can carry a panel.
   table.out is also restyled below so the existing markup still looks right.
   ========================================================================== */
.ledger { display: block; }

.out-row,
.out-row > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: 11px var(--sp-6) 11px 44px;   /* 44px aligns with expandable rows */
  border-bottom: 1px solid var(--hairline);
}
.out-row > summary {
  padding-left: var(--sp-6);
  border-bottom: 0;
  cursor: pointer;
  list-style: none;
}
.out-row > summary::-webkit-details-marker { display: none; }
details.out-row { border-bottom: 1px solid var(--hairline); padding: 0; }
details.out-row > summary:hover { background: var(--accent-tint); }
.out-label { display: flex; align-items: center; gap: var(--sp-2);
             font: 600 13px var(--font); color: var(--text); }
.out-value { font: 700 14px var(--font); font-variant-numeric: var(--font-mono-num); }

/* The derivation panel */
.out-detail {
  padding: 14px var(--sp-6) var(--sp-4) 44px;
  background: var(--accent-tint);
  border-top: 1px solid var(--accent-border);
}
.out-detail .kicker {
  margin-bottom: var(--sp-2);
  font: 600 10px var(--font);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--accent-text);
}
.out-detail .math { font: 500 12.5px/1.7 var(--font); color: var(--text); }
.out-detail .math b { font-weight: 700; }
/* A derived figure surfaced inside a detail panel rather than as its own
   ledger row (e.g. Artemis Discount % under Artemis Discount). */
.out-detail .detail-figure {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-top: var(--sp-3);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--accent-border);
  font: 600 12.5px var(--font);
  color: var(--text);
}
.out-detail .detail-figure > span:last-child {
  font: 700 14px var(--font);
  font-variant-numeric: var(--font-mono-num);
}

.out-detail .footnote {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  font: 500 11.5px/1.6 var(--font);
  color: var(--dim);
}

/* Commission is the one inverted row. */
.out-row-accent > summary { background: var(--text); }
.out-row-accent > summary:hover { background: var(--text); filter: brightness(1.25); }
.out-row-accent > summary .out-label { color: var(--panel); }
.out-row-accent > summary .out-value { font: 800 18px var(--font); color: var(--accent); }
.out-row-accent > summary .chev { color: var(--accent); }
.out-row-accent .out-detail { background: var(--text); border-top-color: transparent; }
.out-row-accent .out-detail .math { color: var(--panel); }
.out-row-accent .out-detail .footnote { color: var(--dim); }

/* Floor bar — loan vs Min. Loan Amount */
.floor-bar { position: relative; height: 8px; margin-top: var(--sp-3); background: var(--accent-tint-2); }
.floor-bar .fill { position: absolute; inset: 0 auto 0 0; background: var(--accent); }
.floor-bar .marker { position: absolute; top: -4px; bottom: -4px; width: 2px; background: var(--rule); }
.floor-caption {
  display: flex; justify-content: space-between; margin-top: 6px;
  font: 600 10px var(--font); color: var(--dim);
}

/* Existing table.out, restyled so untouched screens stay coherent */
table.out { width: 100%; border-collapse: collapse; }
table.out td { padding: 10px var(--sp-2); border-bottom: 1px solid var(--hairline); font: 500 12.5px var(--font); }
table.out td:last-child {
  text-align: right; font-weight: 600;
  font-variant-numeric: var(--font-mono-num);
}
table.out tr.big td { font-size: 15px; font-weight: 800; color: var(--text); }

/* ============================================================================
   10. RECESSED BLOCKS — PWP rebate + margin block
   ========================================================================== */
.block-dashed { border-top: var(--rule-w) dashed var(--line); border-bottom: var(--rule-w) dashed var(--line); }
.block-dashed .section-head { border-bottom: 0; background: var(--surface-2); }

.margin-block { background: var(--surface-2); }
.margin-block .section-head { border-bottom: 1px solid var(--line); }
.m-row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
  padding: 10px var(--sp-6);
  border-bottom: 1px solid var(--hairline);
  font: 500 12.5px var(--font);
  color: var(--text);
}
.m-row .m-value { font-weight: 600; font-size: 13px; font-variant-numeric: var(--font-mono-num); }
.m-row.sub { padding-left: 40px; color: var(--dim); }
.m-row.sub .m-value { font-weight: 500; color: var(--dim); }
.m-row .qualifier { color: var(--dim); font-weight: 500; }
.m-row.emphasis { background: var(--emphasis-row); padding-top: var(--sp-3); padding-bottom: var(--sp-3); }
.m-row.emphasis span:first-child { font-weight: 700; }
.m-row.emphasis .m-value { font-weight: 800; font-size: 15px; }
.m-row .neg { color: var(--danger); }

/* Rows the server strips for non-Owners — documentation state only. */
.m-row.absent { color: var(--line); }
.m-row.absent .m-value { color: var(--line); font-weight: 500; }

/* ============================================================================
   11. DATA TABLES — config editor, users
   ========================================================================== */
.dtable { display: block; }
.dtable .dt-head,
.dtable .dt-row { display: grid; gap: var(--sp-3); align-items: center; padding: 11px var(--sp-6); }
.dtable .dt-head {
  padding-top: 9px; padding-bottom: 9px;
  border-top: var(--rule-w) solid var(--rule);
  border-bottom: var(--rule-w) solid var(--rule);
  font: 700 10px var(--font); letter-spacing: .1em; text-transform: uppercase; color: var(--dim);
}
.dtable .dt-row { border-bottom: 1px solid var(--hairline); font: 500 12.5px var(--font); }
.dtable .dt-row.edited { background: var(--accent-tint); }
.dtable .dt-row.retired { color: var(--dim); }
.dtable .dt-row .was { color: var(--dim); text-decoration: line-through; }
.dtable .dt-row .num { font-variant-numeric: var(--font-mono-num); }
.dtable .dt-row input { height: 30px; padding: 0 var(--sp-2); width: 100%;
  border: var(--rule-w) solid var(--accent); border-radius: var(--radius);
  background: var(--input); color: var(--text); font: 600 12.5px var(--font); }
.dt-actions { display: flex; gap: 7px; justify-self: end; }

/* Existing plain <table> in users.html */
table.grid { width: 100%; border-collapse: collapse; }
table.grid th, table.grid td { padding: 11px var(--sp-2); text-align: left; border-bottom: 1px solid var(--hairline); }
table.grid th { font: 700 10px var(--font); letter-spacing: .1em; text-transform: uppercase; color: var(--dim); }
table.grid td { font: 500 12.5px var(--font); }
table.grid tr.disabled td { color: var(--dim); }

/* Role chips */
.role { padding: 3px var(--sp-2); border-radius: var(--radius); font: 700 11px var(--font); }
.role-owner { background: var(--accent); color: var(--accent-ink); }
.role-admin { border: 1px solid var(--rule); color: var(--text); }
.role-rep   { border: 1px solid var(--line); color: var(--dim); }

/* Config-editor sidebar */
.side { border-right: var(--rule-w) solid var(--rule); padding: var(--sp-4) 0; }
.side-group { padding: 0 var(--sp-5) 10px; font: 700 10px var(--font);
  letter-spacing: .14em; text-transform: uppercase; color: var(--dim); }
.side-group + .side-item { margin-top: 0; }
.side-group:not(:first-child) { padding-top: 18px; }
.side-item {
  padding: 9px 18px;
  border-left: 4px solid transparent;
  font: 500 12.5px var(--font);
  color: var(--text);
  cursor: pointer;
}
.side-item:hover { background: var(--accent-tint); }
.side-item[aria-current="true"] {
  border-left-color: var(--accent);
  background: var(--surface-2);
  font-weight: 700;
}
.side-item .count { float: right; font: 600 10px var(--font); color: var(--accent-text); }

/* Draft-vs-live preview grid */
.diff {
  display: grid;
  grid-template-columns: 1.3fr 1fr 1fr 1fr;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}
.diff > * { background: var(--panel); padding: 9px var(--sp-3); font: 500 12px var(--font); }
.diff > .h { background: var(--surface-2); font: 700 10px var(--font);
  letter-spacing: .08em; text-transform: uppercase; color: var(--dim); }
.diff > .v { font-weight: 600; font-variant-numeric: var(--font-mono-num); }
.diff > .d { font-weight: 600; color: var(--danger); font-variant-numeric: var(--font-mono-num); }

/* Blocking notice (rebase, validation) */
.notice {
  display: flex; gap: var(--sp-3); align-items: flex-start;
  padding: var(--sp-3) 14px; margin-top: 14px;
  border: var(--rule-w) solid var(--rule);
}
.notice .tag {
  flex: none; padding: 4px var(--sp-2);
  background: var(--danger); color: var(--panel);
  font: 700 10px var(--font); letter-spacing: .08em; text-transform: uppercase;
}
.notice .body { font: 500 12px/1.6 var(--font); color: var(--text); }

/* ============================================================================
   12. SETTINGS POPOVER
   ========================================================================== */
.popover {
  position: absolute;
  right: 0;
  top: 44px;
  z-index: 20;
  width: 280px;
  padding: var(--sp-4) 18px 18px;
  background: var(--panel);
  border: var(--rule-w) solid var(--rule);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.popover .pop-title {
  margin-bottom: 14px;
  font: 700 10px var(--font); letter-spacing: .14em; text-transform: uppercase;
}
.popover .pop-section { border-top: 1px solid var(--line); padding-top: 14px; margin-top: 18px; }
.popover .pop-label {
  margin-bottom: 7px;
  font: 600 10px var(--font); letter-spacing: .07em; text-transform: uppercase; color: var(--dim);
}
.popover .stack { display: grid; gap: 9px; }
.popover input { height: 34px; }

/* ============================================================================
   13. PRINT — customer proposal (src/server/pdf.ts)
   The proposal is always LIGHT, regardless of the app theme.
   ========================================================================== */
.proposal {
  width: 816px;                 /* US Letter at 96dpi */
  margin: 0 auto;
  background: #fff;
  color: #182230;
  font: 500 13px/1.5 var(--font);
}
.proposal .p-head {
  display: flex; align-items: flex-end; justify-content: space-between; gap: var(--sp-8);
  padding: 52px 60px 36px;
  border-bottom: var(--rule-w) solid #182230;
}
.proposal .p-logo { height: 38px; width: auto; display: block; }
.proposal h1 {
  margin: var(--sp-4) 0 0;
  max-width: 9ch;
  font: 800 40px/1.02 var(--font);
  letter-spacing: -.03em;
}
.proposal .p-meta { font: 500 11.5px/1.7 var(--font); color: #5b6672; }
.proposal .p-body { padding: 34px 60px 0; }
.proposal .p-hero { display: grid; grid-template-columns: 1fr 1fr; border-bottom: 1px solid #d8dfe6; }
.proposal .p-hero > div:first-child { padding-right: var(--sp-6); border-right: 1px solid #d8dfe6; }
.proposal .p-hero > div:last-child { padding-left: var(--sp-6); }
.proposal .p-hero > div { padding-bottom: 26px; }
.proposal .p-kicker {
  font: 600 10px var(--font); letter-spacing: .14em; text-transform: uppercase; color: #5b6672;
}
.proposal .p-figure { margin-top: 10px; font: 800 52px/1 var(--font); letter-spacing: -.04em; }
.proposal .p-figure.accent { color: #127a58; }
.proposal .p-sub { margin-top: 10px; font: 500 12px var(--font); color: #5b6672; }
.proposal .p-section { padding: 26px 0; border-bottom: 1px solid #d8dfe6; }
.proposal .p-section h2 {
  margin: 0 0 18px;
  font: 700 11px var(--font); letter-spacing: .14em; text-transform: uppercase;
}
.proposal .p-specs { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-5); }
.proposal .p-specs .n { font: 800 26px var(--font); }
.proposal .p-specs .n small { font-size: 13px; color: #5b6672; font-weight: 500; }
.proposal .p-specs .c { margin-top: var(--sp-1); font: 500 11px var(--font); color: #5b6672; }
.proposal .p-two { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-8); }
.proposal .p-list { display: grid; gap: 9px; font: 500 12.5px/1.5 var(--font); }
.proposal .p-list > div { border-left: 2px solid #3ebe91; padding-left: 10px; }
.proposal .p-rebate { border: var(--rule-w) dashed #b6c0c9; padding: 18px; }
.proposal .p-rebate .r-row { display: flex; justify-content: space-between; }
.proposal .p-rebate .r-total { border-top: 1px solid #d8dfe6; padding-top: 7px; font-weight: 700; }
.proposal .p-rebate .r-total b { color: #127a58; font-weight: 800; }
.proposal .p-legal { padding: 20px 0 40px; font: 500 10.5px/1.6 var(--font); color: #8b949d; }

@media print {
  @page { size: letter; margin: 0; }
  .proposal { width: auto; }
}

/* ============================================================================
   14. UTILITIES
   ========================================================================== */
.err { min-height: 16px; margin-top: 6px; font: 500 12px var(--font); color: var(--bad); }
.ok  { font: 500 12px var(--font); color: var(--good); }
.muted { color: var(--dim); }
.num { font-variant-numeric: var(--font-mono-num); }
.stack-2 { display: grid; gap: var(--sp-2); }
.row-2 { display: flex; gap: var(--sp-2); align-items: center; }
.hr { height: 0; border: 0; border-top: var(--rule-w) solid var(--rule); margin: 0; }

/* ============================================================================
   15. APP INTEGRATION — additions for the live app (no raw hex; everything
   routes through the token blocks above).
   ========================================================================== */
/* Theme-driven logo swap (was in the old inline style block). */
.logo { height: 30px; width: auto; display: block; }
[data-theme="light"] .logo-on-dark { display: none; }
:root:not([data-theme="light"]) .logo-on-light { display: none; }

/* The input groups are <details class="group"> now; keep the existing
   dim-when-inapplicable behavior that applyVisibility() toggles. */
.group.off, .block.off { opacity: .35; pointer-events: none; }

/* Lender is derived from the installer, not chosen. The element stays a
   <select> (the JS contract), presented as the read-only box from the mocks. */
select#lender {
  pointer-events: none;
  border-style: dashed;
  background: var(--surface-2);
  font-weight: 600;
  appearance: none;
}

/* Login card (was styled by the old inline block). */
#login { max-width: 360px; margin: 12vh auto; padding: var(--sp-6); }
#login .logo { margin: 0 auto var(--sp-3); }

/* Saved profiles list. */
#profiles li { display: flex; justify-content: space-between; gap: var(--sp-2);
  padding: 8px 0; border-bottom: 1px solid var(--hairline); list-style: none; }
#profiles ul { padding: 0; margin: 0; }
#profiles a { cursor: pointer; }

/* Outputs two-up grid (ledger | rebate + margin). */
.out-grid { display: grid; grid-template-columns: 1fr 1fr; }
.out-grid > div:first-child { border-right: 1px solid var(--line); }
@media (max-width: 1100px) {
  .out-grid { grid-template-columns: 1fr; }
  .out-grid > div:first-child { border-right: 0; }
}
.m-value.accent { color: var(--accent-text); }

/* THE `hidden` GUARD — root cause of the deployed regressions. In real
   browsers the HTML `hidden` attribute is only a UA-stylesheet display:none
   hint; author rules like `.field { display: block }` and
   `.status-band { display: flex }` above override it, which made BOTH status
   bands and BOTH lender field sets render at once. `hidden` must always win. */
[hidden] { display: none !important; }

/* ============================================================================
   16. SPLIT SCROLL — calculator only (body.split-scroll).
   Desktop: fixed header; the inputs and outputs columns are INDEPENDENT
   scroll panes filling the remaining viewport. A short outputs list stays
   put; once it overflows, it scrolls on its own — never tied to the inputs.
   Mobile (≤900px): normal page scroll, stacked with OUTPUTS FIRST.
   ========================================================================== */
.split-scroll #app {
  height: 100vh;
  height: 100dvh;             /* mobile browser chrome-aware */
  display: flex;
  flex-direction: column;
}
.split-scroll #app > header { flex: none; }        /* header never scrolls */
.split-scroll #app > main {
  flex: 1 1 0;
  min-height: 0;              /* allow children to shrink below content size */
  width: 100%;
  align-items: stretch;       /* panes fill the row (theme default is start) */
}
@media (min-width: 901px) {
  .split-scroll .col-inputs,
  .split-scroll .col-outputs {
    height: 100%;
    min-height: 0;
    overflow-y: auto;         /* each pane manages its own overflow */
    overscroll-behavior: contain;
  }
  /* Keep Save/actions reachable + visible while the inputs pane scrolls. */
  .split-scroll .action-bar { position: sticky; bottom: 0; }
}
@media (max-width: 900px) {
  .split-scroll #app { height: auto; display: block; }  /* one page scroll */
  .split-scroll #app > main { display: grid; }
  .split-scroll .col-outputs { order: 1; }              /* key numbers first */
  .split-scroll .col-inputs  { order: 2; }
}

/* ---- Draggable split divider (desktop calculator only) --------------------
   main carries --inputs-w (px while dragging, % when restored); the divider
   is a 6px hit area with a token-colored bar. Inputs reflow into more
   columns as the pane widens (auto-fit). Mobile: no divider, stack unchanged. */
@media (min-width: 901px) {
  .split-scroll #app > main {
    grid-template-columns: var(--inputs-w, 420px) 6px 1fr;
  }
  .split-divider {
    cursor: col-resize;
    height: 100%;
    background: linear-gradient(to right, transparent 2px, var(--rule) 2px, var(--rule) 4px, transparent 4px);
    touch-action: none;
    user-select: none;
  }
  .split-divider:hover, .split-divider.dragging {
    background: linear-gradient(to right, transparent 1px, var(--accent) 1px, var(--accent) 5px, transparent 5px);
  }
  /* CONTENT-WIDTH FLOW, width-responsive. The inputs pane is a container;
     flex line-breaking uses each field's BASIS, so the bases are the packing
     knobs. Two regimes:
       pane < 640px (the 420px default): today's ~2-up look — wide/money
         fields take a full row, meds pair up.
       pane ≥ 640px (dragged wide): DENSE bases, tuned so the two owner-named
         target rows fit — Battery Type + Qty + Expansion + Back-up + MSP
         5-up (195+70+70+145+145+4 gaps = 673px), and Loan Amount + Min % +
         Baseline % + Cash Contribution 4-up (190+70+70+145+3 gaps = 511px) —
         at a ~50% pane on a normal desktop (inner ≥ ~680px).
     flex-grow fills every row edge-to-edge, so stranded fields/dead tracks
     are impossible; hidden fields drop out of the flow. */
  .split-scroll .col-inputs { container-type: inline-size; }
  .split-scroll .col-inputs .cols2 {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-3);
    /* TIGHTER ROWS (25% off the ORIGINAL 12px — replaces the earlier 5%):
       vertical row-to-row gap only; the horizontal column-gap stays
       var(--sp-3), so the packing math is untouched. */
    row-gap: 9px;
    /* UNIFORM ROWS: bottom-align every field so the input boxes share one
       baseline even when neighbouring labels wrap to different line counts. */
    align-items: flex-end;
  }
  /* Standalone rows (Customer Name, Custom Adders) get the same tightening;
     fields inside .cols2 keep margin-bottom: 0 (higher-specificity rule below)
     and last-in-block stays flush, as before. */
  .split-scroll .col-inputs .field { margin-bottom: 9px; }
  .split-scroll .col-inputs .field:last-child { margin-bottom: 0; }
  /* Reserve a two-line label block, text anchored to its bottom: short labels
     get air above, wrapping labels fill it — nothing drags its input lower.
     (A rare three-line label still bottom-aligns via the row rule above.) */
  .split-scroll .col-inputs .cols2 > .field > label {
    display: flex;
    align-items: flex-end;
    min-height: 27px;
  }
  .split-scroll .col-inputs .cols2 > .field { flex: 2 1 170px; min-width: 150px; margin-bottom: 0; }
  .split-scroll .col-inputs .cols2 > .f-short { flex: 1 1 96px; min-width: 90px; }
  .split-scroll .col-inputs .cols2 > .f-wide,
  .split-scroll .col-inputs .cols2 > .f-money { flex: 1 1 100%; }
  .split-scroll .col-inputs .cols2 > .span2 { flex: 1 1 100%; }
  @container (min-width: 640px) {
    .split-scroll .col-inputs .cols2 > .field { flex: 2 1 145px; min-width: 132px; }
    .split-scroll .col-inputs .cols2 > .f-short { flex: 1 1 70px; min-width: 64px; }
    .split-scroll .col-inputs .cols2 > .f-wide { flex: 3 1 195px; min-width: 175px; }
    .split-scroll .col-inputs .cols2 > .f-money { flex: 3 1 190px; min-width: 170px; }
  }
}
@media (max-width: 900px) {
  .split-divider { display: none; }
}

/* LOUD LENDER WARNINGS: active warnings render red with an icon, stacked when
   several fire at once. The clean state ("no lender warnings") keeps the quiet
   .meta styling. Token colors only — legible on both themes' band tints. */
.status-band .lender-warn {
  display: flex;
  flex-direction: column;
  gap: 2px;
  align-items: flex-end;
  text-align: right;
  font: 700 12px var(--font);
  color: var(--bad);
}
.status-band .lender-warn .w { display: flex; gap: 6px; align-items: baseline; }

/* SAVE FEEDBACK: "Saved ✓" tick beside the Save button. The disabled/grey
   button state comes from the existing global button:disabled rule. */
.action-bar .saved-tick {
  align-self: center;
  font: 700 12px var(--font);
  color: var(--good);
  white-space: nowrap;
}
