/* Battery vs better-timing simulator.
   Shared by tools/battery-vs-load-shifting.html and the embeddable copy at
   embed/battery-vs-load-shifting.html. Every colour comes from an onsun.css
   custom property, so the tool follows whichever theme the host page sets.

   Shape rules: controls sit on a 10px radius, small tags on 6px, surfaces on
   the site's --r-* scale. Nothing on the tool is a fully-rounded pill. */
.bt-tool {
  --bt-r-ctl: 10px;
  --bt-r-tag: 6px;
  --bt-rail: rgba(28, 28, 30, 0.10);
  --bt-blue: #4d8dff;
  --bt-amber: #f5a524;
  --bt-orange: #f0762a;
  --bt-red: #e5473a;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: 1.35rem 1.35rem 1.1rem;
  margin: 1.6rem 0 2rem;
}
[data-theme="dark"] .bt-tool {
  --bt-rail: rgba(255, 255, 255, 0.16);
  background: linear-gradient(135deg, rgba(255, 77, 141, 0.08) 0%, rgba(0, 212, 170, 0.05) 100%);
  border-color: var(--chip-border);
  box-shadow: none;
}
.bt-visually-hidden {
  position: absolute !important; width: 1px; height: 1px; margin: -1px;
  padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- head ---------- */
.bt-head { display: flex; align-items: flex-start; gap: 0.9rem; margin-bottom: 1.2rem; }
.bt-logo { width: 46px; height: 46px; flex: none; border-radius: 13px; box-shadow: none; }
.bt-logo-link { display: inline-flex; line-height: 0; flex: none; margin-top: 1px; }
.bt-head-text h3 { margin: 0 0 0.3rem; font-size: 1.35rem; line-height: 1.2; letter-spacing: -0.02em; color: var(--text-primary); }
.bt-head-text p { margin: 0; font-size: 0.92rem; line-height: 1.55; color: var(--text-secondary); max-width: 44rem; }

/* ---------- sharing the tool itself ----------
   Sits in the header, apart from the two "share this answer" buttons among
   the results, because it shares something different: the tool's own link,
   with none of the visitor's answers on it. */
.bt-head-actions {
  position: relative; flex: none; margin-left: auto;
  display: flex; align-items: center; gap: 0.4rem;
}
.bt-share-tool {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font: inherit; font-size: 0.82rem; font-weight: 600; line-height: 1;
  color: var(--text-secondary); background: var(--bg-card);
  border: 1px solid var(--border-strong); border-radius: var(--bt-r-ctl);
  padding: 0.45rem 0.7rem; cursor: pointer; white-space: nowrap;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.bt-share-tool:hover { color: var(--coral); border-color: var(--coral); }
.bt-share-tool:focus-visible { outline: 2px solid var(--coral); outline-offset: 2px; }
.bt-share-tool svg { width: 15px; height: 15px; flex: none; }
.bt-share-menu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 20;
  min-width: 13.5rem; padding: 0.4rem;
  background: var(--bg-card); border: 1px solid var(--border-strong);
  border-radius: var(--r-media); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.14);
}
[data-theme="dark"] .bt-share-menu { background: var(--bg-card-2); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5); }
.bt-share-menu[hidden] { display: none; }
.bt-share-menu-note {
  margin: 0.15rem 0.5rem 0.35rem; font-size: 0.72rem; line-height: 1.35; color: var(--text-muted);
}
.bt-share-net {
  display: block; width: 100%; text-align: left; font: inherit; font-size: 0.84rem; font-weight: 600;
  color: var(--text-primary); background: none; border: 0; border-radius: var(--bt-r-tag);
  padding: 0.45rem 0.5rem; cursor: pointer; text-decoration: none;
}
.bt-share-net:hover { background: var(--surface-soft); color: var(--coral); }
.bt-share-net:focus-visible { outline: 2px solid var(--coral); outline-offset: -2px; }
.bt-share-net.bt-copied { color: var(--green); }

/* ---------- buttons ---------- */
.bt-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.45rem;
  font: inherit; font-size: 0.9rem; font-weight: 600; line-height: 1.2;
  color: var(--text-primary); background: var(--bg-card);
  border: 1px solid var(--border-strong); border-radius: var(--bt-r-ctl);
  padding: 0.6rem 1.05rem; cursor: pointer; min-height: 42px;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.12s ease, box-shadow 0.15s ease;
}
.bt-btn:hover { border-color: var(--text-muted); }
.bt-btn:active { transform: scale(0.985); }
.bt-btn:focus-visible { outline: 2px solid var(--coral); outline-offset: 2px; }
.bt-btn svg { width: 17px; height: 17px; flex: none; }
.bt-btn:disabled { opacity: 0.45; cursor: default; transform: none; }
.bt-btn-primary {
  color: #fff; background: var(--coral); border-color: var(--coral);
  box-shadow: 0 6px 18px rgba(255, 107, 71, 0.22);
}
.bt-btn-primary:hover { background: var(--coral-2); border-color: var(--coral-2); }
[data-theme="dark"] .bt-btn-primary { box-shadow: 0 6px 18px rgba(255, 77, 141, 0.28); }
[data-theme="dark"] .bt-btn { background: rgba(10, 10, 26, 0.45); }
[data-theme="dark"] .bt-btn-primary { background: var(--coral); }

.bt-copy-btn .bt-icon-tick, .bt-copy-btn .bt-label-done { display: none; }
.bt-copy-btn.bt-copied { color: var(--green); border-color: var(--green); animation: bt-pop 0.5s ease; }
.bt-copy-btn.bt-copied .bt-icon-idle { display: none; }
.bt-copy-btn.bt-copied .bt-icon-tick, .bt-copy-btn.bt-copied .bt-label-done { display: block; }
.bt-share-tool.bt-copied .bt-icon-tick { display: inline-block; }
.bt-copy-btn.bt-copied .bt-label-idle { display: none; }
@keyframes bt-pop {
  0% { transform: scale(1); } 35% { transform: scale(0.96); }
  70% { transform: scale(1.03); } 100% { transform: scale(1); }
}

/* ---------- the question flow ----------
   Three sections stacked. The open one shows its questions; the others show
   a one-line summary of the answer given, so the whole conversation stays on
   screen and any answer is one tap from being changed. */
.bt-wiz { display: grid; gap: 0.6rem; }
.bt-step {
  border: 1px solid var(--border); border-radius: var(--r-panel);
  background: var(--surface-soft); overflow: hidden;
  transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
}
/* The step you are on is the only white card, and the only one with a hard
   outline. The inset shadow doubles the border without moving anything, so
   opening a step never nudges the layout by a pixel. */
.bt-step.open {
  background: var(--bg-card); border-color: var(--text-primary);
  box-shadow: inset 0 0 0 1px var(--text-primary);
}
/* A hard white outline is too loud on the dark canvas, so the open card is
   marked by a bright hairline rather than by a doubled black edge. */
[data-theme="dark"] .bt-step.open {
  background: rgba(10, 10, 26, 0.35); border-color: rgba(255, 255, 255, 0.30);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16);
}
.bt-step-head {
  width: 100%; display: flex; align-items: center; gap: 0.85rem; text-align: left;
  font: inherit; color: var(--text-primary); background: none; border: 0;
  padding: 0.95rem 1.05rem; cursor: pointer; min-height: 60px;
}
.bt-step-head:disabled { cursor: default; }
.bt-step-head:focus-visible { outline: 2px solid var(--coral); outline-offset: -2px; border-radius: var(--r-panel); }
/* Each step keeps its own picture through all three states; only the colour of
   the tile changes, so the row you are on is obvious at a glance. */
