/* ==========================================================================
   Bundu Power look & feel
   --------------------------------------------------------------------------
   Palette, typography and component styling matched to the public
   www.bundupower.co.za site: black header bar with yellow (#f9e701) accent
   line, white nav with a yellow underline on the active tab, Oswald for
   headings (uppercase, bold) and Open Sans for body text, white cards with
   soft shadows, and yellow primary buttons - mirroring their .btn-warning /
   .spec-card / .navbar treatment.

   Shared by all three tool pages (index.php, generator.php, inverter.php)
   via <link rel="stylesheet" href="assets/css/theme.css">.
   ========================================================================== */

:root {
  --bp-yellow: #f9e701;
  --bp-yellow-dark: #e6d500;
  --bp-black: #111111;
  --bp-dark: #212529;
  --bp-text: #444444;
  --bp-heading: #333333;
  --bp-muted: #777777;
  --bp-border: #eaeaea;
  --bp-bg: #f8f9fa;
  --bp-ok: #1f8a3b;
  --bp-bad: #c0392b;
}

* { box-sizing: border-box; }

/* Hard safety net against the page ever being pushed right / needing a
   horizontal scrollbar (reported symptom: "the pump graph and bar graph
   push the page over to the right"). Root causes fixed elsewhere in this
   file are (a) .page-wrap previously using 96vw, a unit that includes the
   OS/browser's reserved vertical-scrollbar gutter and so can compute wider
   than the actually-available content area on browsers that reserve fixed
   scrollbar space (most of Windows - the real deployment target), and
   (b) CSS Grid tracks default to min-width:auto, which for a track holding
   a wide <img> (the 700px-native pump/hourly charts) resolves to that
   image's full intrinsic width and refuses to let the column shrink
   further, regardless of the image's own responsive width:100% CSS. Belt
   and braces: even if some other element sneaks in an oversized intrinsic
   width in future, clip horizontal overflow at the document root instead
   of ever revealing a rightward scrollbar/shift.
*/
html, body { max-width: 100%; overflow-x: hidden; }

body {
  font-family: "Open Sans", Helvetica, Arial, sans-serif;
  color: var(--bp-text);
  background: var(--bp-bg);
  margin: 0;
  padding: 0;
}

