:root {
  /* Text-safe green (>=4.5:1 on white) so small links/labels pass WCAG AA;
     the large hero headline and borders read fine too. */
  --accent: #15803d;
  --accent-ink: #052e16;
  --worth: #15803d;
  --close: #b45309;
  --gas: #dc2626;

  --bg: #eef2f6;
  --card: #ffffff;
  --card-2: #f8fafc;
  --text: #0f172a;
  --muted: #5b6a7d;
  --line: #e2e8f0;
  --field: #f1f5f9;

  --radius: 18px;
  --radius-sm: 12px;
  --shadow: 0 6px 24px rgba(2, 6, 23, 0.08);
  --shadow-sm: 0 2px 8px rgba(2, 6, 23, 0.06);

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --bg: #070b14;
    --card: #111827;
    --card-2: #0b1120;
    --text: #e5e7eb;
    --muted: #94a3b8;
    --line: #1f2937;
    --field: #1a2436;
    /* Lighter accents so green/amber pass contrast on the dark surfaces. */
    --accent: #22c55e;
    --worth: #22c55e;
    --close: #f59e0b;
    --shadow: 0 6px 28px rgba(0, 0, 0, 0.5);
    --shadow-sm: 0 2px 10px rgba(0, 0, 0, 0.4);
  }
}

:root[data-theme="dark"] {
  --bg: #070b14;
  --card: #111827;
  --card-2: #0b1120;
  --text: #e5e7eb;
  --muted: #94a3b8;
  --line: #1f2937;
  --field: #1a2436;
  /* Lighter accents so green/amber pass contrast on the dark surfaces. */
  --accent: #22c55e;
  --worth: #22c55e;
  --close: #f59e0b;
  --shadow: 0 6px 28px rgba(0, 0, 0, 0.5);
  --shadow-sm: 0 2px 10px rgba(0, 0, 0, 0.4);
}

* { box-sizing: border-box; }

/* Ensure the hidden attribute always wins over component display rules. */
[hidden] { display: none !important; }

/* Honor the OS "reduce motion" setting: drop transitions/animations and the
   sticky verdict's smooth color fades for users prone to motion sickness. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
}

body {
  font-size: 16px;
  line-height: 1.4;
  /* Floor the layout at a phone-sized width. Below this (e.g. dragging a
     desktop window very narrow) a horizontal scrollbar appears instead of the
     inputs and buttons squeezing until text spills out of them. */
  min-width: 320px;
}

