:root {
  --bg: #f4f7f2;
  --card-bg: #ffffff;
  --accent: #3a753a;       /* 4.82:1 on --accent-light, 5.55:1 white-on-accent */
  --accent-light: #e8f2e5;
  --text: #23301f;
  --text-muted: #646e5f;   /* 4.94:1 on --bg, 5.33:1 on white */
  --border: #dde5d8;
  /* Shared risk-state palette (lifted from the .forecast-agreement and
     .status-pill.watering rules so existing components don't shift). */
  --warn: #a25a00;
  --warn-bg: #fdf3e2;
  --danger: #8a2419;
  --danger-bg: #fdecea;
  --info: #1c5d8a;
  --info-bg: #e3f0fb;
  --night-bg: #161c2b;      /* 7-Day Moon cards: night-sky surface */
  --night-border: #2a3348;
  --night-text: #e7ebf3;
  --night-muted: #a3adc2;

  /* Stronger status colours: borders, icons, button fills, bold status text */
  --danger-strong: #c0392b;
  --danger-extreme: #7b1113;   /* extreme alerts, severe-weather icon */
  --danger-border: #f5c6c0;
  --warn-strong: #c77b1b;
  --warn-border: #e8b978;
  --ok: #4a7c4a;
  --ok-bg: #eaf5ea;
  --info-border: #a9c9e6;
  --highlight-bg: #fff9e6;     /* yellow "look here" panels */
  --highlight-border: #e8d878;
  --on-accent: #fff;           /* text/marks on accent or status fills */
  --rain-text: #2f6ea8;        /* 4.96:1 on --bg */

  /* Weather icon tints (wxIcon), see .wx-icon[data-code] */
  --wx-default: #8a9585;
  --wx-sun: #e0a92b;
  --wx-storm-sun: #d99b1f;
  --wx-storm: #6b7566;
  --wx-rain: #3f7fbf;
  --wx-ice: #5fa2d8;
  --wx-smoke: #a09577;
  --wx-moon: #6b7688;
  --wx-cold: #2980b9;
  /* Forecast high/low range bar: cold -> mild -> warm -> hot */
  --temp-cold: #6fa8dc;
  --temp-mild: #7fb069;
  --temp-hot: #d9743a;

  /* Moon: banner path, photo shadow, day badges */
  --moon-path: #8e9ab0;
  --moon-shadow: #070a12;
  --moon-badge-bg: #1f2638;
  --moon-badge-text: #f1e3b0;
  --moon-gold: #e7c96b;
  --moon-ink: #1b2233;

  /* Biodynamic day chips (white text on each) */
  --bd-root: #7a5230;
  --bd-flower: #8f6f00;        /* white text 4.73:1 */

  /* Radius */
  --radius-sm: 6px;    /* controls: small buttons, inputs, icon buttons */
  --radius-md: 8px;    /* buttons, banners, inline panels */
  --radius-lg: 12px;   /* content surfaces: cards, charts, summaries, dialogs */
  --radius-pill: 999px;

  /* Type scale */
  --text-2xs: 0.7rem;
  --text-xs: 0.8rem;
  --text-sm: 0.85rem;
  --text-md: 0.9rem;
  --text-base: 1rem;
  --text-lg: 1.1rem;
  --text-xl: 1.4rem;
  --text-2xl: 2rem;
  --text-display: 3rem;

  /* Spacing (4px grid) */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;

  /* Elevation: only for elements that float above the page */
  --shadow-popover: 0 6px 20px rgba(0, 0, 0, 0.12);
  --shadow-dialog: 0 12px 40px rgba(0, 0, 0, 0.25);

  /* Stacking. Leaflet panes use 400-1000 internally; <dialog> uses the top layer. */
  --z-base: 0;
  --z-dropdown: 4;
  --z-nav: 1100;       /* phone bottom tab bar: above Leaflet panes/controls (<= 1000) */
  --nav-height: 56px;

  /* Layout */
  --content-max: 1440px;
  --prose-max: 75ch;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
}

/* Measured values: fixed-width digits so readings and columns align. */
.card p,
.summary-box .big,
.gdd-custom-total,
.forecast-hero-temp, .forecast-hero-hilo, .forecast-hero-metrics,
.forecast-hour-temp, .forecast-hour-precip,
.forecast-day-temps, .forecast-day-precip,
.calendar-day-num, .calendar-day-total,
.log-table td, .run-log-table td {
  font-variant-numeric: tabular-nums;
}

header {
  /* Full-width band; contents align to main's column. */
  padding-top: var(--space-6);
  padding-bottom: var(--space-6);
  padding-left: max(var(--space-6), env(safe-area-inset-left), calc((100% - var(--content-max)) / 2 + var(--space-6)));
  padding-right: max(var(--space-6), env(safe-area-inset-right), calc((100% - var(--content-max)) / 2 + var(--space-6)));
  background: var(--accent);
  color: white;
}

.header-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.header-top h1 { margin: 0; }

.header-top .btn-small {
  background: rgba(255,255,255,0.15);
  border-color: rgba(255,255,255,0.4);
  color: white;
  white-space: nowrap;
}

.header-top .btn-small:hover {
  background: rgba(255,255,255,0.28);
}

header h1 { margin: 0 0 var(--space-1) 0; font-size: var(--text-xl); }
.subtitle { margin: var(--space-2) 0 0 0; opacity: 0.85; font-size: var(--text-md); }

main {
  max-width: var(--content-max);
  margin: 0 auto;
  padding: var(--space-6);
  padding-left: max(var(--space-6), env(safe-area-inset-left));
  padding-right: max(var(--space-6), env(safe-area-inset-right));
}

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  text-align: center;
}

.card h3 {
  margin: 0 0 var(--space-2) 0;
  font-size: var(--text-xs);
  color: var(--text-muted);
}

.card p { margin: 0; font-size: var(--text-xl); font-weight: 600; }

.summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-8);
}

.summary-box {
  background: var(--accent-light);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

.summary-box h2 {
  margin: 0 0 var(--space-2) 0;
  font-size: var(--text-md);
  color: var(--accent);
}

.summary-box .big { font-size: var(--text-2xl); font-weight: 700; margin: 0; }
.summary-box .small { margin: var(--space-1) 0 0 0; color: var(--text-muted); font-size: var(--text-sm); }

.charts {
  display: grid;
  /* minmax(0, ...) lets charts shrink when the window narrows (e.g. a tablet
     rotating to portrait); otherwise the canvas holds the old width. */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-6);
}

.chart-container {
  min-width: 0;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}

.chart-container h2 {
  margin: 0 0 var(--space-3) 0;
  font-size: var(--text-base);
  color: var(--text-muted);
}

.gdd-custom-total {
  font-weight: 600;
  color: var(--accent);
  font-size: var(--text-base);
  white-space: nowrap;
  align-self: flex-end;
  margin-left: auto;
}

.cimis-controls {
  margin: var(--space-3) 0 var(--space-2) 0;
}

.cimis-block {
  margin: var(--space-4) 0;
  padding: var(--space-4);
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.cimis-block h3,
.cimis-subblock h3 {
  margin: 0 0 6px 0;
  font-size: var(--text-base);
}

/* Sub-sections nested inside the "Page Settings" <details> (backfill,
   stations near the farm) -- separated by a rule instead of their own
   card, since the outer <details> already has the card look. */
.cimis-subblock {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
.cimis-subblock:first-of-type {
  margin-top: 10px;
  padding-top: 0;
  border-top: none;
}

/* Collapsible "Page Settings" and "Stations Near the Farm" blocks. Once
   stations are picked the JS closes the station <details> so the list +
   map don't eat page space; it stays open while nothing is selected yet. */
.cimis-page-settings > summary,
.cimis-station-details > summary,
.water-usage-collapsible > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.cimis-page-settings > summary::-webkit-details-marker,
.cimis-station-details > summary::-webkit-details-marker,
.water-usage-collapsible > summary::-webkit-details-marker { display: none; }
.cimis-page-settings > summary::before,
.cimis-station-details > summary::before,
.water-usage-collapsible > summary::before {
  content: "\25B8"; /* ▸ */
  color: var(--text-muted);
  font-size: 0.9em;
  transition: transform 0.15s ease;
}
.cimis-page-settings[open] > summary::before,
.cimis-station-details[open] > summary::before,
.water-usage-collapsible[open] > summary::before { transform: rotate(90deg); }
.cimis-station-summary-title { font-weight: 600; font-size: var(--text-base); }
.cimis-station-summary-current {
  font-size: var(--text-xs);
  font-weight: 400;
  color: var(--text-muted);
}
.cimis-station-map {
  height: 260px;
  width: 100%;
  margin: 10px 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  z-index: var(--z-base);
}

.cimis-backfill-actions,
.cimis-station-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 10px 0;
}

.cimis-station-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 10px 0;
}

.cimis-station-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: "cb main" "cb meta";
  column-gap: var(--space-2);
  align-items: center;
  padding: 7px var(--space-2);
  border-radius: var(--radius-md);
  cursor: pointer;
  font-size: var(--text-md);
}

.cimis-station-row:hover { background: var(--accent-light, rgba(0,0,0,0.03)); }
.cimis-station-row input { grid-area: cb; cursor: pointer; }
.cimis-station-main { grid-area: main; font-weight: 600; }
.cimis-station-meta { grid-area: meta; font-size: var(--text-xs); color: var(--text-muted); }

.cimis-view-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
}

.cimis-series-toggles,
.cimis-chart-toggles {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) 18px;
  align-items: center;
}

.cimis-chart-toggles {
  margin: var(--space-3) 0 var(--space-5) 0;
  padding: var(--space-3) var(--space-4);
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.cimis-toggle-label {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-muted);
}

.cimis-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-md);
  color: var(--text-muted);
  cursor: pointer;
}

.cimis-toggle input {
  cursor: pointer;
}

/* Per-graph "Data ▾" picker in the top-right of each CIMIS chart card. */
#cimis-charts .chart-container { position: relative; }

.cimis-chart-range-row {
  gap: var(--space-2) 10px;
  margin-bottom: 6px;
}
.cimis-chart-range-row label { font-size: var(--text-xs); }
.cimis-chart-range-row input {
  min-width: 0;
  width: 128px;
  padding: 5px 7px;
  font-size: var(--text-xs);
}
.cimis-chart-range-row .btn-small { padding: 5px 10px; font-size: var(--text-xs); }

.cimis-chart-picker-wrap {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: var(--z-dropdown);
}

.cimis-chart-picker-btn {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 3px 9px;
  font-size: var(--text-xs);
  color: var(--text-muted);
  cursor: pointer;
}
.cimis-chart-picker-btn:hover { background: var(--accent-light); }
.cimis-chart-picker-btn.overridden {
  border-color: var(--accent);
  color: var(--accent);
  font-weight: 600;
}

.cimis-chart-picker {
  display: none;
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  min-width: 200px;
  padding: 10px var(--space-3);
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-popover);
  flex-direction: column;
  gap: var(--space-2);
}
.cimis-chart-picker.open { display: flex; }
.cimis-chart-picker .cimis-toggle { font-size: var(--text-sm); }

.cimis-chart-picker-reset {
  margin-top: 2px;
  padding: var(--space-1) var(--space-2);
  font-size: var(--text-xs);
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--text-muted);
  cursor: pointer;
}
.cimis-chart-picker-reset:disabled { opacity: 0.45; cursor: default; }
.cimis-chart-picker-reset:not(:disabled):hover { background: var(--accent-light); }

.irrigation {
  margin-top: var(--space-6);
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

.irrigation h2 {
  margin: 0 0 var(--space-3) 0;
  font-size: var(--text-lg);
}

.irrigation-summary {
  color: var(--text-muted);
  font-size: var(--text-md);
  margin-bottom: var(--space-4);
}

.zone-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--space-3);
}

.zone-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px;
  /* Grid items default to min-width:auto, which lets a long unbreakable
     child (a wide slider, a long checkbox label) force the card past its
     grid track's width instead of shrinking/wrapping. */
  min-width: 0;
}

.zone-card h4 {
  margin: 0 0 var(--space-2) 0;
  font-size: var(--text-base);
}