h1, h2, h3, h4, h5, h6 {
  font-family: "Oswald", Impact, sans-serif;
  color: var(--bp-heading);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

a { color: var(--bp-black); text-decoration: none; transition: color 0.2s ease; }
a:hover { color: var(--bp-muted); }

/* ---- Site header (logo bar + nav), rendered by includes/nav.php ---- */
.site-header-bar {
  background: var(--bp-black);
  border-bottom: 2px solid var(--bp-yellow);
  padding: 10px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.site-header-bar img { height: 34px; display: block; }
.site-header-bar .tagline { color: #fff; font-size: 12.5px; opacity: 0.85; }
.site-header-bar .tagline b { color: var(--bp-yellow); }

.nav {
  background: #fff;
  border-bottom: 3px solid var(--bp-yellow);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
  padding: 0 24px;
  display: flex;
  gap: 4px;
  margin: 0;
}
.nav a {
  display: inline-block;
  color: #333;
  text-transform: uppercase;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.04em;
  padding: 16px 16px;
  border-bottom: 3px solid transparent;
  margin-bottom: -3px;
}
.nav a:hover { color: #000; border-bottom-color: #ddd; }
.nav a.active { color: #000; border-bottom-color: var(--bp-yellow); }

/* ---- Page content wrapper ----
   Fluid width instead of a fixed max-width: on wide monitors the page now
   stretches to use the available screen space (important for the
   side-by-side Solar/Hybrid chart images added to the Pumps page, which
   were being squeezed into a narrow fixed column while most of a wide
   screen sat empty), but is still capped at an upper ceiling so it doesn't
   stretch to an unreadable full-bleed width on ultra-wide displays, and
   gracefully narrows back down on small screens.

   Deliberately uses a PERCENTAGE (96%) here, not 96vw: the vw unit is
   defined by the CSS spec as a percentage of the viewport's full width,
   INCLUDING the space reserved for the vertical scrollbar on browsers/OSes
   that reserve fixed scrollbar space (essentially all of Windows, which is
   the actual XAMPP deployment target) - on a long page like this one that
   (almost) always has a vertical scrollbar, that made 96vw compute a few
   dozen pixels WIDER than the content area actually available, which is
   exactly what was pushing the whole page rightward and forcing an
   unwanted horizontal scrollbar once the wide chart images were on
   screen. A percentage width resolves against the parent element's actual
   content box instead, which already correctly excludes the scrollbar
   gutter, so this can never overflow regardless of scrollbar style. */
.page-wrap { width: min(96%, 1800px); margin: 0 auto; padding: 24px; }


h1.page-title { font-size: 22px; margin: 0 0 4px; }
.subtitle { color: var(--bp-muted); font-size: 13px; margin-bottom: 20px; }

/* ---- Layout grids ----
   Every grid track below is explicitly given "min-width: 0" on its direct
   children (via the "> *" selector) - by default a CSS Grid track's
   minimum size is "auto", which for a track containing a replaced element
   like <img> resolves to that element's INTRINSIC (natural, undecoded-css)
   width, not its CSS-constrained displayed width. The pump/hourly-flow
   chart <img> tags are natively 700x320px PNGs (ChartGenerator.php) - so
   without this override, each grid column holding one was never allowed
   to shrink below 700px no matter how narrow the viewport or how small
   .chart-img's own width:100% tried to make it, which silently forced the
   whole page wider than the viewport (a horizontal scrollbar / "push the
   page right" effect) as soon as those charts were on screen. This is a
   well-known CSS Grid "blowout" gotcha, not specific to this app's charts -
   applying min-width:0 broadly here is a safe, standard fix that has no
   visible effect on any grid that doesn't contain an oversized child. */
.grid { display: grid; grid-template-columns: 340px 1fr; gap: 20px; align-items: start; }
.grid > * { min-width: 0; }
.tabs-row { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; }
.tabs-row > * { min-width: 0; }
.three-col { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; }
.three-col > * { min-width: 0; }
/* 4-across variant, used for the Generator page's "Load Levels & Inrush
   Limitations" card once it grew a 4th column (100% Load) alongside the
   existing 50%/80% Load and 1-Step Inrush Limit columns. */
.four-col { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; gap: 10px; }
.four-col > * { min-width: 0; }
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.two-col > * { min-width: 0; }

/* Wider gutter variant for two-column Solar/Hybrid comparison blocks
   (Matching Pumps, Pump Selection, Flow & Head, Panel Configuration,
   Cable Loss & Pipe Friction, and the pump/hourly-flow charts) - the
   default 10px .two-col gap wasn't enough breathing room once the right-
   aligned value in the Solar column (e.g. Panel Configuration's "Total
   Panels: 6") sat almost flush against the Hybrid column's label
   immediately to its right ("Total Panels"), reading as if they were part
   of the same line. This doesn't add a literal extra grid column/element -
   a wider CSS grid "gap" already IS empty dividing space between the two
   columns, it just needed to be wider - but functions exactly like the
   requested small (invisible) divider column. Widened from the initial
   32px to 56px per follow-up request for an even clearer visual break
   between the Solar and Hybrid sides - also now applied to the Pump
   Performance Curve / Estimated Hourly Flow Rate chart image columns
   (previously plain .two-col with only a 10px gap), since those looked
   just as visually ambiguous as the table-based comparison cards once a
   wide chart image sits right up against its neighbour. */
.two-col.divided { gap: 56px; }

/* Pump/hourly-flow charts embedded as <img> tags on the Pumps page (see
   api/pump-chart.php) - sized to fit their card column, matching the same
   .chart-img styling already used inside the PDF report (ReportRenderer.php). */
.chart-img {
  width: 100%;
  /* Native chart resolution is 700x320 (ChartGenerator.php) - capping at
     that width avoids the image being stretched/blurred wider than its
     real resolution now that the page itself can grow much wider. */
  max-width: 700px;
  height: auto;
  display: block;
  margin: 8px auto;
  border-radius: 6px;
}

/* Legend explaining the coloured reference lines on the Generator page's
   Inrush Timeline chart(s) - matches the same-named class/swatch colours
   used in the PDF report (ReportRenderer.php) so both look identical. */
.chart-legend { text-align: center; margin-top: 6px; font-size: 12px; color: var(--bp-muted); }
.chart-legend-title { font-weight: 700; margin-right: 12px; }
.chart-legend-item { margin: 0 12px; white-space: nowrap; }

/* Summer / Winter / Average season selector shown under each brand's
   Estimated Hourly Flow Rate chart (includes/pump-results-partial.php) -
   a compact segmented-control-style radio group rather than plain stacked
   radio buttons, so it reads as one cohesive 3-way switch directly under
   the chart it controls. Solar and Hybrid each get their own independent
   copy (different name= per brand), so picking "Winter" for Solar has no
   effect on the Hybrid chart alongside it. */
.season-select {
  display: flex;
  justify-content: center;
  gap: 4px;
  margin: 8px auto 4px;
  padding: 3px;
  background: var(--bp-bg);
  border-radius: 8px;
  max-width: 340px;
}
.season-option {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 5px 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--bp-muted);
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
  white-space: nowrap;
}
.season-option:hover { background: rgba(0,0,0,0.04); }
.season-option input[type="radio"] {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  margin: 0;
}
.season-option:has(input:checked) {
  background: #fff;
  color: var(--bp-heading);
  box-shadow: 0 1px 3px rgba(0,0,0,0.15);
}
.chart-legend-swatch {
  display: inline-block; width: 11px; height: 11px; border-radius: 3px;
  margin-right: 5px; vertical-align: middle;
}

/* "Available Base Load" note shown directly under the Generator page's
   Inrush Timeline chart (or under each of the 3 per-phase charts, when
   Single-phase motors are in the mix) - see Calculations::
   calculateAvailableBaseLoad()'s docblock for the full rationale: how
   much MORE continuous load this generator/phase could still take on
   beyond the motors already entered, without needing to read it off the
   graph itself (per explicit request - "not on the graph... displayed
   below the graph or below each graph"). */
.base-load-note {
  margin-top: 8px; padding: 8px 10px; background: var(--bp-bg);
  border: 1px solid var(--bp-border); border-radius: 6px; text-align: center;
}
.base-load-note-title {
  display: block; font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.03em; color: var(--bp-muted); margin-bottom: 2px;
}
.base-load-note-range { font-size: 13px; font-weight: 700; color: var(--bp-heading); }
/* Separator between the kW range and the Amp range (see item 3's
   request to show them as two distinct ranges, not one combined
   "kW / A" pair repeated at each end) - a plain vertical bar with a
   little breathing room either side, de-emphasised (lighter weight/
   colour) relative to the two range figures either side of it. */
.base-load-note-sep { margin: 0 10px; font-weight: 400; color: var(--bp-muted); }

/* ---- Cards ---- */
.card {
  background: #fff;
  border: 1px solid var(--bp-border);
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
  padding: 18px 20px;
  margin-bottom: 20px;
}
.card h2 {
  font-size: 14px;
  margin: 0 0 14px;
  padding-bottom: 10px;
  border-bottom: 2px solid #f1f1f1;
}

/* Lets a card's <h2> title share its row with a right-aligned action
   (currently just the "Clear Inputs" button, moved here from the page
   subtitle bar - see .clear-inputs-btn below) instead of only ever being
   plain title text. Used on each tool page's first/primary Inputs card
   (Pumps: "Inputs", Generators: "Generator & Site", Inverter: "System
   Type") so Clear Inputs sits directly next to the inputs it clears,
   rather than up in the page header alongside unrelated page-level info
   like the data-source pill. */
.card h2.with-action {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}


/* ---- Form elements ---- */
label {
  display: block;
  font-size: 11.5px;
  text-transform: uppercase;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--bp-muted);
  margin: 12px 0 4px;
}
input[type=number], input[type=text], input[type=password], select {
  width: 100%;
  padding: 8px 10px;
  border-radius: 4px;
  border: 1px solid #ddd;
  background: #fff;
  color: #333;
  font-size: 13px;
  font-family: inherit;
}
input:focus, select:focus {
  outline: none;
  border-color: var(--bp-yellow);
  box-shadow: 0 0 0 3px rgba(249, 231, 1, 0.35);
}

button, .btn {
  margin-top: 16px;
  width: 100%;
  padding: 11px;
  border: 1px solid var(--bp-yellow);
  border-radius: 4px;
  background: var(--bp-yellow);
  color: #000;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  cursor: pointer;
  font-size: 13px;
  transition: background 0.15s ease, border-color 0.15s ease;
}
button:hover { background: var(--bp-yellow-dark); border-color: var(--bp-yellow-dark); }
button.secondary { background: #fff; color: #333; border: 1px solid #ddd; }
button.secondary:hover { background: var(--bp-bg); }

/* Small inline auto-submit selects (e.g. model overrides) get a tighter margin */
.inline-select { margin-top: 0; margin-bottom: 10px; }

/* ---- Tables ---- */
table { width: 100%; border-collapse: collapse; font-size: 12.5px; margin-top: 8px; }
td, th { padding: 7px 6px; text-align: left; border-bottom: 1px solid #f1f1f1; }
th { color: var(--bp-muted); font-weight: 700; text-transform: uppercase; font-size: 10.5px; letter-spacing: 0.03em; }

.ok { color: var(--bp-ok); font-weight: 700; }
.bad { color: var(--bp-bad); font-weight: 700; }

/* ---- Collapsible result cards ----
   Keeps the page overview lean: only the headline figures (e.g. Flow
   (final)/Est. Daily Flow, Total Panels/Config Result, Cable Result/Pipe
   Result) are shown by default, with the rest of each card's detail
   tucked behind a native <details>/<summary> toggle the user can expand
   only when they need it. */
.summary-block { margin-top: 8px; }
.summary-title { font-weight: 700; font-size: 12.5px; margin-bottom: 6px; }
.summary-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  padding: 6px 0;
  border-bottom: 1px solid #f1f1f1;
  font-size: 12.5px;
}
.summary-row:last-child { border-bottom: none; }
.summary-row > span { color: var(--bp-muted); }
.summary-row > strong { text-align: right; white-space: nowrap; }

.detail-toggle { margin-top: 6px; }
.detail-toggle > summary {
  cursor: pointer;
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--bp-muted);
  padding: 6px 0;
  list-style: none;
  user-select: none;
}
.detail-toggle > summary::-webkit-details-marker { display: none; }
.detail-toggle > summary::before { content: "▸ "; display: inline-block; transition: transform 0.15s ease; }
.detail-toggle[open] > summary::before { transform: rotate(90deg); }
.detail-toggle > summary:hover { color: var(--bp-heading); }
.detail-toggle table { margin-top: 4px; }

.pill {
  display: inline-block;
  background: var(--bp-bg);
  border: 1px solid var(--bp-border);
  border-radius: 999px;
  padding: 3px 12px;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--bp-muted);
}

.error {
  background: #fdecea;
  border: 1px solid #f3b8b3;
  color: #a3352a;
  padding: 12px 16px;
  border-radius: 6px;
  margin-bottom: 16px;
  font-size: 13px;
}
.info {
  background: #eaf6ff;
  border: 1px solid #b8e2ff;
  color: #0c5c8a;
  padding: 10px 14px;
  border-radius: 6px;
  margin-bottom: 16px;
  font-size: 12.5px;
}

/* ---- "Generate Report" card (Pumps / Generators / Inverters pages) ---- */
#reportCard { border-top: 3px solid var(--bp-yellow); }
.report-hint { font-size: 12px; color: var(--bp-muted); margin: 0 0 4px; }
.report-hint + .two-col { margin-top: 4px; }

/* Per-inverter / per-MPPT / per-PV-input panel breakdown (Inverter
   tool's "Solar Array Detail" card) - a proper 3-level nested grouping
   matching the site's existing "bubble card" visual language (the same
   pattern used for the Generator page's per-motor cards): each inverter
   (or group of identical inverters) gets its own numbered bubble card,
   each MPPT tracker inside it gets its own labelled sub-section, and
   each individual PV input under that MPPT gets its own line - rather
   than a flat merged sentence, since a real nested hierarchy (Inverter >
   MPPT > PV Input) reads far more clearly than one run-on line per
   inverter once a system needs several inverters/MPPTs/inputs. */
/* Lays each inverter's (or identical-inverter-group's) card out
   side-by-side rather than stacked one-per-row - per explicit request,
   since the Solar Array Detail card is wide enough to comfortably fit
   3-4 of these bubble cards across at once, and stacking them vertically
   wasted most of that horizontal space once a system needed several
   inverters. flex-wrap lets as many cards fit per row as actually have
   room (space permitting) rather than a fixed column count that could
   force cramped cards on a narrower viewport. */
.pv-breakdown-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 16px;
}
.pv-breakdown-inverter {
  position: relative;
  /* flex-basis sets a comfortable minimum card width (enough for the
     longest realistic "PV Input 2 (MPPT 2)... 999 panels 999.99V /
     99.99A" line without wrapping awkwardly) - flex-grow then lets
     however many of these fit per row (3-4 on a typical desktop width,
     per the explicit request) stretch evenly to fill any remaining
     row space, rather than leaving a ragged gap on the right. */
  flex: 1 1 260px;
  min-width: 220px;
  margin: 0;
  padding: 14px 14px 10px;
  background: var(--bp-bg);
  border: 1px solid var(--bp-border);
  border-radius: 10px;
}
.pv-breakdown-badge {
  position: absolute;
  top: -11px;
  left: 14px;
  background: var(--bp-yellow);
  color: var(--bp-black);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.02em;
  padding: 3px 12px;
  border-radius: 999px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
  white-space: nowrap;
}
.pv-breakdown-mppt {
  margin: 10px 0 0;
  padding: 8px 0 0 14px;
  border-left: 3px solid var(--bp-yellow-dark);
}
.pv-breakdown-mppt:first-of-type { margin-top: 6px; }
.pv-breakdown-mppt-label {
  font-size: 11.5px;
  font-weight: 700;
  color: var(--bp-heading);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin-bottom: 4px;
}
.pv-breakdown-input {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 12.5px;
  padding: 2px 0 2px 10px;
}
.pv-breakdown-input-label { color: var(--bp-muted); min-width: 78px; flex-shrink: 0; }
.pv-breakdown-input-value { font-weight: 600; }
.pv-breakdown-input-spec { color: var(--bp-muted); font-size: 11.5px; }
/* The inline row of panel icons merged directly underneath each PV
   Input's own text line (see includes/helpers.php's renderPanelIconRow()) -
   per explicit follow-up request to combine the panel images with the
   Panel Wiring Breakdown section rather than showing them as a separate
   standalone diagram higher up the page. Tighter margins than the
   standalone diagram's own .panel-array-table (no row label/polarity
   columns needed here - just the panel run itself). */
.panel-array-table-inline { margin: 4px 0 10px 10px; }

/* ---- Panel Array Diagram (Pumps' Panel Configuration card + Inverter's
   Solar Array Detail card) - a dynamically-generated visual wiring
   layout, per explicit request: "add in a picture of a solar panel and
   lay this out depending on the pump used and the panel requirements,
   i.e. 6 panels in series, 2 strings parallel". Deliberately a flat,
   minimal CSS-drawn icon (a dark rectangle with a yellow border and a
   faint 4-cell grid) rather than a real photo - matches the app's
   existing flat, modern black/yellow look, scales crisply at any size,
   loads instantly (no image file/network request at all), and - equally
   important - renders identically inside the Dompdf-generated PDF
   reports (verified directly: Dompdf can't render inline SVG data-URIs,
   but DOES correctly render plain CSS backgrounds/borders/::before/
   ::after pseudo-elements, which is exactly what this icon is built
   from).
   ROWS = STRINGS, one row of panel icons per string wired in SERIES;
   multiple rows stacked = strings wired in PARALLEL - e.g. "6 in series,
   2 parallel" draws as 2 rows of 6 panels each, matching how installers
   conventionally sketch a wiring diagram.

   Redesigned TWICE since. First redesign: portrait/vertical panel icons
   (kept - confirmed again in the second redesign below rather than
   switching to landscape), bigger sizing, "-" text connectors, and a
   shared ladder-style busbar across every string.

   Second (current) redesign, prompted by a reference image of a real
   installer-style diagram (horizontal wire segments between panels,
   ending in a +/- connector dot at each string end) - see
   includes/helpers.php's renderPanelArrayDiagram() docblock for the
   full detail on all 4 changes made:
     1. FIXED panel icon size across every diagram (sized once against a
        20-panel string, this app's practical per-string max) - not
        rescaled smaller per-diagram based on that diagram's own longest
        string, so the gap/size stays visually consistent between a
        short string and a long one.
     2. Short BLACK connector bands (.panel-array-band, a solid
        rectangle) between panels AND between each string's end panels
        and their own polarity icons - replacing the previous "-" text
        glyph, matching the reference image's wire segments (in black,
        matching this app's theme rather than the reference's orange).
     3. NO shared busbar across strings any more (removed entirely,
        along with the uneven-string "wire filler" cell that existed
        only to keep that busbar aligned) - each string now has its own
        independent pair of polarity icons, since strings often land on
        separate MPPT inputs/inverters, not a shared physical rail.
     4. Polarity icons are small filled circles: RED with white "+"
        (string start/left), BLACK with white "-" (string end/right).
   IMPLEMENTATION NOTE: still built as a plain HTML <table> (rowspan is
   no longer needed now the busbar is gone), not flexbox - verified
   directly that Dompdf does not reliably lay out flex containers, but
   handles tables exactly like a real browser, so the exact same markup
   (built once by includes/helpers.php's renderPanelArrayDiagram())
   renders correctly both on-screen and inside a PDF report. */
.panel-array-diagram {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--bp-border);
}
.panel-array-diagram-title {
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--bp-muted);
  margin-bottom: 10px;
}
/* Horizontal scroll fallback (rather than wrapping/squashing) for the
   rare case of a genuinely very long string on a narrow viewport - the
   diagram's fixed sizing is already tuned to fit a full 20-panel string
   (this app's practical per-string maximum) within a typical card/page
   width, so this is a safety net for an unusually narrow browser
   window, not the normal behaviour. */