.app {
  max-width: 480px;
  margin: 0 auto;
  padding: 16px 16px calc(24px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* Desktop: keep the phone-first column, but center it fluidly with no magic
   height numbers so it adapts to any content size, and dress the page so it
   isn't a lonely strip on an empty canvas. `safe center` centers when it fits
   and falls back to top-aligned scrolling when the content is taller than the
   viewport (prevents the classic flexbox top-clipping). */
@media (min-width: 700px) {
  body {
    min-height: 100dvh;
    display: flex;
    justify-content: center;
    align-items: center;
    align-items: safe center;
    padding: 40px 16px;
    background:
      radial-gradient(900px 520px at 50% -8%, color-mix(in srgb, var(--accent) 10%, transparent), transparent 70%),
      var(--bg);
  }
  .app {
    width: 468px;
    max-width: 468px;
    padding: 0;
    gap: 16px;
  }
}

.app__head {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 6px 4px 0;
}
.app__head-text { min-width: 0; }
/* One cohesive control cluster instead of three loose pills, sitting as tidy
   chrome above the hero so the title/tagline reads as a clean block. The wrapper
   is a positioning context (position: relative) so the currency menu can anchor
   under the cluster; the border/overflow/segment styling lives on the inner
   .control-cluster element. Keeping the menu outside .control-cluster matters
   because it uses overflow: hidden to clip its rounded corners, which would
   otherwise clip an absolutely-positioned dropdown. */
.app__head-actions {
  align-self: flex-end;
  position: relative;
}
.control-cluster {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
/* Secondary chrome: sized down a touch so the cluster reads as options rather
   than a headline feature. Still comfortably above the WCAG AA 24px target. */
.control-cluster > .pill {
  min-height: 36px;
  padding: 5px 12px;
  font-size: 12px;
  border: 0;
  border-radius: 0;
  background-color: transparent;
  box-shadow: none;
}
.control-cluster > .pill + .pill { border-left: 1px solid var(--line); }
.control-cluster > .pill:active {
  transform: none;
  background-color: color-mix(in srgb, var(--text) 8%, transparent);
}
.control-cluster > .pill:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* Theme icon and currency trigger: centered glyphs, sized to match the row. */
.control-cluster > #themeToggle { min-width: 36px; padding: 5px 10px; font-size: 13px; }
#currencyBtn { min-width: 36px; font-size: 14px; }

.app__title {
  font-size: 24px;
  line-height: 1.2;
  font-weight: 800;
  letter-spacing: -0.02em;
  margin: 0;
}
.app__tagline {
  margin: 3px 0 0;
  font-size: 13px;
  line-height: 1.35;
  font-weight: 500;
  color: var(--muted);
}

.pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--text);
  border-radius: 999px;
  padding: 7px 14px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
}
.pill:active { transform: scale(0.97); }
.pill--icon { min-width: 44px; padding: 7px 11px; font-size: 15px; line-height: 1; }

.card {
  background: var(--card);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 18px;
}
.card__title { margin: 0 0 4px; font-size: 15px; font-weight: 800; letter-spacing: -0.01em; }

/* --- Result hero --- */
.result {
  text-align: center;
  padding: 22px 18px 26px;
  position: relative;
  overflow: hidden;
  /* Solid edge in the verdict color so the card reads as a distinct object,
     especially while floating (sticky) over the content scrolling beneath. */
  border: 2px solid var(--accent);
  transition: background 0.35s ease, border-color 0.35s ease;
}
/* v2 experiment: keep the verdict pinned to the top of the viewport while you
   scroll down into the optional fee / charge-time sections, so the answer is
   always on screen. The dock does the pinning and paints the page background
   across the small top gap so scrolling content can't peek through above the
   card. Remove .result-dock (and unwrap the card) to drop the behavior. */
.result-dock {
  position: sticky;
  top: 0;
  z-index: 20;
  padding-top: 8px;
  background: var(--bg);
}
#resultCard {
  /* Lift it off the page so the colored edge stands out when floating. */
  box-shadow: 0 8px 22px color-mix(in srgb, var(--accent) 22%, rgba(2, 6, 23, 0.14));
}
.result::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 12%, transparent), transparent 60%);
  pointer-events: none;
  transition: background 0.35s ease;
}
.result[data-verdict="worth"] { --accent: var(--worth); }
.result[data-verdict="close"] { --accent: var(--close); }
.result[data-verdict="gas"]   { --accent: var(--gas); }
.result[data-verdict="none"]  { --accent: var(--muted); }

/* Car tile: summary chip + inline picker */
.car-summary { display: inline-flex; align-items: center; gap: 10px; }
.car-summary__icon { font-size: 20px; }
.car-summary__name {
  font-size: 16px;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--text);
}

/* Info (i) affordance next to a field label */
.field-label-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}
.field-label-row label { margin: 0; }
/* Inside a two-column row the label-row's bottom margin would push its input
   lower than the plain-label column's input, so drop it to keep them aligned. */
.field-row .field-label-row { margin-bottom: 0; }
.info-btn {
  position: relative;
  width: 18px;
  height: 18px;
  flex: none;
  border-radius: 50%;
  border: none;
  background: var(--muted);
  color: var(--card);
  font-size: 11px;
  font-weight: 800;
  font-style: italic;
  font-family: Georgia, "Times New Roman", serif;
  line-height: 18px;
  text-align: center;
  cursor: pointer;
  padding: 0;
}
.info-btn:active { transform: scale(0.9); }
/* Invisible 44x44 hit area so the tiny "i" stays tappable (WCAG target size). */
.info-btn::after { content: ""; position: absolute; inset: -13px; }
/* The note is a floating popover, not an in-flow block. On desktop the whole
   app column is vertically centered (`align-items: safe center`), so an in-flow
   note that grows the page height would shift the column up, slide the (i) out
   from under the cursor, hide the note, and flicker forever. Positioning it
   absolutely (anchored to the label row so it sits right under the title/(i))
   keeps page height constant, so the trigger never moves. */