.zone-card .rec {
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--accent);
  margin: 0 0 var(--space-1) 0;
}

.zone-card .rec.skip {
  color: var(--text-muted);
  font-size: var(--text-base);
  font-weight: 600;
}

.zone-card .detail {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin: 0 0 10px 0;
}

.zone-card .et-schedule-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0 0 10px 0;
}

.et-schedule-hour-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.et-schedule-hour-label input[type="range"] {
  width: 100px;
}

.zone-card .manual-zone-row {
  border-top: none;
  padding: 10px 0 0 0;
  margin-top: var(--space-1);
  justify-content: flex-start;
  gap: var(--space-1);
}

.zone-card .manual-zone-row .zone-name {
  flex: 0 0 100%;
  min-width: 0;
  margin: 0 0 var(--space-1) 0;
}

.zone-card .manual-zone-row input[type="number"] {
  text-align: right;
}

.zone-card .manual-zone-row button {
  margin-left: var(--space-4);
}

.rachio-error {
  background: var(--danger-bg);
  border: 1px solid var(--danger-border);
  color: var(--danger);
  border-radius: var(--radius-md);
  padding: var(--space-3) 14px;
  margin-bottom: var(--space-4);
  font-size: var(--text-sm);
  font-family: monospace;
  white-space: pre-wrap;
  word-break: break-word;
}

.status-pill {
  display: inline-block;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: 600;
}

.status-pill.online { background: var(--accent-light); color: var(--accent); }
.status-pill.offline { background: var(--danger-bg); color: var(--danger); }

/* Escalating risk states, shared by the header Fire Risk / Heat Advisory pills. */
.status-pill.level-calm   { background: var(--accent-light); color: var(--accent); }
.status-pill.level-warn   { background: var(--warn-bg);      color: var(--warn); }
.status-pill.level-danger { background: var(--danger-bg);    color: var(--danger); }

.device-actions {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}

.btn {
  border: none;
  border-radius: var(--radius-md);
  padding: var(--space-2) 14px;
  font-size: var(--text-sm);
  cursor: pointer;
  background: var(--accent);
  color: white;
}

.btn.secondary {
  background: white;
  color: var(--text);
  border: 1px solid var(--border);
}

.btn.danger {
  background: var(--danger-strong);
}

.btn:disabled {
  background: var(--border);
  color: var(--text-muted);
  cursor: not-allowed;
}

.btn:hover:not(:disabled) {
  opacity: 0.9;
}

.manual-zone-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-2) 0;
  border-top: 1px solid var(--border);
  flex-wrap: wrap;
}

.manual-zone-row:first-of-type { border-top: none; }

.manual-zone-row .zone-name {
  font-weight: 600;
  min-width: 140px;
}

.manual-zone-row input[type="number"] {
  width: 70px;
  padding: 6px var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

/* Shared by the Deficit Irrigation and Pressure Chamber Adjustment rows
   on each Scheduling zone card, so the two stay visually consistent --
   same container, same header line, same slider size, same checkbox
   line. Row-specific classes (.deficit-zone-*, .pressure-zone-*) only
   carry what's actually different between the two (e.g. the suggestion
   text under the pressure slider). */
.deficit-zone-row,
.pressure-zone-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 6px 10px;
  margin-bottom: var(--space-2);
  /* Own stacking context so nothing inside (a wide slider, a long
     checkbox label) can push the card wider than its grid column. */
  min-width: 0;
}

.deficit-zone-header,
.pressure-zone-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: var(--text-xs);
}

.deficit-zone-pct,
.pressure-zone-pct {
  font-weight: 600;
  min-width: 42px;
  text-align: right;
}

.deficit-zone-slider,
.pressure-zone-slider {
  width: 75%;
  max-width: 100%;
}

.deficit-zone-disregard,
.pressure-zone-auto {
  font-size: var(--text-sm);
  white-space: normal;
}

.pressure-zone-suggestion {
  font-size: var(--text-xs);
  color: var(--text-muted);
}

.schedule-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: 10px 0;
  border-top: 1px solid var(--border);
  flex-wrap: wrap;
}

.schedule-row:first-of-type { border-top: none; }

.schedule-row .sched-name {
  font-weight: 600;
  min-width: 160px;
}

.schedule-row input[type="number"] {
  width: 70px;
  padding: 6px var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.controller-power-block {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-3);
}

.controller-power-block .device-header { margin-bottom: var(--space-2); }
.controller-power-block .device-actions { margin-bottom: var(--space-2); }

.unit-toggle {
  display: flex;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.unit-btn {
  flex: 1;
  border: none;
  background: white;
  color: var(--text);
  padding: var(--space-2) 6px;
  font-size: var(--text-xs);
  cursor: pointer;
}

.unit-btn.active {
  background: var(--accent);
  color: white;
  font-weight: 600;
}

.unit-btn:not(.active):hover {
  background: var(--accent-light);
}

.settings-group {
  margin-bottom: var(--space-5);
  padding-bottom: var(--space-5);
  border-bottom: 1px solid var(--border);
}

.settings-group:last-of-type {
  border-bottom: none;
}

.settings-group h3 {
  margin: 0 0 10px 0;
  font-size: var(--text-md);
  color: var(--text-muted);
}

.settings-hint {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin: 0 0 10px 0;
}

.settings-row {
  display: flex;
  gap: var(--space-5);
  flex-wrap: wrap;
  margin-bottom: 10px;
}

.settings-row label {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-size: var(--text-xs);
  color: var(--text-muted);
}

.settings-row input,
.settings-row select {
  padding: var(--space-2) 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: var(--text-md);
  width: 100px;
}

.axis-row {
  align-items: center;
}

.axis-row .axis-label {
  width: 100%;
  font-size: var(--text-sm);
  font-weight: 600;
}

.axis-row input {
  width: 70px;
}

.settings-status {
  font-size: var(--text-sm);
  margin-bottom: 10px;
  min-height: 1.2em;
}

.settings-status.success { color: var(--accent); }
.settings-status.error { color: var(--danger-strong); }
.settings-status.warning { color: var(--warn-strong); }

/* ---------- Tabs ---------- */

.tabs {
  display: flex;
  gap: var(--space-1);
  padding: 0 var(--space-6);
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
}

.tabs::-webkit-scrollbar { display: none; }

.tab-btn {
  appearance: none;
  border: none;
  background: transparent;
  padding: var(--space-3) var(--space-5);
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
  border-bottom: 3px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
  flex-shrink: 0;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.tab-btn:hover {
  color: var(--text);
}

.tab-btn.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.tab-panel {
  animation: tab-fade-in 0.15s ease;
}

.tab-panel[hidden] {
  display: none;
}

@keyframes tab-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* ---------- Irrigation Calendar ---------- */

.irrigation-calendar {
  margin-bottom: var(--space-6);
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

.irrigation-calendar h2 {
  margin: 0 0 var(--space-3) 0;
  font-size: var(--text-lg);
}

.calendar-header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: 10px;
}

.calendar-header h3 {
  margin: 0;
  font-size: var(--text-base);
  flex: 1;
  text-align: center;
}

.btn-icon {
  appearance: none;
  border: 1px solid var(--border);
  background: var(--bg);
  border-radius: var(--radius-sm);
  width: 32px;
  height: 32px;
  font-size: var(--text-lg);
  line-height: 1;
  cursor: pointer;
  color: var(--text);
}

.btn-icon:hover { background: var(--accent-light); }

.btn-small {
  appearance: none;
  border: 1px solid var(--border);
  background: var(--bg);
  border-radius: var(--radius-sm);
  padding: 6px var(--space-3);
  font-size: var(--text-sm);
  cursor: pointer;
  color: var(--text);
}

.btn-small:hover { background: var(--accent-light); }

.btn-small:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  background: var(--bg);
}

.btn-small:disabled:hover {
  background: var(--bg);
}

.calendar-legend {
  display: flex;
  gap: var(--space-4);
  margin-bottom: 10px;
  font-size: var(--text-xs);
  color: var(--text-muted);
}

.legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.legend-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  display: inline-block;
}

.legend-dot.legend-past { background: var(--accent); }
.legend-dot.legend-future {
  background: transparent;
  border: 2px solid var(--accent);
}

.calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: var(--space-1);
}

.calendar-weekday {
  text-align: center;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-muted);
  padding-bottom: var(--space-1);
}

.calendar-day {
  min-height: 62px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 6px var(--space-1);
  cursor: pointer;
  background: var(--bg);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  transition: background 0.12s ease;
}

.calendar-day:hover { background: var(--accent-light); }

.calendar-day.empty {
  border: none;
  cursor: default;
  background: transparent;
}

.calendar-day.today {
  border-color: var(--accent);
  border-width: 2px;
}

.calendar-day.selected {
  background: var(--accent-light);
}

.calendar-day-num {
  font-size: var(--text-sm);
  font-weight: 600;
}

.calendar-day-dots {
  display: flex;
  gap: 3px;
  min-height: 9px;
}

.calendar-day-dots .legend-dot.legend-future {
  border-width: 1.5px;
}

.calendar-day-total {
  font-size: var(--text-2xs);
  font-weight: 600;
  line-height: 1.2;
}

.calendar-day-total.watered {
  color: var(--accent);
}

.calendar-day-total.scheduled {
  color: var(--text-muted);
  font-style: italic;
  font-weight: 500;
}

.calendar-flex-note {
  margin-top: var(--space-3);
  font-size: var(--text-xs);
  color: var(--text-muted);
}

.calendar-day-detail {
  margin-top: 14px;
  font-size: var(--text-md);
}

.calendar-day-detail:empty { margin-top: 0; }

.calendar-day-detail h4 {
  margin: 0 0 var(--space-2) 0;
  font-size: var(--text-md);
}

.calendar-day-detail ul {
  margin: 0;
  padding-left: 18px;
}

.calendar-day-detail li {
  margin-bottom: var(--space-1);
}

/* ---------- Water Use History ---------- */

.water-use {
  margin-bottom: var(--space-6);
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

.water-use h2 {
  margin: 0 0 var(--space-3) 0;
  font-size: var(--text-lg);
}

.water-use-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-2);
}

.range-btn-group {
  display: flex;
  gap: var(--space-1);
}

.range-btn {
  appearance: none;
  border: 1px solid var(--border);
  background: var(--bg);
  border-radius: var(--radius-sm);
  padding: 6px var(--space-3);
  font-size: var(--text-sm);
  cursor: pointer;
  color: var(--text);
}

.range-btn:hover { background: var(--accent-light); }

.range-btn.active {
  background: var(--accent);
  border-color: var(--accent);
  color: white;
}

.custom-range {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.custom-range input {
  width: 90px;
  padding: 6px var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
}

.precip-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.toggle-group {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-left: auto;
}

.water-use-hint {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin: 0 0 var(--space-3) 0;
}

/* ---------- Zone Flow Rates (content lives inside .zone-flow-dialog) ---------- */

.zone-flow-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 10px;
  margin: var(--space-4) 0;
}

.zone-flow-row {
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
  background: var(--bg);
}

.zone-flow-row .zone-flow-name {
  flex: 1;
  font-size: var(--text-md);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.zone-flow-row input[type="number"] {
  width: 70px;
  padding: 6px var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
}

.zone-flow-row select {
  padding: 6px var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
}

.zone-flow-unit {
  font-size: var(--text-xs);
  color: var(--text-muted);
}

.zone-flow-dialog {
  border: none;
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  max-width: 640px;
  width: 90%;
  max-height: 80vh;
  overflow-y: auto;
  background: var(--card-bg);
  color: var(--text);
  box-shadow: var(--shadow-dialog);
}

.zone-flow-dialog::backdrop {
  background: rgba(0,0,0,0.45);
}

.dialog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-2);
}

.dialog-header h2 {
  margin: 0;
  font-size: var(--text-lg);
}

/* ---------- Irrigation tab header / general settings ---------- */

.irrigation-tab-header {
  display: flex;
  justify-content: flex-end;
  margin-bottom: var(--space-3);
}

.settings-subsection {
  margin-top: var(--space-2);
}

.settings-subsection h3 {
  margin: 0 0 var(--space-2) 0;
  font-size: var(--text-base);
}

.settings-subsection + .settings-subsection {
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border);
}