.panel-array-diagram-scroll { overflow-x: auto; }
/* width: auto overrides the site-wide "table { width: 100% }" rule -
   without this, this diagram's table stretches to fill the whole card
   width and the browser spreads its (otherwise fixed-size) cells out to
   fill that width, opening up large, inconsistent gaps between panels -
   exactly the opposite of the fixed, consistent spacing this diagram is
   built to guarantee. */
.panel-array-table { border-collapse: collapse; margin-bottom: 8px; width: auto; }
.panel-array-table td { padding: 0; vertical-align: middle; }
.panel-array-table tr:not(:last-child) td { padding-bottom: 10px !important; }
.panel-array-string-label {
  font-size: 11px;
  color: var(--bp-muted);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  white-space: nowrap;
  padding-right: 10px !important;
}
.panel-array-panel-cell { padding: 0 !important; text-align: center; }
/* The panel icon itself - a single <span>, no nested markup needed (the
   cross-grid lines are drawn via ::before/::after below) - kept this
   simple deliberately so a 20-panel string doesn't bloat the page/PDF
   with dozens of extra child elements. Portrait/vertical orientation
   (taller than wide). Actual width/height are set inline by
   renderPanelArrayDiagram()'s FIXED sizing (identical across every
   diagram, calculated once to fit a full 20-panel string). */