.bt-step-icon {
  flex: none; width: 38px; height: 38px; border-radius: 12px;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(28, 28, 30, 0.06); color: var(--text-muted);
  transition: background 0.2s ease, color 0.2s ease;
}
.bt-step-icon svg { width: 20px; height: 20px; }
[data-theme="dark"] .bt-step-icon { background: rgba(255, 255, 255, 0.08); }
.bt-step.open .bt-step-icon { background: var(--coral); color: #fff; }
.bt-step.done:not(.open) .bt-step-icon { background: rgba(26, 143, 63, 0.12); color: var(--green); }
[data-theme="dark"] .bt-step.done:not(.open) .bt-step-icon { background: rgba(0, 212, 170, 0.14); }
.bt-step-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; }
.bt-step-q { font-size: 1.02rem; font-weight: 700; line-height: 1.3; letter-spacing: -0.005em; }
.bt-step-sum {
  font-size: 0.86rem; line-height: 1.4; color: var(--text-secondary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bt-step-sum:empty { display: none; }
.bt-step.open .bt-step-sum { display: none; }
/* Until a step has been answered its header explains what it asks; only a step
   you have actually been through shows a summary of the answers. */
.bt-step:not(.done) .bt-step-sum { display: none; }
/* Hints wrap rather than clip: an explanation cut off mid-sentence is worse
   than a two-line row. The answer summary above still clips, because it can
   be long and the step is already understood by then. */
.bt-step-hint { font-size: 0.86rem; line-height: 1.4; color: var(--text-secondary); }
.bt-step.done .bt-step-hint { display: none; }
/* Sits under the hint it belongs to, quieter than it. */
.bt-step-note { display: block; margin-top: 0.15rem; font-size: 0.8rem; color: var(--text-muted); }
.bt-step-head:disabled .bt-step-q { color: var(--text-muted); }
/* Answered steps carry a green tick on the right edge. It draws itself in
   rather than appearing, which reads as "that one is done" without a caption. */
.bt-step-tick {
  width: 22px; height: 22px; flex: none; color: var(--green);
  opacity: 0; transform: scale(0.5);
  transition: opacity 0.2s ease, transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.bt-step.done:not(.open) .bt-step-tick { opacity: 1; transform: none; }

/* Open / close via a grid track so the height animates without measuring. */
.bt-step-body {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows 0.32s cubic-bezier(0.22, 1, 0.36, 1);
}
.bt-step.open .bt-step-body { grid-template-rows: 1fr; }
/* min-width 0: a grid item defaults to its min-content width, which on a
   phone came out wider than the card. */
.bt-step-body > .bt-step-inner { min-height: 0; min-width: 0; overflow: hidden; }
.bt-step.open.settled .bt-step-body > .bt-step-inner { overflow: visible; }
/* No vertical padding on the clipped wrapper, or a closed step would still
   show a padding-high sliver of its content. The gap is content instead. */
.bt-step-inner { padding: 0 1.05rem; }
.bt-step-inner::after { content: ""; display: block; height: 1.05rem; }
.bt-step-lead { margin: 0 0 0.9rem; font-size: 0.9rem; line-height: 1.55; color: var(--text-secondary); max-width: 46rem; }
.bt-step-nav { display: flex; justify-content: flex-end; margin-top: 1.1rem; }
.bt-step-nav .bt-btn { min-width: 10rem; }

/* ---------- location: search + map ---------- */
.bt-search { position: relative; display: flex; gap: 0.55rem; align-items: stretch; margin-bottom: 0.7rem; }
.bt-search-box {
  position: relative; flex: 1 1 auto; min-width: 0; display: flex; align-items: center;
  background: var(--bg-card); border: 1px solid var(--border-strong);
  border-radius: var(--bt-r-ctl); min-height: 46px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.bt-search-box:focus-within { border-color: var(--coral); box-shadow: 0 0 0 3px rgba(255, 107, 71, 0.16); }
.bt-search-box > svg { width: 18px; height: 18px; flex: none; margin: 0 0.25rem 0 0.8rem; color: var(--text-muted); }
.bt-search-box input {
  flex: 1 1 auto; min-width: 0; font: inherit; font-size: 0.95rem; color: var(--text-primary);
  background: transparent; border: 0; padding: 0.55rem 0.5rem; outline: none;
  -webkit-appearance: none; appearance: none;
}
.bt-search-box input::-webkit-search-cancel-button { -webkit-appearance: none; }
.bt-search-box input::placeholder { color: var(--text-muted); }
.bt-search-go {
  flex: none; font: inherit; font-size: 0.84rem; font-weight: 700; color: var(--text-primary);
  background: var(--surface-soft); border: 0; border-left: 1px solid var(--border);
  border-radius: 0 calc(var(--bt-r-ctl) - 1px) calc(var(--bt-r-ctl) - 1px) 0;
  padding: 0 0.95rem; align-self: stretch; cursor: pointer;
}
.bt-search-go:hover { background: var(--chip-bg); color: var(--coral); }
.bt-btn-locate { flex: none; }
[data-theme="dark"] .bt-search-box { background: rgba(10, 10, 26, 0.65); }
.bt-search-list {
  position: absolute; z-index: 20; top: calc(100% + 6px); left: 0; right: 0;
  list-style: none; margin: 0; padding: 0.35rem;
  background: var(--bg-card); border: 1px solid var(--border-strong);
  border-radius: var(--bt-r-ctl); box-shadow: var(--shadow-card);
  animation: bt-drop 0.16s ease;
}
.bt-search-list[hidden] { display: none; }
@keyframes bt-drop { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.bt-search-item {
  display: flex; flex-direction: column; gap: 0.05rem; padding: 0.5rem 0.7rem;
  border-radius: 7px; cursor: pointer; font-size: 0.9rem; color: var(--text-primary);
}
.bt-search-item small { font-size: 0.78rem; color: var(--text-muted); }
.bt-search-item:hover, .bt-search-item.active { background: var(--chip-bg); }
.bt-search-item.bt-search-none { color: var(--text-secondary); cursor: default; }
.bt-search-item.bt-search-none:hover { background: none; }
[data-theme="dark"] .bt-search-list { background: var(--bg-card); }

#bt-map {
  height: 300px; background: var(--surface-soft);
  border-radius: var(--r-media); border: 1px solid var(--border);
  overflow: hidden; z-index: 0;
}
#bt-map img { border-radius: 0; box-shadow: none; }
#bt-map .leaflet-control-zoom a { border-radius: 0; }
[data-theme="dark"] #bt-map { border-color: transparent; }
[data-theme="dark"] #bt-map .leaflet-control-attribution { background: rgba(10, 10, 26, 0.7); color: var(--text-muted); }
[data-theme="dark"] #bt-map .leaflet-control-attribution a { color: var(--text-secondary); }
.bt-hint { margin: 0.65rem 0 0; font-size: 0.84rem; line-height: 1.5; color: var(--text-muted); }
.bt-msg { margin: 0.6rem 0 0; font-size: 0.86rem; color: var(--coral); }
.bt-fallback { display: none; gap: 0.5rem; align-items: center; flex-wrap: wrap; margin-top: 0.7rem; }
.bt-fallback label { font-size: 0.85rem; color: var(--text-secondary); }
.bt-fallback input { width: 6.5rem; font: inherit; padding: 0.45rem 0.6rem; border: 1px solid var(--border); border-radius: var(--bt-r-ctl); background: var(--bg-card); color: var(--text-primary); }

/* Fetch and simulation status: the whole list stays in view, each line
   spinning while it is worked on and ticked when it is done, with the bar
   underneath. */
.bt-progress { display: none; margin-top: 0.8rem; }
.bt-progress.on { display: block; }
.bt-progress-bar { height: 4px; border-radius: 2px; background: var(--border); overflow: hidden; margin-top: 0.65rem; }
.bt-progress-fill { height: 100%; width: 0%; background: var(--gradient-accent); transition: width 0.4s ease; }
.bt-progress-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.32rem; }
.bt-progress-steps li { display: flex; align-items: center; gap: 0.55rem; font-size: 0.84rem; color: var(--text-muted); font-weight: 600; transition: color 0.25s ease; }
.bt-progress-steps li.doing { color: var(--text-primary); }
.bt-progress-steps li.done { color: var(--text-secondary); }
.bt-progress-steps li .bt-dot {
  position: relative; width: 14px; height: 14px; flex: none; border-radius: 50%; box-sizing: border-box;
  border: 2px solid var(--border-strong); transition: background 0.2s ease, border-color 0.2s ease;
}
.bt-progress-steps li.doing .bt-dot { border-color: var(--coral); border-top-color: transparent; animation: bt-spin 0.8s linear infinite; }
.bt-progress-steps li.done .bt-dot { background: var(--green); border-color: var(--green); }
.bt-progress-steps li.done .bt-dot::after {
  content: ""; position: absolute; left: 3px; top: 0.5px; width: 3px; height: 6px;
  border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg);
}
@keyframes bt-spin { to { transform: rotate(360deg); } }
/* Finished and kept as the record: ticks only, no bar. */
.bt-progress-kept .bt-progress-bar { display: none; }
.bt-progress-kept .bt-progress-steps li.done { color: var(--text-secondary); }

/* ---------- questions ---------- */
.bt-group { padding: 0.85rem 0 0; }
.bt-group + .bt-group { margin-top: 0.35rem; }
.bt-q { margin: 0 0 0.6rem; font-size: 0.95rem; font-weight: 700; color: var(--text-primary); line-height: 1.35; }
/* Wide enough for a label column: the question sits on the left and its
   answers line up down the right, so the five answers scan as one list.
   Scoped to the home step on purpose. Its groups are all one question and one
   row of choices; the solar and price groups carry headings over field grids,
   which want the full width. */
@media (min-width: 640px) {
  #bt-body-home .bt-group:not(.bt-group-pair), #bt-body-home .bt-group-pair > div {
    display: grid; grid-template-columns: 10.5rem minmax(0, 1fr);
    gap: 0.35rem 1.1rem; align-items: center;
  }
  #bt-body-home .bt-group > .bt-q, #bt-body-home .bt-group-pair > div > .bt-q { margin: 0; }
  #bt-body-home .bt-group-pair { display: block; }
  #bt-body-home .bt-group-pair > div + div { margin-top: 0.85rem; }
}
.bt-grid-top { margin-top: 0.9rem; max-width: 34rem; }

/* Segmented choices: one bordered strip, the chosen segment filled solid. */
.bt-pills { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.bt-pill {
  flex: 1 1 auto; font: inherit; font-size: 0.86rem; font-weight: 600; line-height: 1.25;
  color: var(--text-secondary); background: var(--bg-card);
  border: 1px solid var(--border-strong); border-radius: var(--bt-r-ctl);
  padding: 0.38rem 0.85rem; min-height: 36px; cursor: pointer; white-space: nowrap;
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease, transform 0.12s ease;
}
.bt-pill:hover { border-color: var(--text-muted); color: var(--text-primary); }
.bt-pill:active { transform: scale(0.985); }
.bt-pill:focus-visible { outline: 2px solid var(--coral); outline-offset: 2px; }
/* The chosen answer is tinted, not inverted: a page of solid black blocks
   read as disabled controls rather than as choices already made. */
.bt-pill { color: var(--text-primary); }
.bt-pill.on {
  color: var(--coral); border-color: var(--coral); font-weight: 700;
  background: rgba(255, 107, 71, 0.09);
  background: color-mix(in srgb, var(--coral) 10%, var(--bg-card));
}
[data-theme="dark"] .bt-pill { background: rgba(10, 10, 26, 0.45); }
[data-theme="dark"] .bt-pill.on { background: rgba(255, 77, 141, 0.16); }

.bt-currency-note { margin: -0.2rem 0 0.75rem; font-size: 0.8rem; line-height: 1.5; color: var(--text-muted); }
.bt-currency-note:empty { display: none; }

/* Optional disclosures, styled as quiet links rather than boxes. */
.bt-opt { margin-top: 0.85rem; }
.bt-opt > summary {
  cursor: pointer; font-size: 0.84rem; font-weight: 600; color: var(--text-secondary);
  list-style: none; display: inline-flex; align-items: center; gap: 0.4rem;
}
.bt-opt > summary::-webkit-details-marker { display: none; }
.bt-opt > summary::before {
  content: ""; width: 7px; height: 7px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(-45deg) translateY(1px); transition: transform 0.18s ease; margin-right: 0.15rem;
}
.bt-opt[open] > summary::before { transform: rotate(45deg) translateY(-1px); }
.bt-opt > summary:hover { color: var(--coral); }
.bt-opt-tag { font-size: 0.72rem; font-weight: 500; color: var(--text-muted); }
.bt-opt > summary:hover .bt-opt-tag { color: inherit; }
.bt-opt-sub { margin: 0.6rem 0 0; font-size: 0.8rem; color: var(--text-muted); line-height: 1.5; }
.bt-opt .bt-grid { margin-top: 0.8rem; }
.bt-field-note { margin: 0.35rem 0 0; font-size: 0.76rem; color: var(--text-muted); line-height: 1.45; }

.bt-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 0.85rem 1.1rem; }
/* The array row and the battery row read as a pair, so they take the same
   two-column split and the same width rather than each sizing itself from its
   own contents - which is what left the two sliders ending in different
   places. The width cap that .bt-grid-top puts on a lone field is dropped. */
.bt-grid-size { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: none; }
@media (max-width: 560px) { .bt-grid-size { grid-template-columns: 1fr; } }
.bt-field[hidden] { display: none; }
/* Labels get two lines' worth and sit on their bottom edge, so the boxes in
   a row line up even when one label wraps or one field carries a note. */
.bt-field label { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0 0.3em; font-size: 0.82rem; font-weight: 600; color: var(--text-secondary); margin: 0 0 0.35rem; line-height: 1.35; }
@media (min-width: 561px) { .bt-grid .bt-field label { min-height: 2.7em; } }
.bt-field input[type="number"], .bt-field select {
  width: 100%; font: inherit; font-size: 0.95rem; padding: 0.55rem 0.7rem; min-height: 42px;
  border: 1px solid var(--border-strong); border-radius: var(--bt-r-ctl);
  background: var(--bg-card); color: var(--text-primary);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.bt-field input[type="number"]:focus, .bt-field select:focus {
  outline: none; border-color: var(--coral); box-shadow: 0 0 0 3px rgba(255, 107, 71, 0.16);
}
/* Sliders are drawn by hand rather than left to accent-color, which colours
   the filled side but leaves the rest the browser's own dark grey - so an
   empty slider read as a full one. The rail is a hairline; the fill is a
   gradient stop the JS keeps in step with the value, because WebKit has no
   pseudo-element for the travelled part of a track. Firefox paints that with
   ::-moz-range-progress and ignores the gradient. */
.bt-tool input[type="range"] {
  -webkit-appearance: none; appearance: none;
  width: 100%; background: transparent; cursor: pointer;
  accent-color: var(--coral);
}
.bt-tool input[type="range"]::-webkit-slider-runnable-track {
  height: 6px; border-radius: 999px;
  background: linear-gradient(to right,
    var(--coral) 0 var(--bt-fill, 0%), var(--bt-rail) var(--bt-fill, 0%) 100%);
}
.bt-tool input[type="range"]::-moz-range-track { height: 6px; border-radius: 999px; background: var(--bt-rail); }
.bt-tool input[type="range"]::-moz-range-progress { height: 6px; border-radius: 999px; background: var(--coral); }
.bt-tool input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 18px; height: 18px; margin-top: -6px; border-radius: 50%;
  background: var(--coral); border: 2px solid var(--bg-card);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
}
.bt-tool input[type="range"]::-moz-range-thumb {
  width: 18px; height: 18px; border-radius: 50%; box-sizing: border-box;
  background: var(--coral); border: 2px solid var(--bg-card);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
}
.bt-tool input[type="range"]:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px rgba(255, 107, 71, 0.4); }
.bt-tool input[type="range"]:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 3px rgba(255, 107, 71, 0.4); }
/* In a two-up row the slider shares a line with a 42px-tall box, so it takes
   the same height and centres its track against it. */