/* ---------- Water Use zone select ---------- */

.zone-select-wrap {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: var(--space-2);
  flex-wrap: wrap;
}

.zone-select-buttons {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.zone-select-wrap label {
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.zone-select-wrap select {
  min-width: 220px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  padding: var(--space-1);
}

/* ---------- Zone Run Log ---------- */

.zone-run-log {
  margin-bottom: var(--space-6);
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

.zone-run-log h2 {
  margin: 0 0 var(--space-2) 0;
  font-size: var(--text-lg);
}

.run-log-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-5);
  margin: 14px 0 var(--space-2) 0;
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.run-log-controls select#run-log-days-back {
  padding: 6px var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
}

.run-log-table-wrap {
  overflow-x: auto;
  max-height: 420px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.run-log-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.run-log-table th {
  position: sticky;
  top: 0;
  background: var(--bg);
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border);
  font-weight: 600;
}

.run-log-table td {
  padding: 6px var(--space-3);
  border-bottom: 1px solid var(--border);
}

.run-log-table tr:last-child td {
  border-bottom: none;
}

.run-log-table .zone-unresolved {
  color: var(--text-muted);
  font-style: italic;
}

/* ---------- Fertigation & Pest Log ---------- */

.fert-pest-section {
  margin-bottom: var(--space-6);
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

.fert-pest-section h2 {
  margin: 0 0 14px 0;
  font-size: var(--text-lg);
}

.log-form {
  margin-bottom: var(--space-4);
}

.log-form-row {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-bottom: 10px;
}

.log-form-row label {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-size: var(--text-xs);
  color: var(--text-muted);
}

.log-form-row input,
.log-form-row select {
  padding: 7px 9px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  min-width: 130px;
}

.log-form-row input[type="radio"],
.log-form-row input[type="checkbox"] {
  padding: 0;
  border: none;
  min-width: 0;
  width: auto;
  flex: 0 0 auto;
}

.log-notes-label {
  flex: 1;
  min-width: 200px;
}

.log-notes-label input {
  width: 100%;
  min-width: 200px;
}

.log-table-wrap {
  overflow-x: auto;
  max-height: 360px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.log-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.log-table th {
  position: sticky;
  top: 0;
  background: var(--bg);
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border);
  font-weight: 600;
}

.log-table td {
  padding: 6px var(--space-3);
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}

.log-table tr:last-child td {
  border-bottom: none;
}

.log-delete-btn {
  appearance: none;
  border: 1px solid var(--border);
  background: var(--bg);
  border-radius: var(--radius-sm);
  padding: 3px var(--space-2);
  font-size: var(--text-xs);
  cursor: pointer;
  color: var(--text-muted);
}

.log-delete-btn:hover {
  background: var(--danger-bg);
  color: var(--danger-strong);
  border-color: var(--danger-strong);
}

.severity-low { color: var(--accent); }
.severity-medium { color: var(--warn-strong); }
.severity-high { color: var(--danger-strong); font-weight: 600; }

/* ---------- Global API & Site Settings dialog ---------- */

.wide-dialog {
  max-width: 760px;
}

.restart-badge {
  display: inline-block;
  font-size: var(--text-2xs);
  font-weight: 500;
  color: var(--danger-strong);
  background: var(--danger-bg);
  border-radius: var(--radius-sm);
  padding: 2px 7px;
  margin-left: var(--space-2);
  vertical-align: middle;
}

.checkbox-label {
  flex-direction: row !important;
  align-items: center;
  gap: 6px !important;
}

.kc-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
  gap: 10px;
}

.kc-grid label {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-align: center;
}

.kc-grid input {
  padding: 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  text-align: center;
  font-size: var(--text-sm);
  width: 100%;
}

/* ---------- Forecast & Alerts ---------- */

.alerts-section {
  margin-bottom: var(--space-6);
  background: var(--warn-bg);
  border: 1px solid var(--warn-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

.alerts-section h2 {
  margin: 0 0 var(--space-3) 0;
  font-size: var(--text-lg);
  color: var(--warn);
}

.alert-card {
  background: white;
  border-left: 4px solid var(--danger-strong);
  border-radius: var(--radius-sm);
  padding: var(--space-3) 14px;
  margin-bottom: 10px;
}

.alert-card:last-child { margin-bottom: 0; }

.alert-card.severity-minor { border-left-color: var(--warn-strong); }
.alert-card.severity-moderate { border-left-color: var(--warn-strong); }
.alert-card.severity-severe { border-left-color: var(--danger-strong); }
.alert-card.severity-extreme { border-left-color: var(--danger-extreme); }

.alert-event {
  font-weight: 700;
  margin-bottom: 2px;
}

.alert-headline {
  font-size: var(--text-md);
  margin-bottom: 6px;
}

.alert-meta {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-bottom: 6px;
}

.alert-description {
  font-size: var(--text-sm);
  color: var(--text);
  white-space: pre-line;
  max-height: 120px;
  overflow-y: auto;
}

.forecast-section {
  margin-bottom: var(--space-6);
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

.forecast-section h2 {
  margin: 0 0 10px 0;
  font-size: var(--text-lg);
}

.forecast-table-wrap {
  overflow-x: auto;
}

.forecast-table th, .forecast-table td {
  white-space: nowrap;
}

.forecast-error {
  color: var(--danger-strong);
  font-weight: 600;
  background: var(--danger-bg);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
}

/* ---------- Weather condition icons ---------- */

/* The sprite itself never renders -- it only holds <symbol>s for <use> to
   reference. It lives just inside <body> rather than in the Forecast panel
   because that panel carries the `hidden` attribute. */
.wx-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* CSS selectors cannot reach inside a <use> shadow tree -- only INHERITED
   properties cross that boundary. So every stroke/fill setting is declared
   here on the wrapper and inherits down, and the two-tone accents are done
   with custom properties (which also inherit) that the symbols read as
   var(--wx-accent) / var(--wx-wet). Setting a stroke on the <symbol>s
   themselves would win over inheritance and make them untheme-able. */
.wx-icon {
  display: block;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--wx-default);
}

.wx-icon[data-code="clear"] { color: var(--wx-sun); --wx-accent: var(--wx-sun); }
.wx-icon[data-code="partly-cloudy"],
.wx-icon[data-code="mostly-cloudy"] { --wx-accent: var(--wx-sun); }
.wx-icon[data-code="rain"],
.wx-icon[data-code="showers"] { --wx-accent: var(--wx-sun); --wx-wet: var(--wx-rain); }
.wx-icon[data-code="thunderstorm"] { --wx-accent: var(--wx-storm-sun); --wx-wet: var(--wx-rain); color: var(--wx-storm); }
.wx-icon[data-code="snow"],
.wx-icon[data-code="sleet"],
.wx-icon[data-code="freezing-rain"] { --wx-wet: var(--wx-ice); }
.wx-icon[data-code="smoke"] { color: var(--wx-smoke); }
.wx-icon[data-code="hot"] { color: var(--danger-strong); }
.wx-icon[data-code="cold"] { color: var(--wx-cold); }
.wx-icon[data-code="severe"] { color: var(--danger-extreme); }
.wx-icon[data-code="unknown"] { color: var(--text-muted); }

/* Moon glyph (moonIcon() in script.js) -- same stroke treatment as the
   weather sprite, in a cool moonlit silver so it reads as night, not sun. */
.wx-icon[data-code="moon"] { color: var(--wx-moon); }

/* ---------- Forecast: "Right Now" hero ---------- */

.forecast-hero {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px 28px;
}

.forecast-hero-main {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

.forecast-hero-icon .wx-icon { width: 68px; height: 68px; }

.forecast-hero-temp {
  font-size: var(--text-display);
  font-weight: 700;
  line-height: 1;
}

.forecast-hero-cond {
  font-size: var(--text-base);
  margin-top: var(--space-1);
}

.forecast-hero-hilo {
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin-top: 2px;
}

.forecast-hero-metrics {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 26px;
  margin-left: auto;
}

.forecast-metric-label {
  font-size: var(--text-2xs);
  color: var(--text-muted);
}

.forecast-metric-value {
  font-size: var(--text-base);
  font-weight: 600;
}

.forecast-hero-note { margin-bottom: 0; }

/* ---------- Header: "Right Now" live band ----------
   A small reference line (time · date · daylight, alerts, freshness), then
   one row: conditions | the sun's flat path | the moon flush right, then the
   readings. The time is deliberately small -- it's a reference, not the
   headline. */

.hero-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px var(--space-4);
}
.hero-ref { font-size: var(--text-md); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.hero-ref b { color: var(--text); font-weight: 600; }
.current-hero-updated {
  margin-left: auto;
  font-size: var(--text-xs);
  color: var(--text-muted);
  white-space: nowrap;
}
.current-hero-updated.stale { color: var(--danger); }

/* Alerts: a small chip per active alert (warn/danger) that opens the
   matching tab; calm sources collapse into one quiet note. */
.hero-alerts { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.hero-alert-chips { display: contents; }
.hero-alert {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
  transition: border-color 150ms ease-out;
}
.hero-alert.level-warn   { background: var(--warn-bg);   color: var(--warn); }
.hero-alert.level-danger { background: var(--danger-bg); color: var(--danger); }
.hero-alert:hover { border-color: currentColor; }
.hero-alert:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
.hero-alert-dot { flex: none; width: 7px; aspect-ratio: 1; border-radius: 50%; background: currentColor; }
.hero-alert-chev { font-size: var(--text-base); line-height: 1; }
.hero-alert-calm { font-size: var(--text-sm); color: var(--text-muted); }
.hero-alert-info {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--text-muted);
  cursor: pointer;
}
.hero-alert-info:hover { color: var(--text); text-decoration: underline; }
.hero-alert-info:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.hero-row {
  display: flex;
  align-items: center;
  gap: var(--space-4) 40px;
  margin-top: var(--space-3);
}
.current-hero-section .forecast-hero-main { flex: none; }
.current-hero-section .forecast-hero-icon .wx-icon { width: 84px; height: 84px; }
.current-hero-section .forecast-hero-temp,
.current-hero-section .forecast-metric-value { font-variant-numeric: tabular-nums; }
.current-hero-section .forecast-hero-cond { text-wrap: balance; }
.current-hero-section .forecast-hero-hilo { text-wrap: pretty; }

/* The sun's path sits centred between the conditions and the moon, capped
   so its rise/set labels keep clear space from the text on either side. */
.hero-sky { flex: 0 1 572px; max-width: 572px; min-width: 0; margin-inline: auto; display: flex; flex-direction: column; align-items: center; }
.hero-sky[hidden] { display: none; }
.hero-sky-arc { display: block; width: 100%; height: auto; max-height: 90px; overflow: visible; }
.hero-sky-horizon { stroke: var(--border); stroke-width: 1.5; }
.hero-sky-track { fill: none; stroke: var(--border); stroke-width: 1.5; stroke-dasharray: 1 1.6; }
.hero-sky-progress { fill: none; stroke: var(--warn); stroke-width: 2.5; stroke-linecap: round; stroke-dasharray: 0 100; }
/* While the moon has the path (after dark), its progress is a moonlit silver. */
.hero-sky-arc.moon .hero-sky-progress { stroke: var(--moon-path); }
/* Fallback only: moon.js fitHeroSkyLabels() sets the size from the path's
   drawn width so the labels render ~12px at any screen width. */
.hero-sky-time { font-size: 12px; fill: var(--text-muted); font-variant-numeric: tabular-nums; }
.hero-sky-note { font-size: var(--text-xs); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.hero-sky-note:empty { display: none; }

/* The moon: same size as the weather icon, flush right, text on its left. */
.hero-moon { flex: none; display: flex; align-items: center; gap: var(--space-3); margin-left: auto; text-align: right; }
/* While the path is showing, its own auto margins centre it and still push
   the moon flush right; the moon's margin would otherwise skew the centring. */
.hero-sky:not([hidden]) + .hero-moon { margin-left: 0; }
.hero-moon-img .moon-photo { width: 84px; height: 84px; }
.hero-moon-phase { font-weight: 600; }
.hero-moon-lit,
.hero-moon-when { font-size: var(--text-sm); color: var(--text-muted); font-variant-numeric: tabular-nums; }

/* The header band's metric readout runs a touch larger than the Forecast
   sub-tab's hero -- it's the always-on at-a-glance strip. Scoped so the
   Forecast hero keeps its own smaller sizing. */
.current-hero-section .forecast-metric-label { font-size: var(--text-xs); }
.current-hero-section .forecast-metric-value { font-size: var(--text-lg); }
.current-hero-section .current-hero-metrics {
  margin: var(--space-3) 0 0;
  padding-top: var(--space-3);
  border-top: 1px solid var(--border);
  justify-content: space-between;
}

/* ---------- Forecast: hourly strip ---------- */

/* Stays a horizontal scroller at every width -- 24 tiles never fit, and a
   wrapping grid would break the left-to-right reading of time. */
.forecast-hourly-strip {
  display: flex;
  gap: var(--space-1);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  padding-bottom: var(--space-2);
}

.forecast-hour {
  flex: 0 0 58px;
  scroll-snap-align: start;
  text-align: center;
  padding: var(--space-2) 2px;
  border-radius: var(--radius-md);
}

.forecast-hour.is-now { background: var(--accent-light); }

.forecast-hour-time {
  font-size: var(--text-2xs);
  color: var(--text-muted);
  margin-bottom: var(--space-1);
}

.forecast-hour .wx-icon {
  width: 24px;
  height: 24px;
  margin: 0 auto var(--space-1) auto;
}

.forecast-hour-temp {
  font-size: var(--text-md);
  font-weight: 600;
}

.forecast-hour-precip {
  font-size: var(--text-2xs);
  color: var(--rain-text);
  min-height: 1em;
}

/* ---------- Forecast: 7-day cards ---------- */

.forecast-days {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(104px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}

.forecast-day {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 10px var(--space-2);
  text-align: center;
}

.forecast-day.is-today {
  border-color: var(--accent);
  background: var(--accent-light);
}

.forecast-day-name {
  font-size: var(--text-xs);
  font-weight: 700;
}

.forecast-day-date {
  font-size: var(--text-2xs);
  color: var(--text-muted);
  margin-bottom: 6px;
}

.forecast-day .wx-icon {
  width: 38px;
  height: 38px;
  margin: 0 auto 6px auto;
}

.forecast-day-temps {
  font-size: var(--text-sm);
  font-weight: 600;
  display: flex;
  justify-content: center;
  gap: 6px;
}

.forecast-day-lo { color: var(--text-muted); font-weight: 500; }

/* Range bar. JS supplies only two unitless numbers as custom properties --
   where this day's low sits in the whole week's low-to-high span, and how
   wide its own low-to-high range is. Both are computed in canonical
   Fahrenheit so switching to metric relabels the card without shifting the
   bars, since the bar is a comparison across the week, not a reading. */
.forecast-range {
  position: relative;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--border);
  margin: 7px 0;
  overflow: hidden;
}

.forecast-range-fill {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--range-start, 0) * 100%);
  width: calc(var(--range-width, 1) * 100%);
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--temp-cold) 0%, var(--temp-mild) 45%, var(--wx-sun) 78%, var(--temp-hot) 100%);
}

.forecast-range.no-range .forecast-range-fill { display: none; }

.forecast-day-precip {
  font-size: var(--text-xs);
  color: var(--rain-text);
  min-height: 1em;
}

/* NWS's own wording, clipped to one line at card width. The card's title
   attribute carries the untruncated text plus the wind. */
.forecast-day-cond {
  font-size: var(--text-2xs);
  color: var(--text-muted);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.forecast-agreement {
  display: inline-block;
  margin-top: 6px;
  padding: 2px var(--space-2);
  border-radius: var(--radius-pill);
  font-size: var(--text-2xs);
  font-weight: 600;
}

.forecast-agreement.agree { background: var(--accent-light); color: var(--accent); }
.forecast-agreement.close { background: var(--warn-bg); color: var(--warn); }
.forecast-agreement.differ { background: var(--danger-bg); color: var(--danger); }

.forecast-empty,
.forecast-hourly-empty {
  color: var(--text-muted);
  font-size: var(--text-md);
  padding: 14px 0;
}

/* ---------- Weather icons: Meteocons "fill" ---------- */

/* wxIcon() now returns a <span class="wx-icon wx-meteocon"> holding the
   Meteocons SVG as an <img>; every existing .wx-icon size rule still sizes
   the box. The artwork sits inside a 64-unit box with generous padding, so
   it's scaled up a little to match the old line icons' optical size. */
.wx-meteocon { position: relative; }
.wx-meteocon > img {
  display: block;
  width: 100%;
  height: 100%;
  transform: scale(1.2);
}
.wx-meteocon > .wx-meteocon-wind {
  position: absolute;
  right: -12%;
  bottom: -12%;
  width: 55%;
  height: 55%;
  transform: none;
}

/* ---------- Sun & Moon (moon.js) ---------- */

/* Photo moon: the night side is a near-black overlay that lets a little of
   the photo through as earthshine. */
.moon-photo { display: block; overflow: visible; }
.moon-photo-shadow { fill: var(--moon-shadow); opacity: 0.86; }

/* Sun times line on each 7-day forecast card */
.forecast-day-sun {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0 6px;
  margin-top: 4px;
  font-size: var(--text-2xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.forecast-day-sun span { display: inline-flex; align-items: center; white-space: nowrap; }
.forecast-day-sun img { width: 20px; height: 20px; margin: -3px -2px -3px -4px; }

/* 7-Day Moon cards reuse .forecast-day; these only add the moon rows. */
.moon-day { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.moon-day .moon-photo { width: 64px; height: 64px; margin: 4px 0 6px; }
.moon-day-phase { font-size: var(--text-xs); font-weight: 600; }
.moon-day-illum {
  font-size: var(--text-2xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.moon-day-rs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0 6px;
  font-size: var(--text-2xs);
  font-variant-numeric: tabular-nums;
}
.moon-day-chip { margin-top: 4px; font-size: var(--text-2xs); padding: 2px 8px; }
.moon-day-path { font-size: var(--text-2xs); color: var(--text-muted); }
.moon-day-badge {
  margin-top: 4px;
  padding: 1px var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--moon-badge-bg);
  color: var(--moon-badge-text);
  font-size: var(--text-2xs);
  font-weight: 600;
}
.moon-day-caution {
  margin-top: 2px;
  padding: 1px var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--warn-bg);
  color: var(--warn);
  font-size: var(--text-2xs);
}

.moon-details {
  display: grid;
  /* Fixed column counts, not auto-fit: the full-width Sky events card would
     otherwise hold an empty extra track open and squeeze the others. */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-3);
}
.moon-detail-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.moon-detail-card h3 { margin: 0 0 2px; font-size: var(--text-md); }
.moon-detail-card .bd-day-chip { align-self: flex-start; }
.moon-detail-row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  font-size: var(--text-sm);
}
.moon-detail-label { color: var(--text-muted); flex: none; }
.moon-detail-value { text-align: right; font-variant-numeric: tabular-nums; }
.moon-detail-note { font-size: var(--text-xs); color: var(--text-muted); }
.moon-detail-tasks { margin: 0; padding-left: 18px; font-size: var(--text-sm); }

/* Night-sky cards for the 7-Day Moon row (the photo moon reads best on dark). */
.moon-days .moon-day {
  background: var(--night-bg);
  border-color: var(--night-border);
  color: var(--night-text);
}
.moon-days .moon-day.is-today { border-color: var(--night-muted); }
.moon-days .moon-day .forecast-day-date,
.moon-day-illum,
.moon-day-path { color: var(--night-muted); }
.moon-days .moon-day-badge { background: var(--moon-gold); color: var(--moon-ink); }
.moon-day-event {
  margin-top: 4px;
  padding: 1px var(--space-2);
  border-radius: var(--radius-pill);
  border: 1px solid var(--night-muted);
  color: var(--night-text);
  font-size: var(--text-2xs);
  text-align: center;
}

.moon-detail-wide { grid-column: 1 / -1; }
@media (max-width: 1100px) { .moon-details { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .moon-details { grid-template-columns: minmax(0, 1fr); } }
.sky-events {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-3) var(--space-4);
}
.sky-event { display: flex; flex-direction: column; gap: 2px; }
.sky-event-head { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 2px var(--space-2); }
.sky-event-name { font-weight: 600; font-size: var(--text-sm); }
.sky-event-when { font-size: var(--text-xs); color: var(--text-muted); font-variant-numeric: tabular-nums; }

@media (max-width: 720px) {
  /* Below this the 7-day grid would wrap to two ragged rows, so it becomes
     a snap-scroller instead -- the same interaction as the hourly strip
     directly above it, rather than a second thing to learn. */
  .forecast-days {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    padding-bottom: var(--space-2);
  }

  .forecast-day {
    flex: 0 0 106px;
    scroll-snap-align: start;
  }

  .forecast-hero { justify-content: center; text-align: center; }
  .forecast-hero-metrics { margin-left: 0; justify-content: center; }
  .forecast-hero-temp { font-size: var(--text-2xl); }
  /* Phone: the time line keeps "Live · updated" at its right end and the
     alerts drop below it; the sun (weather icon) and the moon share one row
     with the sun's path underneath. */
  .hero-top { align-items: flex-end; gap: 6px var(--space-3); }
  .hero-ref { flex: 1 1 0; min-width: 0; font-size: var(--text-xs); }
  .current-hero-updated { font-size: var(--text-2xs); }
  .hero-alerts { order: 3; flex-basis: 100%; }
  .hero-alert { min-height: 36px; }
  .hero-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: var(--space-2) 10px;
  }
  .current-hero-section .forecast-hero-main { gap: var(--space-2); justify-content: flex-start; text-align: left; }
  .current-hero-section .forecast-hero-icon .wx-icon { width: 48px; height: 48px; }
  .current-hero-section .forecast-hero-temp { font-size: 1.6rem; }
  .current-hero-section .forecast-hero-cond { font-size: var(--text-sm); }
  /* Clamped to two lines here: the wind it ends with is in the readings row too. */
  .current-hero-section .forecast-hero-hilo {
    font-size: var(--text-2xs);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .hero-moon { gap: var(--space-2); }
  .hero-moon-img .moon-photo { width: 48px; height: 48px; }
  .hero-moon-phase { font-size: var(--text-sm); }
  .hero-moon-lit, .hero-moon-when { font-size: var(--text-2xs); }
  .hero-sky { grid-column: 1 / -1; order: 3; width: 100%; max-width: none; margin-inline: 0; }
  .hero-sky-arc { max-height: none; }
  .hero-sky-time { font-size: 20px; }
}

/* ---------- Irrigation Recommendation Controls ---------- */

.manual-watering-actions {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin: var(--space-2) 0 var(--space-4) 0;
}

.recommendation-controls {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

.deficit-control, .heatwave-control {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px var(--space-4);
}

.deficit-control label {
  font-size: var(--text-md);
  display: block;
  margin-bottom: var(--space-2);
}

.deficit-control input[type="range"] {
  width: 100%;
  margin-bottom: 6px;
}

.heatwave-status {
  font-size: var(--text-sm);
  font-weight: 600;
  padding: 6px 10px;
  border-radius: var(--radius-sm);
  margin-bottom: 10px;
  background: var(--card-bg);
  border: 1px solid var(--border);
  color: var(--text-muted);
}

.heatwave-status.active {
  background: var(--warn-bg);
  border-color: var(--warn-border);
  color: var(--warn);
}

.heatwave-control .checkbox-label {
  margin-bottom: var(--space-2);
  font-size: var(--text-md);
}

#heatwave-detail-controls {
  margin-bottom: var(--space-2);
}

#heatwave-detail-controls input {
  width: 70px;
}

.heatwave-note {
  font-size: var(--text-sm);
  background: var(--warn-bg);
  border: 1px solid var(--warn-border);
  border-radius: var(--radius-md);
  padding: 10px var(--space-3);
  margin-top: 10px;
  color: var(--warn);
}

.pressure-control {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px var(--space-4);
  grid-column: 1 / -1;
}

/* ---------- Zone Details ---------- */

.zone-details-section {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

.zone-details-section h2 {
  margin: 0 0 var(--space-2) 0;
  font-size: var(--text-lg);
}

.zone-details-select-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  margin: 14px 0;
}

.zone-details-select-row select {
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: var(--text-md);
}

.zone-details-grid {
  display: block;
}

.soil-reference-box {
  font-size: var(--text-xs);
  color: var(--text-muted);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 10px var(--space-3);
  margin-bottom: 14px;
  min-height: 1.2em;
}

.soil-reference-box strong {
  color: var(--text);
}

.zone-details-map-panel h3 {
  margin: 0 0 6px 0;
  font-size: var(--text-base);
}

#zonedetails-map,
#croparea-map {
  height: 360px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  margin: 10px 0;
}