.field-label-row:has(> .info-note) { position: relative; }
.info-note {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 20;
  margin-top: 6px;
  padding: 10px 12px;
  background: var(--card-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
}
/* The charge-power label sits in a half-width column; break its note out to
   span the full two-column row so the text isn't crammed. */
#powerInfoNote { right: auto; width: calc(200% + 12px); }
.info-note a { color: var(--accent); font-weight: 700; }

/* Searchable car combobox */
.combo { position: relative; }
.combo__results {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 30;
  margin: 0;
  padding: 4px;
  list-style: none;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  max-height: 46vh;
  overflow-y: auto;
}
.combo__item {
  padding: 12px;
  border-radius: 10px;
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
}
.combo__item:hover { background: var(--field); }
.combo__item--custom { color: var(--accent); }
.combo__none { padding: 12px; font-size: 13px; color: var(--muted); }

/* Currency picker menu: reuses .combo__results / .combo__item, but anchors to
   the right-aligned cluster and lays each row out as an aligned symbol column
   plus a name so the ragged symbols line up. min-width keeps it off the left
   viewport edge; right: 0 keeps it under the right-aligned trigger. */
.currency-menu {
  right: 0;
  left: auto;
  min-width: 180px;
}
.currency-item {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  box-sizing: border-box;
}
.currency-item__sym {
  flex: 0 0 auto;
  width: 28px;
  text-align: center;
  font-weight: 700;
}
.currency-item__name { color: var(--muted); font-weight: 600; }
.currency-item[aria-selected="true"] { background: var(--field); color: var(--accent); }
.currency-item[aria-selected="true"] .currency-item__name { color: var(--accent); }
.currency-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* Units picker menu: same right-anchored dropdown pattern as the currency menu
   (sibling of .control-cluster so it isn't clipped by its overflow: hidden), but
   each row is a single named label (e.g. "US (mpg, gallon)"). min-width keeps it
   off the left viewport edge on narrow screens. */
.unit-menu { min-width: 190px; }
.unit-item {
  display: flex;
  align-items: center;
  min-height: 44px;
  box-sizing: border-box;
  font-size: 14px;
}
.unit-item[aria-selected="true"] { background: var(--field); color: var(--accent); }
.unit-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* "Adjust numbers" mini-disclosure inside the car tile */
.tweak { margin-top: 6px; }
.tweak > summary {
  list-style: none;
  cursor: pointer;
  font-size: 14px;
  font-weight: 700;
  color: var(--accent);
  padding: 4px 0;
}
.tweak > summary::-webkit-details-marker { display: none; }
.tweak > summary::after { content: " +"; color: var(--muted); }
.tweak[open] > summary::after { content: " −"; }
.tweak__body { padding-top: 8px; }
/* Energy-mode disclosure as a lightweight accent accordion: a leading chevron
   that rotates open. Colored so it stands out from the surrounding hints,
   without a box, so it never reads as an input to fill. */
.tweak--muted > summary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--accent);
  font-weight: 700;
  font-size: 14px;
  padding: 6px 0;
}
.tweak--muted > summary::after,
.tweak--muted[open] > summary::after { content: none; }
.tweak--muted > summary::before {
  content: "\25B8";
  color: var(--accent);
  font-size: 12px;
  display: inline-block;
  transition: transform 0.15s;
}
.tweak--muted[open] > summary::before { transform: rotate(90deg); }

.result__label {
  margin: 0;
  color: var(--muted);
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  position: relative;
  z-index: 1;
}
.result__value {
  margin: 4px 0 8px;
  font-size: 54px;
  font-weight: 800;
  letter-spacing: -0.03em;
  color: var(--accent);
  line-height: 1;
  position: relative;
  z-index: 1;
}
.result__unit {
  font-size: 22px;
  font-weight: 700;
  color: var(--muted);
  margin-left: 2px;
}
.result__verdict {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  position: relative;
  z-index: 1;
}
.result__headline {
  margin: 8px 0 8px;
  font-size: 40px;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.05;
  color: var(--accent);
  position: relative;
  z-index: 1;
  transition: color 0.25s ease;
}
.result__sub {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  position: relative;
  z-index: 1;
}
.result__detail {
  margin: 6px 0 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  position: relative;
  z-index: 1;
}
.result__time {
  margin: 10px 0 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  position: relative;
  z-index: 1;
}
/* Best-value "smart tip": a distinct green block under the yes/no verdict that
   surfaces the cheaper short-charge without contradicting the headline. Uses
   --worth directly so it stays green even when the verdict accent is red. */
.result__tip {
  margin: 14px 0 0;
  padding: 11px 13px;
  border-radius: var(--radius-sm);
  text-align: left;
  background: color-mix(in srgb, var(--worth) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--worth) 45%, transparent);
  position: relative;
  z-index: 1;
}
.result__tip-lead { margin: 0; font-size: 14px; font-weight: 800; color: var(--worth); }
.result__tip-sub { margin: 3px 0 0; font-size: 13px; font-weight: 600; color: var(--text); }