.bt-grid .bt-field input[type="range"] { height: 42px; }
.bt-field .bt-range-val { font-size: 0.85rem; font-weight: 700; color: var(--text-primary); }
[data-theme="dark"] .bt-field input, [data-theme="dark"] .bt-field select,
[data-theme="dark"] .bt-fallback input,
[data-theme="dark"] .bt-info-tip { background: rgba(10, 10, 26, 0.65); }
.bt-unit { font-weight: 400; color: var(--text-muted); }

/* ---------- appliance picker ----------
   One grid of cards, each a toggle. Picking a card fills its circle and draws
   the tick in, so the tap answers itself; the logo stays put and only loses
   its grey when the appliance moves into the sun. */
.bt-appl-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 0.55rem; }
.bt-appl {
  position: relative; display: flex; flex-direction: column; cursor: pointer;
  background: var(--bg-card); border: 1px solid var(--border-strong);
  border-radius: var(--r-media);
  transition: border-color 0.18s ease, background 0.18s ease, transform 0.12s ease;
}
/* The whole card is the target, so the whole card takes the press. */
.bt-appl:active { transform: scale(0.985); }
.bt-appl:hover { border-color: var(--text-muted); }
.bt-appl.on {
  border-color: var(--coral);
  background: rgba(255, 107, 71, 0.08);
  background: color-mix(in srgb, var(--coral) 9%, var(--bg-card));
}
[data-theme="dark"] .bt-appl.on { background: rgba(255, 77, 141, 0.14); }
.bt-appl-main {
  width: 100%; display: flex; align-items: center; gap: 0.6rem;
  font: inherit; text-align: left; cursor: pointer;
  padding: 0.65rem 0.75rem; background: none; border: 0;
  border-radius: var(--r-media); color: inherit;
}
/* Focus stays on the button, which is still the real control; the ring just
   moves out to the card, because the card is what the click now covers. A
   browser without :has() drops the last two rules and rings the button. */