.croparea-zone-checklist {
  display: flex;
  flex-wrap: wrap;
  gap: 6px var(--space-4);
  margin: var(--space-1) 0 var(--space-3) 0;
}

.croparea-zone-checklist label {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 6px;
  font-size: var(--text-md);
}

.croparea-zone-checklist:empty::before {
  content: "No Rachio zones loaded yet.";
  color: var(--text-muted);
  font-size: var(--text-sm);
}

.map-area-readout {
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--accent);
  margin-bottom: 10px;
}

.map-buttons {
  display: flex;
  gap: 10px;
}

/* ---------- Fire Risk ---------- */

.fire-map-section {
  margin-bottom: var(--space-6);
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

.fire-map-section h2 {
  margin: 0 0 var(--space-3) 0;
  font-size: var(--text-lg);
}

.fire-alert-banner {
  background: var(--danger-bg);
  border: 1px solid var(--danger);
  border-radius: var(--radius-md);
  padding: 10px 14px;
  margin-bottom: var(--space-3);
  font-size: var(--text-md);
}

.fire-alert-banner strong {
  color: var(--danger);
}

.fire-nearest-box {
  font-size: var(--text-md);
  margin-bottom: var(--space-3);
}

.fire-nearest-box strong {
  color: var(--accent);
}

.fire-map {
  height: 340px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  margin: 10px 0;
}

.fire-incident-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px;
}