.panel-icon-v {
  display: inline-block;
  background: var(--bp-black);
  border: 2px solid var(--bp-yellow);
  border-radius: 3px;
  box-sizing: border-box;
  position: relative;
}
.panel-icon-v::before {
  /* horizontal cell-divider line */
  content: "";
  position: absolute;
  left: 2px;
  right: 2px;
  top: 50%;
  height: 1px;
  background: #3a3a3a;
}
.panel-icon-v::after {
  /* vertical cell-divider line */
  content: "";
  position: absolute;
  top: 2px;
  bottom: 2px;
  left: 50%;
  width: 1px;
  background: #3a3a3a;
}
/* Short black connector band between adjacent panels on the same
   string, and between a string's end panels and their own polarity
   icon - represents the physical wire (per the reference image's
   orange wire segments, drawn here in black to match this app's
   theme), replacing the previous "-" text character. */
.panel-array-band-cell { padding: 0 !important; text-align: center; }
.panel-array-band {
  height: 3px;
  background: var(--bp-black);
  border-radius: 1px;
}
/* Collapsed-run ellipsis marker - used instead of drawing every single
   panel icon once a run is longer than renderPanelIconRow()'s own
   collapse threshold (see that function's docblock): shows just the
   first 3 and last 3 panel icons with this "⋮" marker standing in for
   the rest, still visually conveying "all N panels wired in series"
   (the exact panel count is always stated in the text line above the
   icons anyway) without needing to draw a very long/wide row - which is
   what was previously causing a single MPPT's own panel row to overflow
   its allotted space in the Inverter PDF report's 2-column layout and
   force an awkward mid-MPPT page break. */