/* --- Fields --- */
.field { display: flex; flex-direction: column; gap: 6px; }
.field + .field { margin-top: 14px; }
.inputs .field:first-child { margin-top: 0; }

label {
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
}

input[type="text"],
input[type="number"] {
  width: 100%;
  border: 1px solid var(--line);
  background: var(--field);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 13px 14px;
  font-size: 17px;
  font-weight: 600;
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}
input[type="text"]:focus,
input[type="number"]:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}
/* Numeric fields: strip spinner arrows; positivity is enforced via min=0. */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type="number"] { -moz-appearance: textfield; appearance: textfield; }

.input-money { position: relative; }
.input-money__sym {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--muted);
  font-weight: 700;
  font-size: 17px;
  pointer-events: none;
}
.input-money input { padding-left: 30px; }
.input-money.has-suffix input { padding-right: 82px; }
.input-money__suffix {
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--muted);
  font-weight: 600;
  font-size: 14px;
  pointer-events: none;
}

.field-row { display: flex; gap: 12px; }
.field-row .field { flex: 1; margin-top: 0; }
/* The charge-power row sits right below the preset buttons. The generic
   `.field + .field` rhythm doesn't match `.field + .field-row`, leaving zero
   gap, which lets the info button's tap target overlap the presets above. */
.field:has(.presets) + .field-row { margin-top: 14px; }
/* A hint paragraph followed straight by a field (e.g. the AC-charging note
   above "Battery now") otherwise butts right up against the slider label;
   restore the normal field rhythm. Lead hints already carry their own gap. */
#advanced .hint:not(.hint--lead) + .field { margin-top: 14px; }

.hint {
  margin: 12px 0 0;
  font-size: 13px;
  color: var(--muted);
}
.hint--lead { margin: 0 0 14px; }
.label-opt { font-weight: 500; color: var(--muted); }

/* --- Time-of-day (TOU) editor --- */
.check {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
}
.check input { width: 20px; height: 20px; accent-color: var(--accent); flex: none; }
.tou-rows { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 8px; }
/* An empty editor (no rows added yet) shouldn't reserve vertical space; that
   dead gap pushes the "+ Add" button away from its label and makes each fee
   block look airy. Removing it from layout keeps the label right above the
   add button; it reappears the moment a row is added. */
.tou-rows:empty { display: none; }
/* Keep the multi-control schedule rows on a single line: the rate field is
   the only flexible item, so it shrinks to absorb narrow widths while the
   "after N hr" group, unit and delete button stay put on one row. */
.tou-row { display: flex; align-items: center; gap: 6px; flex-wrap: nowrap; }
.tou-time {
  flex: 0 0 auto;
  border: 1px solid var(--line);
  background: var(--field);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 11px 10px;
  font-size: 15px;
  font-weight: 600;
}
/* The rate field holds a currency value. On a phone the schedule row is
   cramped, so the field keeps a compact base width (packed left with the small
   hour/unit controls) instead of stretching wide and dwarfing them. It can
   still shrink toward its minimum at the 320px floor. Once the column has room
   (>=480px, see the media query below) the field grows to fill the row so the
   tiers line up edge-to-edge with the full-width Service fee field above. */
.tou-rate-wrap { flex: 0 1 88px; min-width: 60px; }
.tou-del {
  flex: 0 0 auto;
  width: 40px;
  height: 44px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--card-2);
  color: var(--muted);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
.tou-del:active { transform: scale(0.96); }
.tou-add { display: inline-block; margin-top: 2px; }
.tf-unit { flex: 0 0 auto; margin-left: -2px; font-size: 14px; font-weight: 600; color: var(--muted); }
.result__tou { color: var(--text); }

/* Charger fees: three distinct fee types (service / time / tax). A hairline
   divider reads as separate sections without the tall whitespace that made
   them feel like one long block. The label-row margin is dropped so the field's
   own 6px gap sets the label→controls rhythm. */
#chargerFees .field-label-row { margin-bottom: 0; }
#chargerFees .disclosure__body .field + .field {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}

/* Tax rows: an optional name plus a percentage, summed across rows. */
.tax-label { flex: 1 1 120px; min-width: 0; font-size: 15px; padding: 11px 12px; }
.tax-pct-wrap { flex: 0 0 96px; }
.tax-pct-wrap.input-money input { padding-left: 12px; padding-right: 34px; }
.tax-pct-wrap .input-money__suffix { font-size: 15px; }