.fire-incident-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 10px var(--space-3);
  background: var(--bg);
  font-size: var(--text-sm);
}

.pest-reference-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px;
}

.pest-reference-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 10px var(--space-3);
  background: var(--bg);
  font-size: var(--text-sm);
}

.pest-reference-card h3 { font-size: 1em; margin-block: 1.33em; }  /* was an h4; keep its look */

.pest-reference-card img {
  width: 100%;
  max-height: 120px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  margin-bottom: 2px;
}

.pest-reference-card .photo-credit {
  font-size: var(--text-2xs);
  color: var(--text-muted);
  margin-bottom: 6px;
}

.pest-reference-card .warning {
  color: var(--warn);
  font-weight: 600;
}

.fire-incident-card h3 {
  margin: 0 0 var(--space-1) 0;
  font-size: var(--text-md);
}

.fire-incident-card .distance {
  color: var(--text-muted);
  font-size: var(--text-xs);
}

.farm-marker {
  font-size: 20px;
  text-align: center;
  line-height: 24px;
}

/* ---------- Fire History ---------- */

.fire-history-panel {
  margin-top: 18px;
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
}

.fire-history-panel > h3 {
  margin: 0 0 6px 0;
  font-size: var(--text-base);
}

.fire-history-panel input[type="date"],
.fire-history-panel .dtp-display {
  padding: 6px var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
}

.fire-incident-card.historical {
  opacity: 0.75;
}

.fire-incident-card.selected {
  border-color: var(--info);
  border-width: 2px;
  background: var(--info-bg);
  opacity: 1;
}

/* ---------- Weather Sub-Tabs ---------- */

.subtabs {
  display: flex;
  gap: var(--space-1);
  flex-wrap: wrap;
  margin-top: 18px;
  margin-bottom: var(--space-5);
  padding-bottom: var(--space-1);
  border-bottom: 1px dashed var(--border);
}

.subtab-btn {
  appearance: none;
  border: 1px solid var(--border);
  background: var(--bg);
  border-radius: var(--radius-pill);
  padding: 7px var(--space-4);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
  transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}

.subtab-btn:hover {
  color: var(--text);
  background: var(--accent-light);
}

.subtab-btn.active {
  color: white;
  background: var(--accent);
  border-color: var(--accent);
}

.subtab-panel[hidden] {
  display: none;
}

/* ---------- Soil Lookup (SSURGO) ---------- */

.soil-lookup-result {
  background: var(--info-bg);
  border: 1px solid var(--info-border);
  border-radius: var(--radius-md);
  padding: 10px 14px;
  margin-bottom: var(--space-3);
  font-size: var(--text-sm);
  line-height: 1.5;
}

.soil-lookup-result .lookup-title {
  font-weight: 700;
  margin-bottom: var(--space-1);
}

.soil-lookup-result .lookup-error {
  color: var(--danger);
}

.soil-lookup-result a {
  color: var(--info);
}

.soil-advanced-details {
  margin-bottom: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 10px 14px;
  background: var(--bg);
}

.soil-advanced-details summary {
  cursor: pointer;
  font-weight: 600;
  font-size: var(--text-md);
}

.soil-advanced-details[open] summary {
  margin-bottom: var(--space-2);
}

.soil-lookup-buttons {
  margin-top: 6px;
}

/* ---------- Property Boundary ---------- */

.property-boundary-section {
  background: var(--highlight-bg);
  border: 1px solid var(--highlight-border);
  border-radius: var(--radius-lg);
  padding: 14px var(--space-4);
  margin-bottom: 18px;
}

.property-boundary-section h3 {
  margin: 0 0 6px 0;
  font-size: var(--text-base);
}

.property-soil-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-top: 10px;
}

.pest-thumb,
.abiotic-thumb,
.croptest-thumb {
  width: 48px;
  height: 48px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  cursor: zoom-in;
}

.soil-field-group-label {
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--text-muted);
  display: block;
  margin-top: 6px;
}

.nutrient-ref-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 10px 14px;
  margin-bottom: 10px;
  background: var(--bg);
  font-size: var(--text-sm);
}

.nutrient-ref-card h4 {
  margin: 0 0 var(--space-1) 0;
  font-size: var(--text-md);
}

.amendment-card {
  border-left: 4px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  margin-bottom: var(--space-2);
  background: var(--card-bg);
  border: 1px solid var(--border);
}

.amendment-card.status-low { border-left-color: var(--warn-strong); }
.amendment-card.status-high { border-left-color: var(--danger-strong); }
.amendment-card.status-optimal { border-left-color: var(--ok); opacity: 0.75; }

.amendment-card h4 {
  margin: 0 0 var(--space-1) 0;
  font-size: var(--text-md);
}

.amendment-card .amendment-action {
  font-size: var(--text-sm);
  margin-top: var(--space-1);
}

/* Compact crop-area tiles (Zone Details' "Saved crop areas") -- a smaller,
   grid-wrapped variant of .amendment-card so several fit per row instead of
   one full-width card each. */
.croparea-tile-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.croparea-tile {
  flex: 0 1 190px;
  border-left: 3px solid var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 6px 10px;
  background: var(--card-bg);
}

.croparea-tile.status-optimal { border-left-color: var(--ok); opacity: 0.75; }

.croparea-tile h4 {
  margin: 0 0 2px 0;
  font-size: var(--text-xs);
}

.croparea-tile .amendment-action {
  font-size: var(--text-2xs);
  color: var(--text-muted);
  margin-bottom: var(--space-1);
}

.croparea-tile .btn-small {
  padding: 2px var(--space-2);
  font-size: var(--text-2xs);
}

/* ---------- Soil Test Report Upload + Sample Map ---------- */

.soiltest-dropzone {
  border: 2px dashed var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-6) var(--space-4);
  text-align: center;
  cursor: pointer;
  background: var(--bg);
  transition: border-color 0.15s ease, background 0.15s ease;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 120px;
}

.soiltest-dropzone.dragover {
  border-color: var(--accent);
  background: var(--accent-light);
}

.soiltest-dropzone.upload-success {
  border-color: var(--ok);
  border-style: solid;
  background: var(--ok-bg);
}

.soiltest-dropzone.locked {
  cursor: not-allowed;
  opacity: 0.5;
  pointer-events: none;
}

.soiltest-zone-first-row {
  background: var(--highlight-bg);
  border: 1px solid var(--highlight-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-1);
}

.soiltest-zone-first-row select {
  font-size: var(--text-base);
  font-weight: 600;
  padding: 6px 10px;
}

.soiltest-dropzone-filename {
  margin-top: var(--space-2);
  font-weight: 600;
  font-size: var(--text-sm);
  color: var(--accent);
}

/* Generic report drop-zone, shared by initReportDropZone() -- currently
   used by the Water Bill log; soil test's own .soiltest-dropzone above is
   a planned future migration onto this same shared styling. */
.report-dropzone {
  border: 2px dashed var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-6) var(--space-4);
  text-align: center;
  cursor: pointer;
  background: var(--bg);
  transition: border-color 0.15s ease, background 0.15s ease;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 120px;
}

.report-dropzone.dragover {
  border-color: var(--accent);
  background: var(--accent-light);
}

.report-dropzone.upload-success {
  border-color: var(--ok);
  border-style: solid;
  background: var(--ok-bg);
}

.report-dropzone-filename {
  margin-top: var(--space-2);
  font-weight: 600;
  font-size: var(--text-sm);
  color: var(--accent);
}

.soiltest-sample-map-panel #soiltest-sample-map {
  height: 420px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  margin: var(--space-2) 0;
}

.soiltest-sample-map-panel-full {
  width: 100%;
  margin-bottom: 18px;
}

.soiltest-sample-map-panel-full #soiltest-sample-map {
  height: 65vh;
  min-height: 420px;
  max-height: 700px;
}

.sample-map-toolbar {
  display: flex;
  gap: 10px;
  margin-bottom: 6px;
}

#soiltest-sample-eraser-toggle.active {
  background: var(--danger-strong);
  color: white;
  border-color: var(--danger-strong);
}

#soiltest-edit-sample-map {
  height: 350px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  margin: var(--space-2) 0;
}

#soiltest-edit-sample-eraser-toggle.active {
  background: var(--danger-strong);
  color: white;
  border-color: var(--danger-strong);
}

.sample-x-marker {
  color: var(--danger-strong);
  font-size: 20px;
  font-weight: 900;
  text-align: center;
  line-height: 20px;
  text-shadow: 0 0 3px white, 0 0 3px white, 0 0 3px white;
}

.soiltest-overview-marker {
  font-size: 20px;
  font-weight: 900;
  text-align: center;
  line-height: 20px;
  text-shadow: 0 0 3px white, 0 0 3px white, 0 0 3px white;
  transition: transform 0.1s ease;
}

.soiltest-overview-marker-hover {
  transform: scale(1.25);
}

.soiltest-overview-tooltip {
  font-size: 12px;
}

.soiltest-row-highlighted {
  background: var(--info-bg);
}

.soiltest-check-col {
  width: 32px;
  text-align: center;
  padding-left: var(--space-2);
  padding-right: var(--space-2);
}

.nutrient-optimal {
  color: var(--ok);
  font-weight: 600;
}

.nutrient-outofrange {
  color: var(--danger-strong);
  font-weight: 700;
}

.element-group-header {
  text-align: center;
  background: var(--bg);
  border-bottom: 2px solid var(--border);
}

/* ---------- Zone Infiltration Rates (Zone Details tab) ---------- */

.infiltration-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--space-2);
}

.infiltration-card {
  border: 1px solid var(--border);
  border-left-width: 4px;
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  background: var(--card-bg);
}

.infiltration-rate-warning {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--danger-strong);
  margin-top: var(--space-1);
}

.infiltration-zone-name {
  font-weight: 600;
}

.infiltration-rate {
  font-size: var(--text-lg);
  font-weight: 700;
  margin: 2px 0;
}

.infiltration-source {
  font-size: var(--text-xs);
  color: var(--text-muted);
}

.infiltration-card:has(.infiltration-slow) { border-left-color: var(--danger-strong); }
.infiltration-card:has(.infiltration-moderate) { border-left-color: var(--warn-strong); }
.infiltration-card:has(.infiltration-fast) { border-left-color: var(--ok); }
.infiltration-card:has(.infiltration-unknown) { border-left-color: var(--border); }