.bt-appl-main:focus-visible { outline: 2px solid var(--coral); outline-offset: -2px; }
.bt-appl:has(.bt-appl-main:focus-visible) { outline: 2px solid var(--coral); outline-offset: 2px; }
.bt-appl:has(.bt-appl-main:focus-visible) .bt-appl-main { outline: none; }

/* The circle: an empty outline until it is picked, then coral with the tick
   stroked in. Drawing the path rather than fading it in is what makes the
   tap feel answered. */
.bt-appl-tick {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  border: 2px solid var(--border-strong); background: transparent; color: #fff;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.bt-appl-tick svg { width: 14px; height: 14px; }
.bt-appl-tick svg path { stroke-dasharray: 24; stroke-dashoffset: 24; transition: stroke-dashoffset 0.3s cubic-bezier(0.22, 1, 0.36, 1) 0.05s; }
.bt-appl.on .bt-appl-tick { background: var(--coral); border-color: var(--coral); }
.bt-appl.on .bt-appl-tick svg path { stroke-dashoffset: 0; }
/* One short pop on the tap that turned it on. */
.bt-appl.bt-landed .bt-appl-tick { animation: bt-pop 0.42s cubic-bezier(0.34, 1.56, 0.64, 1); }
@keyframes bt-pop {
  0% { transform: scale(0.62); }
  55% { transform: scale(1.14); }
  100% { transform: scale(1); }
}

.bt-appl img { width: 30px; height: 30px; flex: none; object-fit: contain; border-radius: 0; box-shadow: none; transition: filter 0.25s ease, opacity 0.25s ease; }
.bt-appl:not(.on) img { filter: grayscale(1); opacity: 0.5; }
.bt-appl-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0.06rem; }
.bt-appl-name { font-size: 0.85rem; font-weight: 700; color: var(--text-primary); line-height: 1.25; }
.bt-appl-kw { font-size: 0.7rem; color: var(--text-muted); line-height: 1.25; }

/* How often it runs. Only worth asking once the appliance is in the sun, so
   the row appears with the pick rather than crowding every card. */
.bt-appl-freq-row { display: none; align-items: baseline; flex-wrap: wrap; gap: 0.15rem 0.4rem; padding: 0 0.75rem 0.6rem 3.15rem; }
.bt-appl.on .bt-appl-freq-row { display: flex; }
.bt-appl-freq {
  font: inherit; font-size: 0.74rem; font-weight: 700;
  padding: 0.2rem 0.35rem; text-align: center;
  color: var(--text-primary); background: var(--bg-card);
  border: 1px solid var(--border-strong); border-radius: 7px; cursor: pointer;
}
.bt-appl-freq:hover { border-color: var(--text-muted); }
.bt-appl:has(.bt-appl-freq:active) { transform: none; }
.bt-appl-unit { font-size: 0.7rem; line-height: 1.2; color: var(--text-muted); }

.bt-shift-summary {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem 1rem;
  margin-top: 0.85rem; padding: 0.7rem 0.9rem;
  background: var(--surface-soft); border: 1px solid var(--border); border-radius: var(--r-media);
}
.bt-shift-main { display: flex; align-items: baseline; gap: 0.45rem; flex-wrap: wrap; }
#bt-shift-total { font-size: 1.3rem; font-weight: 800; letter-spacing: -0.02em; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.bt-shift-lead { font-size: 0.84rem; color: var(--text-secondary); }
#bt-shift-peak { font-variant-numeric: tabular-nums; }
.bt-shift-money { font-size: 0.9rem; font-weight: 700; color: var(--green); font-variant-numeric: tabular-nums; }
.bt-shift-money[hidden] { display: none; }
#bt-shift-note { margin-top: 0.5rem; }
#bt-shift-note[hidden] { display: none; }

/* ---------- results ---------- */
.bt-results { margin-top: 1.4rem; padding-top: 1.4rem; border-top: 1px solid var(--border); }
.bt-results[hidden] { display: none; }
.bt-results.bt-stale { opacity: 0.45; transition: opacity 0.3s ease; }
.bt-results.bt-reveal > * { animation: bt-rise 0.55s cubic-bezier(0.22, 1, 0.36, 1) both; }
.bt-results.bt-reveal > :nth-child(2) { animation-delay: 0.08s; }
.bt-results.bt-reveal > :nth-child(3) { animation-delay: 0.16s; }
.bt-results.bt-reveal > :nth-child(n+4) { animation-delay: 0.24s; }
@keyframes bt-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

.bt-verdict { margin-bottom: 1.1rem; max-width: 52rem; }
.bt-verdict-kicker { margin: 0 0 0.3rem; font-size: 0.84rem; font-weight: 700; color: var(--coral); }
.bt-verdict-kicker:empty { display: none; }
.bt-verdict h4 { margin: 0 0 0.45rem; font-size: 1.45rem; line-height: 1.22; letter-spacing: -0.02em; color: var(--text-primary); }
.bt-verdict p { margin: 0; font-size: 0.93rem; color: var(--text-secondary); line-height: 1.62; }

/* The options, side by side. The winner sits on a warm tint; the rest stay plain. */
/* ---------- how far ahead ----------
   The only control that lives among the results. It decides which year the
   options are judged on, so it sits directly above the cards it re-ranks. */