/* Exclusive pricing-mode selector */
.segmented {
  display: flex;
  gap: 4px;
  background: var(--field);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 4px;
}
.segmented > label { flex: 1; position: relative; margin: 0; }
.segmented input { position: absolute; opacity: 0; pointer-events: none; }
.segmented span {
  display: block;
  text-align: center;
  padding: 9px 4px;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 700;
  color: var(--muted);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.segmented input:checked + span {
  background: var(--card);
  color: var(--accent);
  box-shadow: var(--shadow-sm);
}
/* Dim only the flat-rate input when a schedule mode is active, not the mode
   selector / editors that now live in the same field. */
.field.is-disabled > label,
.field.is-disabled > .input-money { opacity: 0.5; }
.field.is-disabled > .input-money input { cursor: not-allowed; }

/* Duration-tier rows */
.dur-after {
  display: flex;
  align-items: center;
  gap: 5px;
  flex: 0 0 auto;
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
  white-space: nowrap;
}
.dur-min {
  width: 54px;
  flex: 0 0 54px;
  border: 1px solid var(--line);
  background: var(--field);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 11px 8px;
  font-size: 15px;
  font-weight: 600;
  text-align: center;
}
.row-unit-wrap { position: relative; flex: 0 0 auto; display: inline-flex; }
.row-unit {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  border: 1px solid var(--line);
  background: var(--field);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 11px 7px;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.row-unit__label {
  display: inline-block;
  min-width: 27px; /* fit the widest option ("min") so the button never reflows */
  text-align: center;
}
.row-unit__caret { font-size: 9px; color: var(--muted); }
.row-unit-menu { left: 0; right: auto; min-width: 76px; }
.row-unit-item { padding: 10px 12px; }

/* --- Compare box --- */
.compare {
  margin-top: 14px;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  font-weight: 600;
  background: var(--card-2);
}
.compare__dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--muted);
  flex: none;
}
.compare[data-verdict="worth"] { background: color-mix(in srgb, var(--worth) 14%, var(--card-2)); color: var(--worth); }
.compare[data-verdict="worth"] .compare__dot { background: var(--worth); }
.compare[data-verdict="close"] { background: color-mix(in srgb, var(--close) 16%, var(--card-2)); color: color-mix(in srgb, var(--close) 80%, var(--text)); }
.compare[data-verdict="close"] .compare__dot { background: var(--close); }
.compare[data-verdict="gas"] { background: color-mix(in srgb, var(--gas) 14%, var(--card-2)); color: var(--gas); }
.compare[data-verdict="gas"] .compare__dot { background: var(--gas); }

/* --- Charger-speed presets --- */
.sublabel { margin: 0 0 6px; font-size: 14px; font-weight: 600; color: var(--muted); }
.presets { display: flex; gap: 8px; }
.preset {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  border: 1px solid var(--line);
  background: var(--field);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 11px 8px;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.preset:active { transform: scale(0.98); }
.preset.is-active {
  border-color: var(--accent);
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, var(--field));
}

/* --- Disclosure --- */
.disclosure { padding: 0; }
.disclosure > summary {
  list-style: none;
  cursor: pointer;
  padding: 16px 18px;
  font-size: 15px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.disclosure > summary::-webkit-details-marker { display: none; }
.disclosure > summary::after {
  content: "＋";
  color: var(--muted);
  font-weight: 700;
}
.disclosure[open] > summary::after { content: "－"; }
.disclosure__body { padding: 0 18px 18px; }

/* --- Range sliders --- */
input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 8px;
  border-radius: 999px;
  background: var(--field);
  outline: none;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--accent);
  border: 3px solid var(--card);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
}
input[type="range"]::-moz-range-thumb {
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--accent);
  border: 3px solid var(--card);
  cursor: pointer;
}
output { font-weight: 800; color: var(--text); }