.infiltration-slow { color: var(--danger-strong); }
.infiltration-moderate { color: var(--warn-strong); }
.infiltration-fast { color: var(--ok); }
.infiltration-unknown { color: var(--text-muted); font-weight: 400; }

.ingest-health-banner {
  background: var(--danger-bg);
  border: 1px solid var(--danger-strong);
  color: var(--danger);
  border-radius: var(--radius-md);
  padding: var(--space-2) 14px;
  margin-top: var(--space-2);
  font-size: var(--text-sm);
}

/* ---------- Your Plants ---------- */

.plants-table select,
.plants-table input[type="text"] {
  width: 100%;
  padding: 6px var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  background: var(--card-bg);
  color: var(--text);
}

.plants-table .plants-kc-cell {
  font-weight: 600;
  text-align: center;
  white-space: nowrap;
}

.th-optional {
  font-weight: 400;
  color: var(--text-muted);
  font-size: 0.8em;
}

.plants-zone-num {
  color: var(--text-muted);
  font-size: var(--text-xs);
  margin-left: 6px;
}

.plants-device {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: var(--radius-pill);
  background: var(--accent-light);
  color: var(--text-muted);
  font-size: var(--text-2xs);
}

.plants-row-disabled { opacity: 0.55; }

.plants-actions {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: var(--space-4);
  flex-wrap: wrap;
}

.plants-footnote { margin-top: 18px; }

.plants-custom-card {
  margin-top: var(--space-4);
  padding: 14px var(--space-4);
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.plants-custom-card h4 { margin: 0 0 var(--space-1); }

.plants-custom-grid { margin-top: 10px; }

.plants-readonly {
  display: inline-block;
  margin-right: 6px;
}

.plants-label-cell {
  color: var(--text-muted);
}

.btn-link {
  background: none;
  border: none;
  padding: 0;
  color: var(--accent);
  font-size: var(--text-xs);
  text-decoration: underline;
  cursor: pointer;
}

.plants-table .plants-kc-input {
  width: 70px;
  padding: var(--space-1) 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: 600;
  text-align: center;
  background: var(--card-bg);
  color: var(--text);
}

.plants-kc-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: var(--radius-pill);
  background: var(--accent-light);
  color: var(--text-muted);
  font-size: var(--text-2xs);
  font-weight: 400;
  vertical-align: middle;
}

.plants-kc-clear {
  background: none;
  border: none;
  margin-left: var(--space-1);
  padding: 0;
  color: var(--text-muted);
  cursor: pointer;
  font-size: var(--text-xs);
  vertical-align: middle;
}

.plants-kc-note {
  color: var(--text-muted);
  font-size: var(--text-xs);
  font-weight: 400;
  font-style: italic;
}

/* Per-zone crop line on the Irrigation tab's recommendation cards */
.zone-card .zone-crop {
  margin: 0 0 6px;
  font-size: var(--text-xs);
  color: var(--accent);
  font-weight: 600;
}

.zone-card .zone-crop-default {
  color: var(--text-muted);
  font-weight: 500;
  font-style: italic;
}

/* ---------- Biodynamic / Organic sub-tab ---------- */

.bd-today-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px var(--space-4);
  background: var(--accent-light);
}

.bd-today-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  font-size: var(--text-md);
}

.bd-today-sub {
  margin-top: 6px;
  font-size: var(--text-xs);
  color: var(--text-muted);
}

.bd-today-tasks {
  margin: 10px 0 0;
  padding-left: 18px;
  font-size: var(--text-sm);
}

.bd-day-chip {
  display: inline-block;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--on-accent);
  background: var(--text-muted);
}

.bd-day-root   { background: var(--bd-root); }
.bd-day-leaf   { background: var(--accent); }
.bd-day-flower { background: var(--bd-flower); }
.bd-day-fruit  { background: var(--danger); }

.bd-reco-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 10px var(--space-3);
  margin-bottom: var(--space-2);
  background: var(--card-bg);
  font-size: var(--text-sm);
}

.bd-reco-head { display: flex; align-items: center; gap: var(--space-2); }

.bd-reco-tag {
  font-size: var(--text-2xs);
  color: var(--text-muted);
}

.bd-reco-meta { color: var(--text-muted); font-size: var(--text-xs); margin: 3px 0; }

.bd-reco-note { margin-top: var(--space-1); font-style: italic; color: var(--text-muted); }

.bd-reco-card ul { margin: var(--space-1) 0 0; padding-left: 18px; }

.bd-audit-bad  { color: var(--danger); }
.bd-audit-warn { color: var(--warn); }
.bd-audit-ok   { color: var(--accent); }

.bd-site-note {
  margin: 10px 0;
  padding: var(--space-2) var(--space-3);
  border-left: 3px solid var(--warn);
  background: var(--warn-bg);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
}

#bd-covercrop-climate {
  margin: 6px 0 var(--space-3);
  font-weight: 600;
}

/* ---------- Knowledge Base (Learn tab + contextual "Related Guide" callouts) ---------- */

.kb-callout {
  margin: 0 0 var(--space-4) 0;
}

.kb-callout-details {
  padding: var(--space-3) 14px;
  border-left: 3px solid var(--accent);
  background: var(--accent-light);
  border-radius: var(--radius-sm);
}

.kb-callout-header {
  font-weight: 700;
  color: var(--accent);
  cursor: pointer;
}

.kb-callout-details[open] .kb-callout-header {
  margin-bottom: 6px;
}

.kb-callout-item + .kb-callout-item {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
}

.kb-callout-title {
  font-weight: 600;
  margin-bottom: 2px;
}

.kb-callout-teaser {
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin-bottom: var(--space-1);
}

.kb-callout-readmore {
  background: none;
  border: none;
  padding: 0;
  color: var(--accent);
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
}

.kb-callout-readmore:hover {
  text-decoration: underline;
}

.kb-loading {
  color: var(--text-muted);
  font-size: var(--text-md);
  padding: 10px 0;
}

.kb-error {
  color: var(--danger);
  background: var(--danger-bg);
  padding: 10px var(--space-3);
  border-radius: var(--radius-sm);
}

.kb-subject-heading {
  margin-top: 28px;
  padding-top: var(--space-1);
  scroll-margin-top: 12px;
  transition: background 0.4s ease;
}

.kb-subject-heading:first-child {
  margin-top: var(--space-1);
}

.kb-subject-highlight {
  background: var(--accent-light);
}

.kb-links-heading {
  margin-top: var(--space-6);
  color: var(--text-muted);
  font-size: var(--text-md);
}

.kb-links-list {
  font-size: var(--text-sm);
  padding-left: var(--space-5);
}

.kb-links-list li {
  margin-bottom: 6px;
}

#tab-learn p code,
.kb-links-list code {
  background: var(--accent-light);
  padding: 1px var(--space-1);
  border-radius: var(--radius-sm);
}

.kb-figure {
  margin: var(--space-4) auto;
  max-width: 560px;
  text-align: center;
}

.kb-figure img {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  display: block;
  margin: 0 auto;
}

.kb-figure figcaption {
  margin-top: 6px;
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-style: italic;
}

.tab-label-short { display: none; }

/* ---------- Responsive layout ----------
   Three sizes: phone (< 600px), tablet (600-1199px, the base styles), and
   wide (>= 1200px). Wide screens get more columns, not longer lines. */

.settings-hint,
.kb-callout-teaser,
#tab-learn .subtab-panel p,
#tab-learn .subtab-panel li {
  max-width: var(--prose-max);
}

@media (min-width: 1200px) {
  /* Chart.js keeps a 2:1 aspect ratio, so two-up also keeps charts a sane height. */
  .charts {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 599px) {
  header {
    padding: var(--space-4) max(var(--space-4), env(safe-area-inset-right)) var(--space-4) max(var(--space-4), env(safe-area-inset-left));
  }
  header h1 { font-size: var(--text-lg); }
  .subtitle { display: none; }
  .header-top .btn-text { display: none; }
  main {
    padding: var(--space-3) max(var(--space-3), env(safe-area-inset-right)) var(--space-3) max(var(--space-3), env(safe-area-inset-left));
  }
  body {
    padding-bottom: calc(var(--nav-height) + env(safe-area-inset-bottom));
  }

  /* Bottom tab bar: same buttons and initTabs() as the top tabs. */
  .tabs {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: var(--z-nav);
    display: grid;
    /* One equal column per visible tab (5 or 6 -- the Wine tab can be
       hidden from Settings), instead of a hard-coded count. */
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 0;
    padding: 0 env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
    background: var(--card-bg);
    border-bottom: none;
    border-top: 1px solid var(--border);
    overflow: visible;
  }
  .tab-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    min-height: var(--nav-height);
    padding: var(--space-1) 0;
    margin: 0;
    border-bottom: none;
    border-top: 3px solid transparent;
    font-size: var(--text-2xs);
  }
  .tab-btn.active { border-top-color: var(--accent); }
  .tab-icon { font-size: var(--text-lg); line-height: 1; }
  /* Full label stays in the accessibility tree (icon + short label are aria-hidden). */
  .tab-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .tab-label-short { display: inline; }

  /* Tables: each row becomes a card of label: value pairs (labels from
     labelTableCells() in script.js). Tables are unchanged from 600px up. */
  .log-table-wrap,
  .run-log-table-wrap,
  .forecast-table-wrap {
    max-height: none;
    overflow: visible;
    border: 0;
  }
  .log-table,
  .log-table tbody,
  .log-table tfoot,
  .run-log-table,
  .run-log-table tbody,
  .run-log-table tfoot {
    display: block;
    width: 100%;
  }
  .log-table thead,
  .run-log-table thead,
  .log-table thead tr,
  .run-log-table thead tr { display: block; }
  .log-table th,
  .run-log-table th {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  /* The soil test's select-all lives in its header; keep it usable. */
  .log-table th.soiltest-check-col {
    position: static;
    width: auto;
    height: auto;
    overflow: visible;
    clip-path: none;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: 0 0 var(--space-3);
    background: none;
    border: 0;
    font-weight: 400;
  }
  .log-table th.soiltest-check-col::after { content: "Show all on map"; }
  .log-table :is(tbody, tfoot) tr,
  .run-log-table :is(tbody, tfoot) tr {
    display: flex;
    flex-direction: column;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-3);
    margin-bottom: var(--space-3);
  }
  .log-table td,
  .run-log-table td {
    display: grid;
    grid-template-columns: minmax(6rem, 40%) minmax(0, 1fr);
    gap: var(--space-2);
    padding: var(--space-1) 0;
    border: 0;
    text-align: left;
    overflow-wrap: anywhere;
  }
  .log-table td::before,
  .run-log-table td::before {
    content: attr(data-label);
    color: var(--text-muted);
    font-size: var(--text-xs);
  }
  /* Card title: the row's first labelled cell (usually the date). */
  .log-table td[data-card-title],
  .run-log-table td[data-card-title] {
    order: -1;
    display: block;
    font-weight: 600;
    font-size: var(--text-base);
    padding-bottom: var(--space-2);
    margin-bottom: var(--space-1);
    border-bottom: 1px solid var(--border);
  }
  /* Unlabelled cells (checkboxes, action buttons) and spanning notes. */
  .log-table td:not([data-label]),
  .run-log-table td:not([data-label]) {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    order: 99;
  }
  .log-table td[colspan]:not([data-label]),
  .run-log-table td[colspan]:not([data-label]) { order: 0; }
  .log-table td[data-card-title]::before,
  .run-log-table td[data-card-title]::before {
    display: block;
    font-weight: 400;
  }
  .log-table td:not([data-label])::before,
  .run-log-table td:not([data-label])::before { content: none; }
  .log-table td:empty,
  .run-log-table td:empty { display: none; }
  .forecast-table td { white-space: normal; }

  /* Inputs at 16px+ so iOS doesn't zoom the page when a field is focused.
     !important because ~20 component rules (some id-based) set smaller
     sizes on fields; this is a phone-wide floor, not a style choice. */
  input,
  select,
  textarea { font-size: max(16px, 1em) !important; }

  /* Control rows stack into one column. */
  .log-form-row > label,
  .settings-row > label { flex: 1 1 100%; }
  .log-form-row input:not([type="checkbox"]):not([type="radio"]),
  .log-form-row select,
  .log-form-row textarea,
  .settings-row input:not([type="checkbox"]):not([type="radio"]),
  .settings-row select,
  .zone-details-select-row select { width: 100%; }
  .irrigation-tab-header {
    flex-wrap: wrap;
    gap: var(--space-2);
  }
  .unit-toggle { flex: 1 1 100%; }
  .unit-toggle .unit-btn { flex: 1 1 0; }
  .map-buttons { flex-wrap: wrap; }
  /* Long file paths in guide text (e.g. <code>soil_amendments.py</code> links) */
  main code { overflow-wrap: anywhere; }

  /* Live-conditions band: metrics in a 3-column grid under the readout. */
  .forecast-hero-metrics {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-2) var(--space-3);
    margin-left: 0;
    width: 100%;
  }
}