.bt-horizon {
  margin: 0 0 0.9rem; padding: 0.8rem 1rem 0.85rem;
  background: var(--surface-soft); border: 1px solid var(--border);
  border-radius: var(--r-media);
}
.bt-horizon-lab { display: block; font-size: 0.88rem; line-height: 1.4; color: var(--text-secondary); }
.bt-horizon-lab b { color: var(--text-primary); font-weight: 700; font-variant-numeric: tabular-nums; }
.bt-horizon input[type="range"] { width: 100%; margin: 0.5rem 0 0; accent-color: var(--coral); }
.bt-horizon input[type="range"]:focus-visible { outline: 2px solid var(--coral); outline-offset: 3px; }
.bt-horizon-scale { display: flex; justify-content: space-between; margin-top: 0.05rem; font-size: 0.72rem; color: var(--text-muted); }
.bt-horizon-note { margin: 0.45rem 0 0; font-size: 0.76rem; line-height: 1.45; color: var(--text-muted); }

.bt-paths { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 0.7rem; margin-bottom: 1.6rem; }
/* Four options (no panels yet) read better as two rows than four thin columns. */
.bt-paths.bt-paths-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.bt-path {
  position: relative; display: flex; flex-direction: column; gap: 0.15rem;
  padding: 1rem 1rem 0.9rem; border: 1px solid var(--border); border-radius: var(--r-panel);
  /* Cards carry different amounts of text; a subgrid lines every row up across
     them (name, blurb, figure, label, rows, note) so they read as one set. */
  display: grid; grid-template-rows: subgrid; grid-row: span 6; row-gap: 0; align-content: start;
  /* Each card is washed and framed in its rank's colour - the same colour its
     line carries on the chart - so the two read as one thing. The plain
     background is the fallback where color-mix is unsupported. */
  background: var(--bg-card);
  background: color-mix(in srgb, var(--bt-light, transparent) 8%, var(--bg-card));
  border-color: var(--bt-light, var(--border)); border-top: 4px solid var(--bt-light, var(--border));
}
[data-theme="dark"] .bt-path {
  background: rgba(10, 10, 26, 0.35);
  background: color-mix(in srgb, var(--bt-light, transparent) 15%, rgba(10, 10, 26, 0.35));
}
/* The winner takes the same green further, and a second ring, so it still
   leads the set rather than merely joining it. */
.bt-path.best {
  background: color-mix(in srgb, var(--bt-light) 16%, var(--bg-card));
  box-shadow: 0 0 0 1px var(--bt-light);
}
[data-theme="dark"] .bt-path.best { background: color-mix(in srgb, var(--bt-light) 24%, rgba(10, 10, 26, 0.35)); }
/* A re-rank is played in two beats: the cards slide to their new places, and
   only once they have landed do they take on the colour of the rank they
   landed in. Both at once reads as a glitch; one after the other reads as a
   decision being remade. The delay on the colour is the length of the move. */