.panel-array-ellipsis-cell {
  padding: 0 4px !important;
  text-align: center;
  font-weight: 700;
  color: var(--bp-muted);
  font-size: 15px;
}
/* Polarity icons - small filled circles at each string's own two ends
   (NOT a shared busbar across strings any more - see this block's
   comment above for why). Red/"+"  = positive (string start, left);
   black/"-" = negative (string end, right). */

.panel-array-polarity-cell { padding: 0 !important; text-align: center; }
.panel-array-polarity {
  display: inline-block;
  border-radius: 50%;
  color: #fff;
  font-weight: 800;
  text-align: center;
  box-sizing: border-box;
}
.panel-array-polarity-plus { background: #c0392b; font-size: 13px; }
.panel-array-polarity-minus { background: var(--bp-black); font-size: 13px; }
.panel-array-diagram-note {
  margin-top: 10px;
  font-size: 11px;
  color: var(--bp-muted);
}
.req { color: var(--bp-bad); }

.report-btn {
  margin-top: 16px;
}
.report-msg { font-size: 12.5px; margin-top: 10px; min-height: 1em; }
.report-msg.error { color: var(--bp-bad); font-weight: 700; }
.report-msg.success { color: var(--bp-ok); font-weight: 700; }

/* ---- Clickable matching-pumps / matching-gensets lists ---- */
.match-list { max-height: 160px; overflow-y: auto; margin-top: 6px; }
.match-list a, .match-list div {
  display: block;
  padding: 6px 8px;
  font-size: 12.5px;
  color: var(--bp-text);
  border-bottom: 1px dashed var(--bp-border);
  border-radius: 4px;
  cursor: pointer;
}
.match-list a:hover { background: #fffbe6; color: #000; }
.match-list a.selected, .match-list div.selected {
  background: var(--bp-yellow);
  color: #000;
  font-weight: 700;
  border-bottom-color: var(--bp-yellow);
}
.match-list div:not(.selected):not(a) { cursor: default; }
.match-list-sub { display: block; font-size: 10.5px; opacity: 0.75; margin-top: 1px; }
/* Est. Daily Flow moved to its own right-aligned figure on each pump's
   own row (was a trailing "· Est. Daily Flow: X L/day" tacked onto the
   sub-line) - per request, a small 2-column stat layout per row: model +
   L/h (and its excl.-friction sub-line) on the left, Est. Daily Flow as
   its own bold value on the right, only rendered once a real (non-
   estimated) figure is actually available for that specific pump. */
.match-list-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.match-list-main { flex: 1 1 auto; min-width: 0; }
.match-list-daily {
  flex: 0 0 auto; text-align: right; font-weight: 700; font-size: 12.5px;
  white-space: nowrap; padding-left: 8px;
}
.match-list-daily-label { display: block; font-size: 9px; font-weight: 400; text-transform: uppercase; opacity: 0.7; letter-spacing: 0.3px; }

/* Tight-gap variant of .two-col, used for grouped input pairs (e.g. pipe
   size + length, cable size + length) where the fields are closely related */
.two-col.tight-gap { gap: 6px; }

/* ---- Generator page: motor load rows ----
   Split into two stacked rows per motor: kW + Phase on top, then a
   Simultaneous-start checkbox row, then Start Method on its own
   full-width row underneath - the start method options ("Star-Delta
   (SD)", "Soft-Start (SS)") are long enough that cramming them into a
   narrow column (as a single row) got visually truncated/cramped, so
   giving Start Method the full card width fixes that. The "Simultaneous
   start" checkbox text also gets its own full-width row (rather than
   squeezing into a third grid column) since this card sits in the
   narrow 340px sidebar column and the label text wouldn't fit
   alongside kW/Phase without wrapping awkwardly or overflowing. */
/* Each motor now gets its own distinct "bubble card" - a nested card
   inside the Motor Loads card, with a numbered badge (matching the
   site's brand yellow used elsewhere for pills/accents) - replacing the
   previous flat, easy-to-miss dashed-line divider between motors, per
   request: "separate motor 1 from motor 2 and from motor 3, like with a
   more prominent divider or even a bubble card or something that fits
   the theme". Positioned relative so the numbered badge (.motor-badge)
   can be absolutely-positioned overlapping its top-left corner, the same
   way a notification/count badge conventionally overlaps a card corner. */
.motor-row {
  position: relative;
  margin-bottom: 16px;
  padding: 14px 14px 10px;
  background: var(--bp-bg);
  border: 1px solid var(--bp-border);
  border-radius: 10px;
}
.motor-row:last-child { margin-bottom: 0; }
.motor-badge {
  position: absolute;
  top: -11px;
  left: 14px;
  background: var(--bp-yellow);
  color: var(--bp-black);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.02em;
  padding: 3px 12px;
  border-radius: 999px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
}
.motor-row label { margin: 0 0 3px; }
.motor-row-top {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  align-items: end;
}
.motor-row-bottom { margin-top: 8px; }
.checkbox-wrap {
  display: flex; align-items: flex-start; gap: 8px;
  margin-top: 8px; padding: 6px 8px;
  background: var(--bp-bg); border-radius: 4px;
}
.checkbox-wrap input { width: auto; margin-top: 2px; flex-shrink: 0; }
.checkbox-wrap span { font-size: 11px; color: var(--bp-muted); line-height: 1.3; }
.motor-loads-hint { font-size: 11.5px; color: var(--bp-muted); margin: -4px 0 14px; line-height: 1.4; }

/* ---- Toggle switch (used for "Advanced Motor Load Analysis") ---- */
.toggle-row { display: flex; align-items: center; gap: 12px; margin: 4px 0 16px; }
.toggle-row .toggle-label { font-size: 13px; font-weight: 700; color: var(--bp-heading); }
.toggle-row .toggle-sub { font-size: 11.5px; color: var(--bp-muted); display: block; margin-top: 1px; }
.switch { position: relative; display: inline-block; width: 46px; height: 25px; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch-slider {
  position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0;
  background-color: #ccc; transition: 0.2s; border-radius: 25px;
}
.switch-slider:before {
  position: absolute; content: ""; height: 19px; width: 19px; left: 3px; bottom: 3px;
  background-color: #fff; transition: 0.2s; border-radius: 50%; box-shadow: 0 1px 3px rgba(0,0,0,0.3);
}
.switch input:checked + .switch-slider { background-color: var(--bp-yellow); }
.switch input:checked + .switch-slider:before { transform: translateX(21px); }
.switch input:focus-visible + .switch-slider { outline: 2px solid var(--bp-yellow); outline-offset: 2px; }

hr { border: none; border-top: 1px solid var(--bp-border); margin: 14px 0; }

.footer-note { margin-top: 24px; font-size: 11.5px; color: var(--bp-muted); }

/* Small "Calculating.../Updated" status indicator next to the page subtitle,
   used by the auto-calculate (no page reload) pages */
.calc-status { margin-left: 10px; font-size: 11.5px; color: var(--bp-muted); font-style: italic; }
.calc-status.active { color: var(--bp-yellow-dark); font-weight: 700; font-style: normal; }

/* "Clear Inputs" link/button in each tool page's subtitle bar - a plain
   navigation to the page's own bare URL (no query string), which resets
   every field back to its server-side default in one click, per explicit
   request for a manual way to wipe the form (as an alternative/backup to
   the various auto-preserve-on-location-lookup fixes elsewhere). */
.clear-inputs-btn {
  margin-left: 12px; font-size: 11.5px; color: #a3352a; text-decoration: none;
  border: 1px solid #f3b8b3; background: #fdecea; padding: 2px 9px; border-radius: 999px;
  white-space: nowrap; display: inline-block; vertical-align: middle;
}
.clear-inputs-btn:hover { background: #fbdedb; text-decoration: none; }

/* ---- Shared Site Location bar (includes/location-bar.php) ---- */
.location-bar { margin-bottom: 20px; }
.location-bar-form { margin: 0; }
.location-bar-row { display: flex; align-items: flex-end; gap: 12px; }
.location-bar-address { flex: 1; }
.location-bar-address label { margin-top: 0; }
.location-bar-row button { margin-top: 0; width: auto; padding: 8px 20px; white-space: nowrap; }
/* "✕ Clear" button in the Site Location bar - only rendered once a
   location is actually set (see location-bar-inner-partial.php) - reuses
   the same red/danger styling as each page's own "Clear Inputs" pill
   (.clear-inputs-btn) so both "clear" affordances look consistent. */
.loc-clear-btn {
  padding: 8px 16px !important;
  color: #a3352a !important;
  background: #fdecea !important;
  border-color: #f3b8b3 !important;
}
.loc-clear-btn:hover { background: #fbdedb !important; }
.location-bar-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid #f1f1f1;
  font-size: 12.5px;
  color: var(--bp-text);
}
.location-bar-summary strong { color: var(--bp-muted); font-weight: 700; text-transform: uppercase; font-size: 10.5px; letter-spacing: 0.02em; display: block; }
.location-bar-updated { margin-left: auto; color: var(--bp-muted); font-size: 11px; align-self: center; }

/* Address autocomplete suggestion dropdown */
.location-suggestions {
  display: none;
  position: absolute;
  top: 100%; left: 0; right: 0;
  background: #fff;
  border: 1px solid var(--bp-border);
  border-top: none;
  border-radius: 0 0 6px 6px;
  box-shadow: 0 6px 14px rgba(0,0,0,0.1);
  z-index: 50;
  max-height: 220px;
  overflow-y: auto;
}
.location-suggestion-item {
  padding: 8px 12px;
  font-size: 12.5px;
  cursor: pointer;
  border-bottom: 1px solid #f5f5f5;
}
.location-suggestion-item:last-child { border-bottom: none; }
.location-suggestion-item:hover { background: #fffbe6; }

/* "View on Map" inline button + preview map */
.location-view-btn {
  margin: 0; width: auto; padding: 4px 12px; font-size: 11px;
  background: #fff; color: #333; border: 1px solid #ddd; text-transform: none; font-weight: 600;
}
.location-view-btn:hover { background: var(--bp-bg); }
.location-preview-map { height: 260px; border-radius: 6px; margin-top: 12px; border: 1px solid var(--bp-border); }

/* Map picker modal */
.loc-modal-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.55);
  z-index: 1000; display: flex; align-items: center; justify-content: center; padding: 20px;
}
.loc-modal {
  background: #fff; border-radius: 8px; width: 100%; max-width: 720px;
  box-shadow: 0 10px 40px rgba(0,0,0,0.3); overflow: hidden; display: flex; flex-direction: column;
}
.loc-modal-header {
  display: flex; justify-content: space-between; align-items: center;
  padding: 14px 18px; border-bottom: 1px solid var(--bp-border); font-size: 13.5px;
}
.loc-modal-close {
  background: none; border: none; font-size: 22px; line-height: 1; cursor: pointer;
  color: var(--bp-muted); width: auto; margin: 0; padding: 0 4px;
}
.loc-modal-close:hover { color: #000; }
.loc-picker-map { height: 420px; width: 100%; }
.loc-modal-footer {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 18px; border-top: 1px solid var(--bp-border);
}
.loc-modal-address { font-size: 12.5px; color: var(--bp-text); flex: 1; }
.loc-modal-confirm { width: auto; margin: 0; padding: 9px 20px; white-space: nowrap; }
.loc-modal-confirm:disabled { opacity: 0.5; cursor: not-allowed; }