/* --- Advanced result --- */
.advanced-result {
  margin-top: 16px;
  padding: 14px;
  border-radius: var(--radius-sm);
  background: var(--card-2);
}
.advanced-result__title { margin: 0 0 8px; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
.advanced-result__row {
  display: flex;
  justify-content: space-between;
  padding: 5px 0;
  font-size: 14px;
  color: var(--muted);
}
.advanced-result__row strong { color: var(--text); font-size: 15px; }
.advanced-result__verdict {
  margin: 10px 0 0;
  font-size: 14px;
  font-weight: 700;
}

/* --- Footer --- */
.app__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 6px 0;
}
.app__foot-note { font-size: 12px; color: var(--muted); }
.app__foot-right { display: flex; align-items: center; gap: 12px; }
.app__foot-gh {
  display: inline-flex;
  color: var(--muted);
  transition: color 0.15s;
}
.app__foot-gh:hover { color: var(--text); }
.app__foot-gh:active { transform: scale(0.92); }
.link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  background: none;
  border: none;
  color: var(--accent);
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
  padding: 0;
}

/* --- Dialog --- */
.dialog {
  border: none;
  border-radius: var(--radius);
  padding: 0;
  max-width: 420px;
  width: calc(100% - 32px);
  background: var(--card);
  color: var(--text);
  box-shadow: var(--shadow);
}
.dialog::backdrop { background: rgba(2, 6, 23, 0.5); backdrop-filter: blur(2px); }
.dialog__inner { padding: 18px; }
.dialog__title { margin: 0 0 12px; font-size: 18px; font-weight: 800; }
.dialog__hint { margin: 0 0 12px; font-size: 13px; color: var(--muted); }
.dialog__select {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--field);
  color: var(--text);
  padding: 6px;
  font-size: 15px;
  outline: none;
}
.dialog__select option { padding: 8px 6px; }
.dialog__actions { display: flex; gap: 10px; margin-top: 14px; }
.btn {
  flex: 1;
  border-radius: var(--radius-sm);
  padding: 13px;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  border: 1px solid var(--line);
}
.btn--ghost { background: var(--card-2); color: var(--text); }
.btn--primary { background: var(--accent); color: #fff; border-color: var(--accent); }
.btn:active { transform: scale(0.98); }

/* Update toast - a small, dismissable "new version available" prompt pinned to
   the bottom. It never reloads on its own; the user taps Refresh when ready. */
.toast {
  position: fixed;
  left: 50%;
  bottom: max(16px, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 1000;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: calc(100% - 24px);
  padding: 6px 8px 6px 16px;
  background: var(--card);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: var(--shadow);
  font-size: 14px;
  font-weight: 500;
  animation: toast-in 0.2s ease-out;
}
.toast__text { white-space: nowrap; }
.toast__action {
  border: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 8px 14px;
  border-radius: 999px;
  background: var(--accent);
  background: color-mix(in srgb, var(--accent) 96%, var(--card));
  color: #fff;
  font-size: 14px;
  font-weight: 600;
}
.toast__action:active { transform: scale(0.97); }
.toast__dismiss {
  border: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  background: transparent;
  color: var(--muted);
  font-size: 15px;
  line-height: 1;
  padding: 8px;
}
@keyframes toast-in {
  from { opacity: 0; transform: translate(-50%, 12px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
  .toast { animation: none; }
}

/* At the ~320px layout floor the schedule rows have every control plus the
   delete button competing for one line. Reclaim side padding inside the
   disclosure cards and shrink the fixed controls so the rate field keeps its
   minimum width without pushing anything to a second row or overflowing.
   Placed last so it wins over the base .disclosure__body padding shorthand. */
@media (max-width: 360px) {
  .disclosure__body { padding-left: 12px; padding-right: 12px; }
  /* The energy-mode editors live in the plain Prices card (18px padding) rather
     than a disclosure body (12px here), so widen them 6px each side to give the
     tier rows the same width the fees rows get, keeping controls on one line. */
  #touEditor, #durEditor { margin-left: -6px; margin-right: -6px; }
  .tou-row { gap: 4px; }
  .dur-after { gap: 4px; }
  .dur-min { width: 48px; flex-basis: 48px; padding-left: 6px; padding-right: 6px; }
  .row-unit { padding-left: 2px; padding-right: 2px; }
  /* Tighten the currency indent so the compact tier rate still shows all its
     digits once the row is this cramped. */
  .tou-rate-wrap .input-money__sym { left: 9px; font-size: 15px; }
  .tou-rate-wrap input { padding-left: 22px; }
  .tou-del { width: 36px; }
}

/* Once the column has room to spare (large phones landscape, tablets, the
   centered desktop column), let the rate field grow to fill the row so the
   tier rows span the same full width as the Service fee field and their delete
   buttons line up at the right edge, instead of stopping short mid-card. */
@media (min-width: 480px) {
  .tou-rate-wrap { flex: 1 1 88px; }
}