.bt-path.bt-shuffle {
  transition:
    transform 0.5s cubic-bezier(0.22, 1, 0.36, 1),
    background 0.42s ease 0.46s,
    border-color 0.42s ease 0.46s,
    box-shadow 0.42s ease 0.46s;
}
.bt-path.bt-shuffle .bt-path-tag {
  transition: background 0.42s ease 0.46s, border-color 0.42s ease 0.46s, color 0.42s ease 0.46s;
}
/* A card mid-move must paint over its neighbours, not slide under them. */
.bt-path.bt-shuffle { z-index: 1; }
.bt-path-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.5rem; }
.bt-path-name { font-size: 0.98rem; font-weight: 700; color: var(--text-primary); line-height: 1.25; }
.bt-path-tag {
  flex: none; font-size: 0.7rem; font-weight: 700; line-height: 1; padding: 0.3rem 0.45rem;
  border-radius: var(--bt-r-tag); color: var(--bt-tag-fg, #fff); background: var(--bt-light); border: 1px solid var(--bt-light);
  white-space: nowrap;
}
.bt-path.best .bt-path-tag { color: #fff; background: var(--green); border-color: var(--green); }
.bt-path-sub { font-size: 0.78rem; color: var(--text-secondary); line-height: 1.45; margin: 0.3rem 0 0.55rem; }
.bt-path-big { font-size: 1.8rem; font-weight: 800; line-height: 1.05; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; color: var(--text-primary); }
.bt-path-big.neg { color: var(--coral); }
.bt-path-big.pos { color: var(--green); }
.bt-path-biglab { font-size: 0.76rem; color: var(--text-muted); margin-bottom: 0.7rem; }
.bt-path-rows {
  display: grid; gap: 0.3rem; padding-top: 0.6rem; align-self: end;
  /* A neutral hairline disappears on a tinted card, so the divider is a faint
     wash of the card's own colour. */
  border-top: 1px solid var(--border);
  border-top-color: color-mix(in srgb, var(--bt-light, var(--border)) 35%, transparent);
}
.bt-path-row { display: flex; justify-content: space-between; gap: 0.6rem; font-size: 0.8rem; line-height: 1.35; }
.bt-path-row span:first-child { color: var(--text-secondary); }
.bt-path-row span:last-child { color: var(--text-primary); font-weight: 600; font-variant-numeric: tabular-nums; text-align: right; }
.bt-path-note { margin: 0.45rem 0 0; font-size: 0.74rem; line-height: 1.4; color: var(--text-muted); }
.bt-path-note:empty { margin: 0; }

/* ---------- chart ---------- */
.bt-section-h { margin: 1.5rem 0 0.3rem; font-size: 1.05rem; letter-spacing: -0.01em; color: var(--text-primary); display: flex; align-items: center; gap: 0.5rem; }
.bt-ico { width: 18px; height: 18px; flex: none; color: var(--coral); }
.bt-more > summary > span { display: inline-flex; align-items: center; gap: 0.5rem; }
.bt-section-sub { margin: 0 0 0.8rem; font-size: 0.86rem; line-height: 1.55; color: var(--text-secondary); max-width: 46rem; }
#bt-chart-wrap { position: relative; }
#bt-chart { display: block; width: 100%; height: 290px; }
.bt-legend { display: flex; justify-content: center; gap: 1.1rem; flex-wrap: wrap; margin: 0.55rem 0 0; }
.bt-legend span { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.82rem; color: var(--text-secondary); }
.bt-legend i { width: 18px; height: 4px; border-radius: 2px; display: inline-block; }

/* ---------- small stats ---------- */
.bt-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.7rem; margin-top: 1.4rem; }
.bt-stat { background: var(--surface-soft); border: 1px solid var(--border); border-radius: var(--r-media); padding: 0.85rem 0.9rem; }
.bt-stat .bt-num { font-size: 1.55rem; font-weight: 800; letter-spacing: -0.02em; line-height: 1.1; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.bt-stat .bt-lab { font-size: 0.78rem; color: var(--text-secondary); margin-top: 0.25rem; line-height: 1.4; }

/* ---------- folded sections ---------- */
.bt-more { margin-top: 0.85rem; border: 1px solid var(--border); border-radius: var(--r-panel); background: var(--surface-soft); }
.bt-more > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 0.6rem;
  padding: 0.85rem 1.05rem; font-size: 0.98rem; font-weight: 700; color: var(--text-primary);
}
.bt-more > summary::-webkit-details-marker { display: none; }
.bt-more > summary svg { width: 18px; height: 18px; color: var(--text-muted); transition: transform 0.22s ease; flex: none; }
.bt-more[open] > summary svg { transform: rotate(180deg); }
.bt-more > summary:hover { color: var(--coral); }
.bt-more-body { padding: 0 1.05rem 1.05rem; }
.bt-more-body > .bt-section-sub { margin-top: -0.2rem; }

/* ---------- browsable hourly chart ---------- */
.bt-win-controls { display: flex; align-items: center; flex-wrap: wrap; gap: 0.6rem; margin-bottom: 0.5rem; }
.bt-win-nav { display: flex; align-items: center; gap: 0.35rem; }
.bt-win-btn {
  width: 34px; height: 34px; flex: none; display: inline-flex;
  align-items: center; justify-content: center; padding: 0; cursor: pointer;
  color: var(--text-primary); background: var(--bg-card);
  border: 1px solid var(--border-strong); border-radius: 8px;
}
.bt-win-btn svg { width: 15px; height: 15px; }
.bt-win-btn:hover:not(:disabled) { border-color: var(--coral); color: var(--coral); }
.bt-win-btn:disabled { opacity: 0.35; cursor: default; }
.bt-win-label { font-size: 0.9rem; font-weight: 700; color: var(--text-primary); min-width: 11rem; font-variant-numeric: tabular-nums; }
.bt-win-len { margin-left: auto; font-size: 0.8rem; font-weight: 600; color: var(--text-secondary); display: inline-flex; align-items: center; gap: 0.4rem; }
.bt-win-len select {
  font: inherit; font-size: 0.84rem; font-weight: 600; padding: 0.35rem 0.5rem;
  border: 1px solid var(--border-strong); border-radius: 8px;
  background: var(--bg-card); color: var(--text-primary); cursor: pointer;
}
[data-theme="dark"] .bt-win-len select, [data-theme="dark"] .bt-win-btn { background: rgba(10, 10, 26, 0.65); }
.bt-win-pos { width: 100%; margin: 0 0 0.5rem; accent-color: var(--coral); }
#bt-week-wrap { position: relative; }
#bt-week { display: block; width: 100%; height: 300px; }
.bt-legend-toggle { gap: 0.45rem; margin-top: 0.6rem; }
.bt-leg-toggle {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font: inherit; font-size: 0.78rem; font-weight: 600; line-height: 1.2;
  padding: 0.35rem 0.7rem; cursor: pointer;
  color: var(--text-muted); background: var(--bg-card);
  border: 1px solid var(--border); border-radius: 8px;
  transition: color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease;
}
.bt-leg-toggle i { width: 14px; height: 3px; border-radius: 2px; display: inline-block; opacity: 0.35; }
.bt-leg-toggle[aria-pressed="true"] { color: var(--text-primary); border-color: var(--border-strong); }
.bt-leg-toggle[aria-pressed="true"] i { opacity: 1; }
.bt-leg-toggle:hover { border-color: var(--coral); }
[data-theme="dark"] .bt-leg-toggle { background: rgba(10, 10, 26, 0.45); }

/* ---------- summary table ---------- */
.bt-table-wrap { overflow-x: auto; }
table.bt-table { width: 100%; border-collapse: collapse; font-size: 0.86rem; min-width: 30rem; }
table.bt-table th, table.bt-table td { padding: 0.6rem 0.65rem; text-align: right; border-bottom: 1px solid var(--border); }
table.bt-table thead th { font-size: 0.8rem; font-weight: 700; color: var(--text-secondary); border-bottom-color: var(--border-strong); }
table.bt-table th:first-child, table.bt-table td:first-child { text-align: left; color: var(--text-secondary); font-weight: 600; }
table.bt-table td { color: var(--text-primary); font-variant-numeric: tabular-nums; }
table.bt-table tr.bt-row-net td { font-weight: 800; }
table.bt-table .bt-pos { color: var(--green); }
table.bt-table .bt-neg { color: var(--coral); }
.bt-rank {
  display: inline-block; padding: 0.2rem 0.45rem; border-radius: var(--bt-r-tag);
  font-size: 0.72rem; font-weight: 700;
}
.bt-rank-best { color: #0f7a35; background: rgba(26, 143, 63, 0.14); }
.bt-rank-worst { color: #c62828; background: rgba(198, 40, 40, 0.12); }
.bt-rank-mid { color: var(--text-muted); background: var(--surface-soft); }
[data-theme="dark"] .bt-rank-best { color: #00d4aa; background: rgba(0, 212, 170, 0.16); }
[data-theme="dark"] .bt-rank-worst { color: #ff6b6b; background: rgba(255, 107, 107, 0.16); }
table.bt-table .bt-col-key { display: inline-flex; align-items: center; gap: 0.4rem; }
table.bt-table .bt-col-key i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }

/* ---------- seasonal bills ---------- */
.bt-seasons { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem 2.2rem; }
.bt-season { min-width: 0; }
.bt-season-h { font-size: 0.95rem; font-weight: 600; color: var(--text-primary); margin: 0 0 0.15rem; }
.bt-season-big { font-size: 2rem; font-weight: 800; color: var(--text-primary); line-height: 1.1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.bt-season-big .bt-cur { font-size: 1rem; font-weight: 600; vertical-align: 0.55em; margin-right: 0.12rem; color: var(--text-secondary); }
.bt-season-sub { font-size: 0.76rem; color: var(--text-muted); margin: 0.1rem 0 0.7rem; }
.bt-bars { display: grid; gap: 1.05rem; }
.bt-bar-row { display: grid; grid-template-columns: 7rem minmax(0, 1fr); align-items: center; gap: 0.6rem; }
.bt-bar-label { font-size: 0.76rem; color: var(--text-secondary); line-height: 1.3; }
/* The option the tool is recommending, marked in the small print too. */
.bt-bar-row.is-best .bt-bar-label { color: var(--text-primary); font-weight: 700; }
.bt-bar-track { position: relative; height: 9px; border-radius: 3px; background: var(--border); }
.bt-bar-fill { position: absolute; inset: 0 auto 0 0; border-radius: 3px; min-width: 3px; transition: width 0.6s cubic-bezier(0.22, 1, 0.36, 1); }
.bt-bar-val { position: absolute; bottom: 100%; font-size: 0.76rem; font-weight: 700; color: var(--text-primary); white-space: nowrap; margin-bottom: 2px; transform: translateX(-100%); font-variant-numeric: tabular-nums; }

/* ---------- share row and fine print ---------- */
.bt-share-row { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1.2rem; }
/* The copy under the option cards pulls up against them: it belongs to the
   answer just read, not to the chart below it. The negative top offsets part
   of the cards' own bottom margin. */
.bt-share-row-top { margin: -0.9rem 0 1.6rem; }
.bt-fine-row { position: relative; display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem; margin-top: 1.1rem; padding-top: 0.9rem; border-top: 1px solid var(--border); font-size: 0.78rem; color: var(--text-muted); }
/* The small print rides beside the "i" button; the app buttons move out of
   this row entirely and close the tool underneath it. */
.bt-fine-row .tool-legal { flex: 1 1 14rem; min-width: 0; margin: 0; text-align: left; font-size: 0.74rem; }
/* Right-justified, to sit under the fine print rather than floating in the
   middle of it, and to match the solar tool's own download row. */
.bt-dl-row { display: flex; justify-content: flex-end; margin-top: 1.05rem; }
.bt-dl { display: flex; align-items: center; flex-wrap: wrap; justify-content: center; gap: 0.45rem; }
.bt-dl span { font-size: 0.8rem; color: var(--text-secondary); }
.bt-dl a { display: inline-flex; line-height: 0; }
.bt-dl img { height: 28px; width: auto; border-radius: 0; box-shadow: none; }
.bt-info-btn {
  flex: none; width: 24px; height: 24px; border-radius: 50%;
  border: 1px solid var(--border-strong); background: var(--bg-card);
  color: var(--text-secondary); font: italic 700 0.82rem Georgia, serif;
  cursor: pointer; line-height: 1; padding: 0;
}
.bt-info-btn:hover { border-color: var(--coral); color: var(--coral); }
.bt-info-tip {
  display: none; position: absolute; bottom: calc(100% + 10px); left: 0; right: 0;
  background: var(--bg-card); border: 1px solid var(--border-strong);
  border-radius: var(--r-media); box-shadow: var(--shadow-card);
  padding: 0.85rem 0.95rem; font-size: 0.78rem; color: var(--text-secondary);
  line-height: 1.55; z-index: 5; max-height: 70vh; overflow: auto;
}
.bt-info-tip::after { content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 12px; }
.bt-info-tip a { color: var(--coral); }
.bt-info-tip strong { color: var(--text-primary); }
.bt-info-tip p { margin: 0 0 0.55rem; }
.bt-info-tip p:last-child { margin-bottom: 0; }
#bt-info-btn:hover ~ .bt-info-tip,
#bt-info-btn:focus-visible ~ .bt-info-tip,
.bt-info-tip:hover,
.bt-info-tip:focus-within,
.bt-fine-row.open .bt-info-tip { display: block; }


/* ---------- layout: the flow beside the dashboard ----------
   Wide screens put the numbers-so-far panel at the right, pinned as the
   page scrolls. Narrow ones fold it into a strip under the site header. */
.bt-body { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 1.4rem; align-items: start; }
.bt-main { min-width: 0; }
.bt-dash { position: sticky; top: var(--bt-sticky-top, 84px); min-width: 0; }
.bt-dash-toggle { display: none; }
.bt-dash-body { display: grid; gap: 0.6rem; }
.bt-dash-title { margin: 0 0 0.1rem; font-size: 0.8rem; font-weight: 700; color: var(--text-muted); letter-spacing: 0.01em; }
.bt-dash-empty { margin: 0; font-size: 0.86rem; line-height: 1.5; color: var(--text-secondary); padding: 0.9rem 1rem; border: 1px dashed var(--border-strong); border-radius: var(--r-media); }
.bt-dash-empty[hidden] { display: none; }
.bt-dash-card {
  padding: 0.85rem 0.95rem 0.9rem; border: 1px solid var(--border); border-radius: var(--r-media);
  background: var(--surface-soft);
}
[data-theme="dark"] .bt-dash-card { background: rgba(10, 10, 26, 0.35); }
.bt-dash-card[hidden] { display: none; }
.bt-dash-card.bt-dash-in { animation: bt-rise 0.5s cubic-bezier(0.22, 1, 0.36, 1) both; }
.bt-dash-card h5 { margin: 0 0 0.5rem; font-size: 0.82rem; font-weight: 700; color: var(--text-primary); display: flex; align-items: center; gap: 0.45rem; }
.bt-dash-card h5 .bt-ico { width: 16px; height: 16px; }
.bt-dash-big { font-size: 1.45rem; font-weight: 800; letter-spacing: -0.02em; line-height: 1.1; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.bt-dash-big small { display: block; font-size: 0.78rem; font-weight: 600; color: var(--text-secondary); letter-spacing: 0; margin-top: 0.1rem; }
.bt-dash-sub { font-size: 0.78rem; color: var(--text-secondary); line-height: 1.4; margin-top: 0.1rem; }
.bt-dash-p { margin: 0.55rem 0 0; font-size: 0.78rem; line-height: 1.5; color: var(--text-secondary); }
.bt-dash-p:empty { display: none; }
.bt-dash-p strong { color: var(--text-primary); font-weight: 700; }
.bt-dash-money { color: var(--green); font-weight: 700; }
.bt-dash-canvas { display: block; width: 100%; height: 64px; margin-bottom: 0.45rem; }
.bt-dash-canvas-tall { height: 96px; }
.bt-dash-gauge { position: relative; height: 8px; border-radius: 3px; background: var(--border); margin-top: 0.55rem; overflow: hidden; }
.bt-dash-gauge i { position: absolute; inset: 0 auto 0 0; width: 0; border-radius: 3px; background: var(--bt-amber); transition: width 0.6s cubic-bezier(0.22, 1, 0.36, 1); }
.bt-dash-card-answer { border-color: var(--chip-border); background: var(--chip-bg); }
/* Reassurance, not fine print: a green-tinted note at the top of the column
   saying the household answers never leave the browser. */
.bt-privacy {
  display: flex; align-items: flex-start; gap: 0.5rem;
  margin: 0 0 0.15rem !important;
  padding: 0.7rem 0.8rem;
  border: 1px solid rgba(26, 143, 63, 0.28); border-radius: var(--r-media);
  background: rgba(26, 143, 63, 0.08);
  font-size: 0.76rem !important; line-height: 1.5;
  color: #1a7a35 !important;
}
.bt-privacy svg { width: 15px; height: 15px; flex: none; margin-top: 1px; }
[data-theme="dark"] .bt-privacy {
  border-color: rgba(0, 212, 170, 0.3);
  background: rgba(0, 212, 170, 0.1);
  color: #6fe6c9 !important;
}
.bt-dash-card-answer .bt-dash-big { font-size: 1.1rem; line-height: 1.25; }
.bt-dash-strip { display: flex; gap: 0.8rem; min-width: 0; flex: 1 1 auto; overflow: hidden; }
.bt-dash-strip-item { display: inline-flex; flex-direction: column; min-width: 0; white-space: nowrap; }
.bt-dash-strip-item:empty { display: none; }
.bt-dash-strip-item b { font-size: 0.92rem; font-weight: 800; color: var(--text-primary); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.bt-dash-strip-item span { font-size: 0.66rem; color: var(--text-muted); line-height: 1.2; }

@media (max-width: 899px) {
  /* The panel moves above the flow and pins under the site header. */
  .bt-body { display: flex; flex-direction: column; align-items: stretch; gap: 0; }
  .bt-dash { order: -1; position: sticky; top: var(--bt-sticky-top, 0px); z-index: 15; margin: 0 0 0.8rem; }
  .bt-dash-toggle {
    display: flex; align-items: center; gap: 0.6rem; width: 100%;
    font: inherit; text-align: left; cursor: pointer; padding: 0.55rem 0.8rem; min-height: 50px;
    color: var(--text-primary); background: var(--bg-card); border: 1px solid var(--border-strong);
    border-radius: var(--r-media); box-shadow: var(--shadow-card);
  }
  .bt-dash-toggle svg { width: 18px; height: 18px; flex: none; color: var(--text-muted); transition: transform 0.22s ease; }
  .bt-dash-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }
  .bt-dash-toggle .bt-dash-strip:empty::before, .bt-dash-strip-item:first-child:empty ~ .bt-dash-strip-item:empty { content: none; }
  [data-theme="dark"] .bt-dash-toggle { background: #12122a; }
  .bt-dash-body {
    display: none; margin-top: 0.4rem; padding: 0.7rem; max-height: min(70vh, 560px); overflow: auto;
    background: var(--bg-card); border: 1px solid var(--border-strong); border-radius: var(--r-media); box-shadow: var(--shadow-card);
  }
  [data-theme="dark"] .bt-dash-body { background: #12122a; }
  .bt-dash.open .bt-dash-body { display: grid; }
  .bt-dash-title { display: none; }
}

/* ---------- the estimate box ---------- */
.bt-use { margin-top: 1.1rem; padding: 0.85rem 0.95rem 0.9rem; border: 1px solid var(--border); border-radius: var(--r-media); background: var(--surface-soft); }
.bt-use-top { display: flex; align-items: baseline; justify-content: space-between; gap: 0.6rem 1rem; flex-wrap: wrap; }
.bt-use-fig { display: flex; align-items: baseline; gap: 0.4rem; flex-wrap: wrap; }
.bt-use-big { font-size: 1.6rem; font-weight: 800; letter-spacing: -0.02em; line-height: 1.05; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.bt-use-unit { font-size: 0.84rem; color: var(--text-secondary); }
/* Being worked out: the number gives way to a spinner and the bar dims. */
.bt-use.working .bt-use-big { display: none; }
.bt-use.working .bt-use-fig::before {
  content: ""; display: block; align-self: center; width: 20px; height: 20px; border-radius: 50%; box-sizing: border-box;
  border: 3px solid var(--coral); border-top-color: transparent; animation: bt-spin 0.8s linear infinite;
}
.bt-use.working .bt-use-bar, .bt-use.working .bt-use-legend { opacity: 0.35; transition: opacity 0.2s ease; }
/* A card being worked out spins where its number goes rather than showing a
   figure the left is still calculating. The number keeps its place in the
   flow, just invisible, so the card never changes height. */
.bt-dash-card.working .bt-dash-big { position: relative; color: transparent; }
.bt-dash-card.working .bt-dash-big::after {
  content: ""; position: absolute; left: 0; top: 3px;
  width: 18px; height: 18px; border-radius: 50%; box-sizing: border-box;
  border: 3px solid var(--coral); border-top-color: transparent;
  animation: bt-spin 0.8s linear infinite;
}
.bt-dash-card.working .bt-use-bar, .bt-dash-card.working .bt-use-legend,
.bt-dash-card.working .bt-dash-sub, .bt-dash-card.working p { opacity: 0.35; transition: opacity 0.2s ease; }
@media (prefers-reduced-motion: reduce) {
  .bt-dash-card.working .bt-dash-big::after { animation: none; border-top-color: var(--coral); }
}
.bt-link { font: inherit; font-size: 0.82rem; font-weight: 600; color: var(--coral); background: none; border: 0; padding: 0.2rem 0; cursor: pointer; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(255, 107, 71, 0.4); }
.bt-link:hover { text-decoration-color: currentColor; }
.bt-use-bar { display: flex; height: 12px; border-radius: 4px; overflow: hidden; margin-top: 0.7rem; background: var(--border); }
.bt-use-bar i { display: block; height: 100%; transition: width 0.5s cubic-bezier(0.22, 1, 0.36, 1); }
.bt-use-bar i + i { margin-left: 2px; }
.bt-use-bar-sm { height: 9px; margin-top: 0.6rem; }
.bt-use-legend { display: flex; flex-wrap: wrap; gap: 0.3rem 0.9rem; margin-top: 0.5rem; }
.bt-use-legend span { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.76rem; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.bt-use-legend i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; flex: none; }
.bt-use-legend b { color: var(--text-primary); font-weight: 700; }
.bt-use-legend-sm span { font-size: 0.72rem; }
.bt-use-legend-sm { gap: 0.2rem 0.7rem; }
.bt-use-own-wrap { margin-top: 0.8rem; padding-top: 0.8rem; border-top: 1px solid var(--border); max-width: 22rem; }
.bt-use-own-wrap[hidden] { display: none; }
.bt-group-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.9rem 1.2rem; }
.bt-pills-tight .bt-pill { flex: 0 1 auto; }

/* ---------- time of use ---------- */
.bt-tou { margin-top: 0.9rem; }
.bt-tou[hidden] { display: none; }
#bt-price-field[hidden] { display: none; }
.bt-hours { display: flex; align-items: center; gap: 0.45rem; }
.bt-hours select { flex: 1 1 auto; min-width: 0; }

/* ---------- what a tile is worth ---------- */
.bt-appl-val { font-size: 0.8rem; font-weight: 700; color: var(--green); font-variant-numeric: tabular-nums; line-height: 1.25; }
.bt-appl:not(.on) .bt-appl-val { color: var(--text-muted); font-weight: 600; }
.bt-appl-val:empty { display: none; }
.bt-appl-note { display: block; padding: 0 0.75rem 0.55rem 3.15rem; font-size: 0.68rem; line-height: 1.3; color: var(--text-muted); }
.bt-appl-note:empty { display: none; }


/* While a run is queued or under way the cards say so with a spinner rather
   than a checklist. The numbers arrive as soon as the model can produce them;
   a staged tick list would only be pretending they take longer. The figures
   stay on screen and dim, so the card never empties out. */
.bt-dash.bt-busy .bt-dash-card h5::after {
  content: ""; flex: none; margin-left: auto; width: 12px; height: 12px;
  border: 2px solid var(--border-strong); border-top-color: var(--coral);
  border-radius: 50%; animation: bt-spin 0.7s linear infinite;
}
@keyframes bt-spin { to { transform: rotate(360deg); } }
.bt-dash.bt-busy .bt-dash-card > :not(h5) { opacity: 0.55; transition: opacity 0.2s ease; }
@media (prefers-reduced-motion: reduce) {
  .bt-dash.bt-busy .bt-dash-card h5::after { animation: none; border-top-color: var(--coral); }
}
.bt-progress-results { margin: 1.4rem 0 0; padding-top: 1.4rem; border-top: 1px solid var(--border); }
.bt-progress-results[hidden] { display: none; }

/* ---------- motion off ---------- */
@media (prefers-reduced-motion: reduce) {
  .bt-copy-btn.bt-copied, .bt-appl.bt-landed .bt-appl-tick,
  .bt-results.bt-reveal > *, .bt-search-list, .bt-dash-card.bt-dash-in { animation: none; }
  .bt-step-body, .bt-step-tick, .bt-appl, .bt-bar-fill, .bt-btn, .bt-pill,
  .bt-path.bt-shuffle, .bt-path.bt-shuffle .bt-path-tag { transition: none; }
  .bt-appl-tick svg path { transition: none; }
  .bt-progress-steps li.doing .bt-dot { animation: none; border-top-color: var(--coral); }
}

/* ---------- small screens ---------- */
@media (max-width: 720px) {
  .bt-seasons { grid-template-columns: 1fr; }
  .bt-paths { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .bt-tool { padding: 1rem 0.9rem 0.9rem; }
  /* Once the badges wrap onto their own lines, centred reads better than
     a ragged right edge. */
  .bt-dl-row { justify-content: center; }
  .bt-group-pair { grid-template-columns: 1fr; }
  /* 16px stops iOS zooming the page when a box is tapped. */
  .bt-search-box input, .bt-field input[type="number"], .bt-field select, .bt-win-len select { font-size: 16px; }
  .bt-head-text h3 { font-size: 1.2rem; }
  .bt-head { flex-wrap: wrap; }
  .bt-head-actions { margin-left: 0; width: 100%; }
  .bt-share-menu { right: auto; left: 0; }
  .bt-logo { width: 40px; height: 40px; border-radius: 11px; }
  .bt-step-head { padding: 0.85rem 0.85rem; gap: 0.65rem; }
  .bt-step-icon { width: 32px; height: 32px; border-radius: 10px; }
  .bt-step-icon svg { width: 18px; height: 18px; }
  .bt-step-inner { padding: 0 0.85rem; }
  .bt-step-inner::after { height: 0.85rem; }
  .bt-step-q { font-size: 0.96rem; }
  .bt-search { flex-wrap: wrap; }
  .bt-btn-locate { flex: 1 1 100%; }
  .bt-appl-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bt-step-nav .bt-btn { width: 100%; }
  #bt-map { height: 240px; }
  #bt-chart { height: 240px; }
  #bt-week { height: 250px; }
  .bt-win-len { margin-left: 0; }
  .bt-win-label { min-width: 0; font-size: 0.84rem; }
  .bt-stats { grid-template-columns: 1fr; }
  .bt-paths { grid-template-columns: 1fr; }
  .bt-verdict h4 { font-size: 1.25rem; }
  .bt-season-big { font-size: 1.75rem; }
  .bt-bar-row { grid-template-columns: 5.6rem minmax(0, 1fr); }
  .bt-share-row .bt-btn { flex: 1 1 auto; }
}