/* ---------- Wine tab (static/wine.js) ---------- */

/* A tab button hidden by settings must stay hidden even where .tab-btn sets display. */
.tab-btn[hidden] { display: none; }

.wine-batchbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  margin-bottom: var(--space-3);
}
.wine-batchbar select { min-width: 12rem; }
.wine-batch-summary { color: var(--text-muted); font-size: var(--text-sm); }

.wine-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.wine-batch-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: var(--space-3);
  margin: var(--space-3) 0;
}
.wine-batch-card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
}
.wine-batch-card.selected { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.wine-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); }
.wine-card-title { font-weight: 700; font-size: var(--text-lg); }
.wine-card-sub { color: var(--text-muted); font-size: var(--text-sm); }
.wine-card-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }

.wine-stage-badge {
  display: inline-block;
  padding: 2px var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--accent-light);
  color: var(--accent);
  font-size: var(--text-xs);
  font-weight: 600;
  white-space: nowrap;
}

.wine-metrics {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-2);
}
.wine-metric-label { display: block; color: var(--text-muted); font-size: var(--text-2xs); }
.wine-metric-value { font-size: var(--text-base); font-weight: 600; font-variant-numeric: tabular-nums; }

.wine-chip {
  display: inline-block;
  margin-top: 2px;
  padding: 0 var(--space-1);
  border-radius: var(--radius-sm);
  font-size: var(--text-2xs);
  font-weight: 600;
}
.wine-chip-ok { background: var(--accent-light); color: var(--accent); }
.wine-chip-low { background: var(--info-bg); color: var(--info); }
.wine-chip-high { background: var(--warn-bg); color: var(--warn); }

.wine-timeline {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.wine-timeline li { display: flex; align-items: center; gap: var(--space-1); }
.wine-timeline li::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 2px solid var(--border);
}
.wine-timeline li.done { color: var(--text); }
.wine-timeline li.done::before { background: var(--accent); border-color: var(--accent); }
.wine-timeline li.current { color: var(--accent); font-weight: 700; }
.wine-timeline li.current::before { border-color: var(--accent); }

.wine-guidance { margin: var(--space-2) 0; padding-left: var(--space-5); display: grid; gap: var(--space-2); }
.wine-guidance li { padding: var(--space-2) var(--space-3); border-left: 3px solid var(--border); background: var(--bg); border-radius: 0 var(--radius-md) var(--radius-md) 0; }
.wine-guidance li.adjust { border-left-color: var(--warn); }
.wine-guidance li.caution { border-left-color: var(--danger); }
.wine-guidance li.ok { border-left-color: var(--accent); }
.wine-guidance li.todo { border-left-color: var(--info); }

.wine-pill {
  display: inline-block;
  padding: 1px var(--space-2);
  border-radius: var(--radius-pill);
  font-size: var(--text-2xs);
  font-weight: 600;
  white-space: nowrap;
}
.wine-pill { width: fit-content; justify-self: start; }
.wine-pill-confirmed, .wine-pill-reported { background: var(--accent-light); color: var(--accent); }
.wine-pill-recommended { background: var(--warn-bg); color: var(--warn); }
.wine-pill-superseded { background: var(--bg); color: var(--text-muted); }
.wine-pill-trial { background: var(--info-bg); color: var(--info); }
.log-table tr.wine-row-muted td { color: var(--text-muted); }
.log-table tr.wine-row-muted td:not(:last-child) { text-decoration: line-through; text-decoration-color: rgba(0, 0, 0, 0.25); }
.wine-row-actions { display: flex; flex-wrap: wrap; gap: var(--space-1); justify-content: flex-end; }
.wine-toggle { margin: var(--space-2) 0; }

.wine-form-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.wine-danger-btn { color: var(--danger); border-color: var(--danger); }
.wine-batch-form { margin-top: var(--space-4); border: 1px solid var(--accent); border-radius: var(--radius-lg); padding: var(--space-4); }
.wine-batch-form h3 { margin-top: 0; }

.wine-calc-basis { margin-bottom: var(--space-4); }
.wine-calc-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: var(--space-3);
}
.wine-calc-card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  min-width: 0;
}
.wine-calc-card h3 { margin: 0 0 var(--space-2) 0; font-size: var(--text-base); }
.wine-calc-wide { grid-column: span 2; }
.wine-calc-result { margin-top: var(--space-3); font-size: var(--text-sm); }
.wine-calc-result:empty { display: none; }
.wine-calc-result dl, .wine-session .wine-calc-card dl { display: grid; grid-template-columns: auto 1fr; gap: 2px var(--space-3); margin: 0 0 var(--space-2) 0; }
.wine-calc-result dt, .wine-session .wine-calc-card dt { color: var(--text-muted); }
.wine-calc-result dd, .wine-session .wine-calc-card dd { margin: 0; font-weight: 600; font-variant-numeric: tabular-nums; }
.wine-calc-result .wine-calc-note { color: var(--text-muted); margin: var(--space-2) 0; }
.wine-calc-result .wine-calc-warn { color: var(--warn); margin: var(--space-2) 0; }

.wine-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--space-2);
  margin: var(--space-4) 0 var(--space-2);
}
.wine-stat { background: var(--bg); border-radius: var(--radius-md); padding: var(--space-2) var(--space-3); }
.wine-stat .wine-metric-value { font-size: var(--text-lg); }

.wine-alert { padding: var(--space-2) var(--space-3); border-radius: var(--radius-md); margin: var(--space-2) 0; font-size: var(--text-sm); }
.wine-alert-info { background: var(--info-bg); color: var(--info); }
.wine-alert-warn { background: var(--warn-bg); color: var(--warn); }
.wine-alert-danger { background: var(--danger-bg); color: var(--danger); }

.wine-chart { position: relative; height: 380px; margin-top: var(--space-3); }

.wine-guide-steps { display: grid; gap: var(--space-2); padding-left: var(--space-5); max-width: var(--prose-max); }
.wine-sources { display: grid; gap: var(--space-1); padding-left: var(--space-5); }
.wine-target-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--space-3); }

@media (max-width: 700px) {
  .wine-calc-wide { grid-column: auto; }
  .wine-calc-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 599px) {
  .wine-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .wine-chart { height: 300px; }
  .wine-batchbar select { min-width: 0; width: 100%; }
  .wine-batchbar label { flex: 1 1 100%; }
}

/* Adjust-must session wizard */
.wine-session-steps { margin-bottom: var(--space-3); }
.wine-session-title { margin: var(--space-2) 0; font-size: var(--text-lg); }
.wine-session-prompt { max-width: var(--prose-max); font-size: var(--text-base); line-height: 1.5; margin: 0 0 var(--space-3); }
.wine-band-strip {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}
.wine-band-item { background: var(--bg); border-radius: var(--radius-md); padding: var(--space-2) var(--space-3); }
.wine-trials { display: grid; gap: var(--space-3); margin-bottom: var(--space-3); }
.wine-trial-row { border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-3); }
.wine-trial-row summary { cursor: pointer; color: var(--text-muted); font-size: var(--text-sm); margin-top: var(--space-2); }
.wine-best { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.wine-add-row { align-items: end; }
.wine-add-label { font-weight: 600; align-self: center; }
.wine-session-history { display: grid; gap: var(--space-1); padding-left: var(--space-5); font-size: var(--text-sm); }
@media (max-width: 599px) {
  .wine-band-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* °F/°C entry switch beside Wine temperature labels */
.wine-unit-switch { display: inline-flex; margin-left: var(--space-1); border: 1px solid var(--border); border-radius: var(--radius-pill); overflow: hidden; vertical-align: middle; }
.wine-unit-switch button { border: 0; background: var(--card-bg); color: var(--text-muted); font-size: var(--text-2xs); font-weight: 600; padding: 1px var(--space-2); cursor: pointer; min-height: 0; }
.wine-unit-switch button.active { background: var(--accent); color: var(--on-accent); }
.wine-unit-switch button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
@media (max-width: 599px) {
  .wine-unit-switch button { font-size: var(--text-xs); padding: var(--space-1) var(--space-3); min-height: 28px; }
}
.wine-stat-sub { display: block; font-size: var(--text-2xs); }
.log-table tr.wine-row-editing td { background: var(--warn-bg); }
.wine-batch-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: var(--space-1); vertical-align: baseline; }
.wine-batch-name { white-space: nowrap; }
.wine-chart-block { margin-top: var(--space-3); }
.wine-chart-block .wine-chart { margin-top: 0; }
.wine-chart-block[hidden] { display: none; }
.wine-graph-head { margin-top: var(--space-4); }
.wine-graph-head h3 { margin: 0; }
/* Fermentation "Show" chips: one tap picks a batch, one tap on All goes back */
.wine-chips-row { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.wine-chips-label { color: var(--text-muted); font-size: var(--text-sm); }
.wine-chips { display: flex; flex-wrap: wrap; gap: var(--space-1); }
.wine-chips button {
  display: inline-flex; align-items: center; gap: var(--space-1);
  padding: var(--space-1) var(--space-3); min-height: 32px;
  border: 1px solid var(--border); border-radius: var(--radius-pill);
  background: var(--card-bg); color: var(--text); font-size: var(--text-sm); font-weight: 600; cursor: pointer;
}
.wine-chips button:hover { border-color: var(--accent); }
.wine-chips button.active { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.wine-chips button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.wine-chips .wine-batch-dot { margin-right: 0; }
.wine-chips button.active .wine-batch-dot { box-shadow: 0 0 0 2px var(--on-accent); }

/* ---------- YoLink field sensors (static/yolink.js) ---------- */
.yolink-sensor-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.yolink-card {
  min-width: 0;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}
.yolink-card h3 {
  margin: 0 0 var(--space-2) 0;
  font-size: var(--text-base);
  text-wrap: balance;
}
.yolink-card-temp {
  font-size: var(--text-2xl);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.yolink-card-meta {
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
}
.yolink-stale { color: var(--danger); }
.yolink-picker-row { align-items: center; }
/* .log-form-row's display:flex would otherwise override [hidden]. */
#yolink-cloud-fields[hidden], #yolink-local-fields[hidden] { display: none; }
.yolink-picker-heading { margin: var(--space-4) 0 var(--space-2) 0; font-size: var(--text-md); }
.yolink-measured { color: var(--accent); font-variant-numeric: tabular-nums; }

/* Fermentation temperature alarm: header banner, visible on every tab */
.wine-alarm-banner { display: grid; gap: var(--space-1); margin-top: var(--space-2); }
.wine-alarm-banner[hidden] { display: none; }
.wine-alarm-line {
  display: block; width: 100%; text-align: left; cursor: pointer;
  padding: var(--space-2) 14px; border-radius: var(--radius-md); font-size: var(--text-sm); line-height: 1.4;
}
.wine-alarm-danger { background: var(--danger-bg); border: 1px solid var(--danger-strong); color: var(--danger); }
.wine-alarm-warning { background: var(--warn-bg); border: 1px solid var(--warn); color: var(--warn); }
.wine-alarm-line:hover { filter: brightness(0.97); }
.wine-alarm-line:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
.wine-alarm-age { opacity: 0.85; }
.wine-limits-wrap { overflow-x: auto; }
.wine-limits-table { border-collapse: collapse; font-size: var(--text-sm); }
.wine-limits-table th, .wine-limits-table td { padding: var(--space-1); text-align: left; }
.wine-limits-table input { width: 5rem; }

/* ---------- Date and time picker (static/datetime_picker.js) ----------
   Every date/time input is hidden (.dtp-native) and shown as a read-only
   text box (.dtp-display) that opens a calendar beside an analog clock:
   a popover on desktop, a bottom sheet on phones. See DESIGN.md. */
.dtp-native { display: none !important; }
.dtp-display {
  cursor: pointer;
  caret-color: transparent;
  font-variant-numeric: tabular-nums;
  padding-right: 30px !important;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Crect x='1.5' y='2.5' width='13' height='12' rx='2' fill='none' stroke='%23646e5f'/%3E%3Cpath d='M1.5 6h13M5 1v3M11 1v3' stroke='%23646e5f'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 9px center;
}
.dtp-display.dtp-time {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='6.5' fill='none' stroke='%23646e5f'/%3E%3Cpath d='M8 4.5V8l2.5 1.5' fill='none' stroke='%23646e5f'/%3E%3C/svg%3E");
}
.dtp-display.dtp-datetime-local { min-width: 13.5rem; }
.dtp-display:disabled { cursor: not-allowed; opacity: 0.6; }
.dtp-display[aria-expanded="true"] { border-color: var(--accent); }

.dtp-pop, .dtp-sheet {
  background: var(--card-bg);
  color: var(--text);
  display: grid;
  gap: var(--space-3);
  font-size: var(--text-md);
  z-index: calc(var(--z-nav) + 20);
}
.dtp-pop {
  position: fixed;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-popover);
  padding: 14px;
  width: max-content;
  max-width: calc(100vw - 16px);
  animation: dtp-pop-in 140ms ease-out;
}
.dtp-scrim { position: fixed; inset: 0; background: rgba(20, 28, 18, 0.35); z-index: calc(var(--z-nav) + 19); animation: dtp-fade 160ms ease-out; }
.dtp-sheet {
  position: fixed; left: 0; right: 0; bottom: 0;
  max-height: 92vh; overflow-y: auto;
  border-radius: 18px 18px 0 0;
  padding: 10px var(--space-4) calc(var(--space-4) + env(safe-area-inset-bottom, 0px));
  animation: dtp-sheet-up 220ms cubic-bezier(.2, .8, .2, 1);
}
.dtp-sheet::before { content: ""; justify-self: center; width: 36px; height: 4px; border-radius: 4px; background: var(--border); }
@keyframes dtp-pop-in { from { opacity: 0; transform: translateY(-4px) scale(0.98); } }
@keyframes dtp-sheet-up { from { transform: translateY(100%); } }
@keyframes dtp-fade { from { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .dtp-pop, .dtp-sheet, .dtp-scrim { animation: none; } }

.dtp-body { display: flex; gap: 18px; align-items: flex-start; }
.dtp-sheet .dtp-body { flex-direction: column; align-items: stretch; }
.dtp-foot { display: flex; align-items: center; gap: var(--space-2); }
.dtp-spacer { margin-right: auto; }
.dtp-btn { font: inherit; font-size: var(--text-sm); min-height: 36px; padding: 6px 14px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--card-bg); color: var(--text); cursor: pointer; }
.dtp-btn:hover { border-color: var(--accent); }
.dtp-primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.dtp-link { font: inherit; font-size: var(--text-sm); border: 0; background: none; color: var(--accent); text-decoration: underline; text-underline-offset: 2px; cursor: pointer; padding: 4px 2px; }
.dtp-pop button:focus-visible, .dtp-sheet button:focus-visible, .dtp-dial:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.dtp-cal { display: grid; gap: 6px; min-width: 260px; align-content: start; }
.dtp-cal-head { display: flex; align-items: center; justify-content: space-between; font-weight: 600; }
.dtp-cal-head button { font: inherit; font-size: 1.1rem; width: 36px; height: 36px; border: 0; border-radius: var(--radius-sm); background: none; color: var(--text); cursor: pointer; }
.dtp-cal-head button:hover { background: var(--accent-light); }
.dtp-cal-grid { display: grid; grid-template-columns: repeat(7, 36px); gap: 2px; justify-content: center; }
.dtp-dow { font-size: var(--text-2xs); color: var(--text-muted); text-align: center; padding-bottom: 2px; }
.dtp-cal-grid button { font: inherit; font-size: var(--text-sm); width: 36px; height: 36px; border: 0; border-radius: 50%; background: none; color: var(--text); cursor: pointer; font-variant-numeric: tabular-nums; }
.dtp-cal-grid button:hover:not(:disabled) { background: var(--accent-light); }
.dtp-cal-grid button.dtp-out { color: var(--text-muted); opacity: 0.6; }
.dtp-cal-grid button.dtp-today { box-shadow: inset 0 0 0 1px var(--accent); }
.dtp-cal-grid button[aria-selected="true"] { background: var(--accent); color: var(--on-accent); }
.dtp-cal-grid button:disabled { opacity: 0.3; cursor: not-allowed; }
.dtp-sheet .dtp-cal-grid { grid-template-columns: repeat(7, minmax(0, 1fr)); }
.dtp-sheet .dtp-cal-grid button { width: 100%; max-width: 44px; height: auto; aspect-ratio: 1; justify-self: center; }

.dtp-clock { display: grid; gap: 10px; justify-items: center; align-content: start; min-width: 250px; }
.dtp-readout { display: flex; align-items: center; gap: var(--space-1); font-variant-numeric: tabular-nums; }
.dtp-part { font: inherit; font-size: var(--text-2xl); font-weight: 500; line-height: 1; min-width: 64px; padding: 6px 10px; border: 0; border-radius: var(--radius-md); background: var(--bg); color: var(--text); cursor: pointer; }
.dtp-part[aria-pressed="true"] { background: var(--accent-light); color: var(--accent); box-shadow: inset 0 0 0 2px var(--accent); }
.dtp-colon { font-size: var(--text-2xl); color: var(--text-muted); }
.dtp-ampm { display: grid; gap: var(--space-1); margin-left: 6px; }
.dtp-ampm button { font: inherit; font-size: var(--text-xs); font-weight: 600; padding: 4px 9px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--card-bg); color: var(--text-muted); cursor: pointer; }
.dtp-ampm button[aria-pressed="true"] { background: var(--accent-light); color: var(--accent); border-color: var(--accent); }
.dtp-dial { width: 240px; height: 240px; max-width: 100%; touch-action: none; cursor: pointer; border-radius: 50%; user-select: none; -webkit-user-select: none; }
.dtp-face { fill: var(--bg); stroke: var(--border); }
.dtp-hand { stroke: var(--accent); stroke-width: 2; }
.dtp-hub, .dtp-knob { fill: var(--accent); }
.dtp-dot { fill: var(--on-accent); }
.dtp-dial text { fill: var(--text); font-size: 15px; text-anchor: middle; dominant-baseline: central; font-variant-numeric: tabular-nums; pointer-events: none; }
.dtp-dial text.dtp-sel { fill: var(--on-accent); font-weight: 600; }
.dtp-hint { font-size: var(--text-xs); color: var(--text-muted); min-height: 1.2em; }
@media (max-width: 599px) {
  .dtp-display.dtp-datetime-local { min-width: 0; }
}

/* Touch targets on phones and touch screens: every control at least 24x24
   (WCAG 2.2 AA 2.5.8). These are the ones a 400px-wide sweep of every tab
   and sub-tab found under that size. */
@media (max-width: 720px), (pointer: coarse) {
  .kb-callout-readmore { min-height: 32px; }
  .kb-callout-header,
  .soil-advanced-details summary,
  .cimis-block > summary { padding-block: 6px; }
  .checkbox-label,
  .precip-toggle { min-height: 32px; }
  .heatwave-control .checkbox-label { display: inline-flex; }
  .checkbox-label input[type="checkbox"],
  .checkbox-label input[type="radio"],
  .precip-toggle input[type="checkbox"] { width: 20px; height: 20px; }
  .soiltest-check-col input[type="checkbox"] { width: 24px; height: 24px; }
  select { min-height: 32px; }
  /* Leaflet's map credits link (drawn by the library, 14px tall) */
  .leaflet-control-attribution a { display: inline-block; padding-block: 5px; }
}

/* Reduced motion: keep every state change, drop the movement (tab fades,
   hover transitions, popover entrances). */
@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;
  }
}

/* ---------- Auth: sign-in page, Devices & Access, header banner (auth.js / login.js) ---------- */
.login-body { min-height: 100vh; min-height: 100dvh; display: flex; align-items: center; justify-content: center;
  padding: var(--space-4) 16px; box-sizing: border-box; }
.login-wrap { width: 100%; max-width: 420px; }
.login-card { display: grid; gap: var(--space-3); text-align: left; }
.login-card h1, .login-card > .settings-hint:first-of-type { text-align: center; }
.login-card h1 { margin: 0; font-size: var(--text-xl); }
.login-card .btn { width: 100%; }
.login-notice { background: var(--info-bg); border: 1px solid var(--info-border); color: var(--info);
  padding: var(--space-2) 14px; border-radius: var(--radius-md); font-size: var(--text-sm); }
.login-notice[hidden], #login-actions[hidden], #login-code-panel[hidden], #login-create-btn[hidden],
#login-enroll[hidden], #login-invite-only[hidden], #join-ready[hidden], #auth-exposed-block[hidden],
#auth-invite-new[hidden] { display: none; }
.login-enroll { margin-top: var(--space-3); }
.login-enroll summary { cursor: pointer; color: var(--accent); font-size: var(--text-sm); }
.login-enroll-form { display: grid; gap: var(--space-2); margin-top: var(--space-2); }
.login-enroll-form[hidden] { display: none; }
.login-enroll-form input { width: 100%; font-size: 16px; }
.login-code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 2.2rem;
  letter-spacing: 0.15em; text-align: center; margin: var(--space-2) 0; font-variant-numeric: tabular-nums; }
.auth-banner { display: grid; gap: var(--space-1); margin-top: var(--space-2); }
.auth-banner[hidden] { display: none; }
.auth-banner-line { background: var(--info-bg); border: 1px solid var(--info-border); color: var(--info);
  padding: var(--space-2) 14px; border-radius: var(--radius-md); font-size: var(--text-sm); }
.auth-banner-line .btn-link { font-size: inherit; color: inherit; }
.auth-list { display: grid; gap: var(--space-1); margin-bottom: var(--space-2); }
.auth-row { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--space-2);
  padding: var(--space-2) 12px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--card-bg); }
.auth-row-info { min-width: 0; flex: 1 1 220px; }
.auth-row-title { font-weight: 600; overflow-wrap: anywhere; }
.auth-row-meta { color: var(--text-muted); font-size: var(--text-xs); overflow-wrap: anywhere; }
.auth-row-actions { display: flex; gap: var(--space-1); }
.btn-small.danger { color: var(--danger-strong); border-color: var(--danger-border); }
.auth-new-key { background: var(--highlight-bg); border: 1px solid var(--highlight-border);
  padding: var(--space-2) 12px; border-radius: var(--radius-md); }
.auth-new-key[hidden], #auth-legacy-block[hidden], #auth-hostname-block[hidden], #auth-signout-row[hidden] { display: none; }
.auth-new-key input { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; flex: 1; min-width: 0; }
#auth-approve-code { letter-spacing: 0.1em; }

/* ---------- Viewer mode (window.AUTH_ROLE === "viewer"; app.py enforces) ---------- */
.viewer-only { display: none; }
.role-viewer .viewer-only { display: inline-flex; }
.role-viewer .owner-only,
.role-viewer #global-settings-btn,
.role-viewer #stop-all-manual-watering-btn,
.role-viewer #rain-delay-all-btn,
.role-viewer .device-actions,
.role-viewer .schedule-row input,
.role-viewer .schedule-row [data-action="adjust"],
.role-viewer .manual-zone-row,
.role-viewer .log-delete-btn,
.role-viewer #fplan-save-btn { display: none !important; }
#join-ready { display: grid; gap: var(--space-3); }
#join-ready p { margin: 0; }
