:root {
  --teal: #0f766e;
  --teal-dark: #0b5650;
  --bg: #0f172a;
  --card: #ffffff;
  --ink: #1e293b;
  --muted: #64748b;
  --danger: #dc2626;
  --line: #e2e8f0;
  --shadow: 0 6px 24px rgba(0,0,0,.18);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  margin: 0;
  height: 100%;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  color: var(--ink);
  overflow: hidden;
}

#map {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.hidden { display: none !important; }

/* ---- Search bar ---- */
.search-bar {
  position: absolute;
  top: calc(env(safe-area-inset-top) + 10px);
  left: 10px;
  right: 10px;
  z-index: 500;
  display: flex;
  gap: 6px;
  background: var(--card);
  border-radius: 12px;
  box-shadow: var(--shadow);
  padding: 6px;
}
.search-bar input {
  flex: 1;
  border: none;
  outline: none;
  font-size: 16px;
  padding: 8px 10px;
  border-radius: 8px;
  background: #f1f5f9;
  min-width: 0;
}
.search-bar button {
  border: none;
  background: #f1f5f9;
  border-radius: 8px;
  font-size: 18px;
  width: 42px;
  cursor: pointer;
}
.search-bar button:active { background: #e2e8f0; }

.search-results {
  position: absolute;
  top: calc(env(safe-area-inset-top) + 64px);
  left: 10px;
  right: 10px;
  z-index: 500;
  margin: 0;
  padding: 4px;
  list-style: none;
  background: var(--card);
  border-radius: 12px;
  box-shadow: var(--shadow);
  max-height: 45vh;
  overflow-y: auto;
}
.search-results li {
  padding: 12px 10px;
  border-radius: 8px;
  font-size: 14px;
  cursor: pointer;
  border-bottom: 1px solid var(--line);
}
.search-results li:last-child { border-bottom: none; }
.search-results li:active { background: #f1f5f9; }

/* ---- Live readout ---- */
.readout {
  position: absolute;
  top: calc(env(safe-area-inset-top) + 66px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 450;
  background: rgba(15,118,110,.95);
  color: #fff;
  border-radius: 14px;
  padding: 10px 18px;
  text-align: center;
  box-shadow: var(--shadow);
  min-width: 200px;
  backdrop-filter: blur(4px);
}
/* While the amber "Editing" banner is up, drop the readout below it. */
.readout.with-banner { top: calc(env(safe-area-inset-top) + 116px); }
.readout-main { font-size: 30px; font-weight: 700; line-height: 1; }
.readout-unit { font-size: 16px; font-weight: 500; opacity: .9; }
.readout-sub { font-size: 12px; margin-top: 6px; opacity: .9; }

/* ---- Bottom action bar ---- */
.action-bar {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 500;
  display: flex;
  gap: 6px;
  padding: 8px 8px calc(8px + env(safe-area-inset-bottom));
  background: linear-gradient(to top, rgba(15,23,42,.85), rgba(15,23,42,0));
}
.act {
  /* flex-basis 0 + min-width 0 lets these actually SHRINK. With `flex: 1` and
     nowrap they could never go below their text width, so adding a sixth button
     pushed the menu clean off the right edge of the phone. */
  flex: 1 1 0;
  min-width: 0;
  border: none;
  border-radius: 12px;
  padding: 14px 4px;
  font-size: 13px;
  font-weight: 600;
  background: var(--card);
  color: var(--ink);
  box-shadow: var(--shadow);
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Icon-only buttons don't need a text button's width */
.act.act-icon { flex: 0 0 38px; padding: 14px 0; font-size: 17px; }
.act:active { transform: translateY(1px); }
.act:disabled { opacity: .45; cursor: default; }
.act-primary { background: var(--teal); color: #fff; }
.act-danger { background: #fee2e2; color: var(--danger); }

/* ---- Centre crosshair + drop-pin button ---- */
.crosshair {
  position: absolute;
  top: 50%; left: 50%;
  width: 46px; height: 46px;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 450;
}
/* The aiming mark is a small bright dot rather than cross lines (his request).
   Magenta on purpose: the roof outline is cyan and the ridge lines are amber, so a
   third colour keeps the aiming point readable against both — and like those two it
   is a colour that does not occur naturally in satellite imagery. The dark edge and
   white ring keep it visible over a white roof as well as a dark one. */
.crosshair::before, .crosshair::after { content: none; }
.crosshair .ch-dot {
  position: absolute; top: 50%; left: 50%;
  /* Halved from 9px at his request - it was covering the very corner being aimed
     at. The border and rings are halved with it, or they would dominate a dot this
     small and undo the change. */
  width: 4.5px; height: 4.5px; border-radius: 50%;
  background: #ff00d4;
  border: 0.75px solid rgba(0,0,0,.6);
  box-shadow: 0 0 0 0.5px rgba(255,255,255,.9), 0 0 3px rgba(255,0,212,.85);
  transform: translate(-50%, -50%);
}
.add-point-btn {
  position: absolute;
  left: 50%;
  bottom: calc(84px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 480;
  background: var(--teal); color: #fff;
  border: none; border-radius: 999px;
  padding: 13px 24px; font-size: 15px; font-weight: 600;
  box-shadow: var(--shadow); cursor: pointer; white-space: nowrap;
}
.add-point-btn:active { transform: translateX(-50%) scale(0.96); }
.add-point-btn.moving { background: #d85a30; }

/* ---- Hint ---- */
.hint {
  position: absolute;
  bottom: calc(134px + env(safe-area-inset-bottom));
  left: 50%;
  transform: translateX(-50%);
  z-index: 400;
  background: rgba(15,23,42,.8);
  color: #fff;
  font-size: 13px;
  padding: 8px 14px;
  border-radius: 999px;
  white-space: nowrap;
  pointer-events: none;
  transition: opacity .3s;
}

/* ---- Panels ---- */
.panel {
  position: absolute;
  inset: 0;
  z-index: 700;
  background: #f8fafc;
  display: flex;
  flex-direction: column;
}
.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: calc(env(safe-area-inset-top) + 14px) 16px 14px;
  background: var(--teal);
  color: #fff;
}
.panel-head h2 { margin: 0; font-size: 18px; }
.panel-close {
  background: rgba(255,255,255,.2);
  border: none;
  color: #fff;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  font-size: 18px;
  cursor: pointer;
}
.saved-list { flex: 1; overflow-y: auto; padding: 12px; }
.saved-item {
  background: var(--card);
  border-radius: 12px;
  padding: 14px;
  margin-bottom: 10px;
  box-shadow: 0 1px 3px rgba(0,0,0,.08);
  cursor: pointer;
}
.saved-item h3 { margin: 0 0 4px; font-size: 16px; }
.saved-item .meta { font-size: 13px; color: var(--muted); }
.saved-item .area { font-size: 15px; font-weight: 700; color: var(--teal); margin-top: 4px; }
.empty-state { text-align: center; color: var(--muted); margin-top: 60px; font-size: 15px; }

/* ---- Modals ---- */
.modal {
  position: absolute;
  inset: 0;
  z-index: 800;
  background: rgba(15,23,42,.5);
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.modal-card {
  background: var(--card);
  width: 100%;
  max-width: 480px;
  border-radius: 18px 18px 0 0;
  padding: 20px 18px calc(20px + env(safe-area-inset-bottom));
  box-shadow: var(--shadow);
  max-height: 90vh;
  overflow-y: auto;
}
.modal-card h2 { margin: 0 0 14px; font-size: 19px; }
.modal-note { margin: -8px 0 14px; font-size: 13px; color: var(--muted); }
.modal-card label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  margin-bottom: 12px;
}
.modal-card input,
.modal-card textarea,
.modal-card select {
  width: 100%;
  margin-top: 5px;
  padding: 11px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  font-size: 16px;
  font-family: inherit;
  color: var(--ink);
}
.modal-card hr { border: none; border-top: 1px solid var(--line); margin: 4px 0 14px; }
.modal-actions { display: flex; gap: 8px; margin-top: 6px; }
.modal-actions.wrap { flex-wrap: wrap; }
.modal-actions .act { box-shadow: none; border: 1px solid var(--line); }
.modal-actions .act-primary { border-color: var(--teal); }

.detail-body { font-size: 14px; line-height: 1.7; }
.detail-body .row { display: flex; justify-content: space-between; border-bottom: 1px solid var(--line); padding: 6px 0; }
.detail-body .row span:first-child { color: var(--muted); }
.detail-body .row span:last-child { font-weight: 600; }
.detail-body .notes { margin-top: 10px; color: var(--muted); }

/* ---- Toast ---- */
.toast {
  position: absolute;
  bottom: calc(86px + env(safe-area-inset-bottom));
  left: 50%;
  transform: translateX(-50%);
  z-index: 900;
  background: #1e293b;
  color: #fff;
  padding: 12px 20px;
  border-radius: 999px;
  font-size: 14px;
  box-shadow: var(--shadow);
  animation: pop .2s ease;
}
@keyframes pop { from { opacity: 0; transform: translate(-50%, 8px); } to { opacity: 1; } }

/* Precise crosshair cursor for placing points (instead of the grab hand) */
.leaflet-grab,
.leaflet-container,
.leaflet-interactive { cursor: crosshair; }
.leaflet-dragging .leaflet-grab,
.leaflet-dragging .leaflet-container { cursor: crosshair; }

/* Vertex markers — draggable */
.vertex-marker {
  width: 18px;
  height: 18px;
  background: #fff;
  border: 3px solid var(--teal);
  border-radius: 50%;
  box-shadow: 0 1px 4px rgba(0,0,0,.4);
  cursor: move;
}
/* Midpoint "add a point here" handles */
.mid-marker {
  width: 16px;
  height: 16px;
  background: rgba(255,255,255,.55);
  border: 2px solid var(--teal);
  border-radius: 50%;
  box-shadow: 0 1px 3px rgba(0,0,0,.35);
  cursor: copy;
}
.edge-label {
  background: rgba(15,23,42,.78);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  padding: 1px 5px;
  border-radius: 4px;
  white-space: nowrap;
}
.leaflet-div-icon { background: transparent; border: none; }

/* ---- New v2 components ---- */
.act-soft { background: #ccfbf1; color: var(--teal-dark); box-shadow: none; }

.field-row { display: flex; gap: 10px; align-items: flex-end; }
.field-row .grow { flex: 1; }
.field-row .act { flex: 0 0 auto; margin-bottom: 12px; padding: 11px 12px; }

.panel-head-actions { display: flex; gap: 8px; align-items: center; }
.panel-icon {
  background: rgba(255,255,255,.2); border: none; color: #fff;
  width: 36px; height: 36px; border-radius: 50%; font-size: 18px; cursor: pointer;
}

/* Photos */
.photos-field { margin-bottom: 12px; }
.photos-head { display: flex; justify-content: space-between; align-items: center; font-size: 13px; font-weight: 600; color: var(--muted); margin-bottom: 6px; }
.add-photo-btn { cursor: pointer; display: inline-flex; align-items: center; }
.photos-head .add-photo-btn { background: #ccfbf1; color: var(--teal-dark); padding: 6px 10px; border-radius: 8px; font-size: 13px; }
.photo-strip { display: flex; gap: 8px; flex-wrap: wrap; }
.photo-thumb { position: relative; width: 64px; height: 64px; border-radius: 8px; overflow: hidden; box-shadow: 0 1px 3px rgba(0,0,0,.2); }
.photo-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; cursor: pointer; }
.photo-thumb .rm { position: absolute; top: 2px; right: 2px; background: rgba(0,0,0,.6); color: #fff; border: none; width: 20px; height: 20px; border-radius: 50%; font-size: 12px; cursor: pointer; line-height: 1; }

/* Calc preview */
.calc-preview { background: #f0fdfa; border: 1px solid #99f6e4; border-radius: 10px; padding: 10px 12px; margin-bottom: 12px; font-size: 13px; line-height: 1.6; color: var(--teal-dark); }
.calc-preview .big { font-size: 18px; font-weight: 700; color: var(--teal); }
.calc-preview.hidden { display: none; }

/* Inclinometer */
.incl-wrap { text-align: center; padding: 18px 0 8px; }
.incl-angle { font-size: 64px; font-weight: 800; color: var(--teal); line-height: 1; }
.incl-sub { font-size: 13px; color: var(--muted); margin-top: 8px; }

/* Profiles editor */
.profiles-head { display: flex; flex-direction: column; gap: 2px; margin-bottom: 8px; }
.profile-editor { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.profile-row { display: flex; gap: 8px; align-items: center; }
.profile-row input.pname { flex: 1; margin: 0; }
.profile-row input.ppct { width: 84px; margin: 0; }
.profile-row .pdel { background: #fee2e2; color: var(--danger); border: none; border-radius: 8px; width: 40px; height: 40px; font-size: 16px; cursor: pointer; flex: 0 0 auto; }

/* Photo viewer */
.photo-viewer { position: absolute; inset: 0; z-index: 950; background: rgba(0,0,0,.92); display: flex; align-items: center; justify-content: center; }
.photo-viewer img { max-width: 96%; max-height: 90%; border-radius: 6px; }
.photo-viewer-close { position: absolute; top: calc(env(safe-area-inset-top) + 14px); right: 16px; background: rgba(255,255,255,.2); color: #fff; border: none; width: 44px; height: 44px; border-radius: 50%; font-size: 20px; cursor: pointer; }

.detail-body .breakdown { margin-top: 8px; padding-top: 8px; border-top: 2px solid var(--line); }

/* Google Drive backup card */
.drive-card { background: #f0fdfa; border: 1px solid #99f6e4; border-radius: 12px; padding: 12px 14px; margin-bottom: 6px; }
.drive-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 10px; }
.drive-title { font-weight: 600; color: var(--teal-dark); }
.drive-status { font-size: 12px; color: var(--muted); text-align: right; }
/* Stale or failed backup — must be impossible to mistake for the healthy state */
.drive-status.drive-warn { color: var(--danger); font-weight: 700; }

/* Mode toggle (area / ridge lines) — sits above the locate button */
.mode-fab {
  position: absolute;
  right: 12px;
  bottom: calc(148px + env(safe-area-inset-bottom));
  z-index: 480;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: none;
  background: #fff;
  color: var(--teal);
  font-size: 22px;
  box-shadow: var(--shadow);
  cursor: pointer;
}
.mode-fab:active { transform: scale(0.94); }

/* Move-whole-outline button — bottom-left, same row as "Drop pin" (that slot is
   free in area mode; the End-line button only appears in ridge mode) */
.move-outline-btn {
  position: absolute;
  left: 12px;
  bottom: calc(84px + env(safe-area-inset-bottom));
  z-index: 480;
  background: #fff;
  color: var(--teal);
  border: none;
  border-radius: 999px;
  padding: 13px 16px;
  font-size: 15px;
  font-weight: 600;
  box-shadow: var(--shadow);
  cursor: pointer;
  white-space: nowrap;
}
.move-outline-btn:active { transform: scale(0.96); }
.move-outline-btn.active { background: #d85a30; color: #fff; }

/* Auto-outline FAB — stacked above the mode toggle */
.footprint-fab {
  position: absolute;
  right: 12px;
  bottom: calc(210px + env(safe-area-inset-bottom));
  z-index: 480;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: none;
  background: #fff;
  color: var(--teal);
  font-size: 22px;
  box-shadow: var(--shadow);
}
.footprint-fab:active { transform: scale(0.94); }
.footprint-fab.busy { opacity: 0.6; }

/* Zoom buttons — stacked above the auto-outline FAB. They exist because PINCH
   gestures stop at the deepest satellite imagery Google holds (zoom 20 around
   Bloemfontein), while map.setZoom() keeps going and simply upscales. Blurry,
   but that's the accepted trade for separating corners that sit close together. */
.zoom-fab {
  position: absolute;
  right: 12px;
  bottom: calc(272px + env(safe-area-inset-bottom));
  z-index: 480;
  display: flex;
  flex-direction: column;
  border-radius: 22px;
  overflow: hidden;
  background: #fff;
  box-shadow: var(--shadow);
}
.zoom-fab button {
  width: 44px; height: 44px;
  border: none; background: #fff; color: var(--teal);
  font-size: 21px; font-weight: 700; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.zoom-fab button:first-child { border-bottom: 1px solid var(--line); }
.zoom-fab button:active { background: #e2e8f0; }

/* ---- Crosshair magnifier ----
   A SECOND, non-interactive map is rendered tiny and then CSS-scaled up. Scaling the
   MAIN map instead would have made a finger-drag move the map twice as far as it
   looks, which would make precise positioning worse, not better — the whole point.
   LOUPE_SCALE in app.js must match the scale() here. */
.loupe {
  position: absolute;
  left: 12px;
  top: calc(84px + env(safe-area-inset-top));
  width: 150px; height: 150px;
  border-radius: 50%;
  overflow: hidden;
  z-index: 470;
  border: 3px solid #fff;
  box-shadow: var(--shadow);
  background: #0f172a;
  pointer-events: none;          /* never steals a tap from the map underneath */
}
/* Rendered at 100px and scaled 2.5 -> a 250px square centred on a 150px circle.
   Deliberately MUCH larger than the circle, for two reasons:
     1. Google's logo and "Terms" sit in the map's bottom corners. At 60px they
        landed inside the circle and covered half the view; at 100px they fall
        well outside the 75px radius and are simply cropped by the clip.
     2. Rotation. A square always contains its own inscribed circle however it is
        turned, so heading sync can never expose an empty corner.
   JS appends rotate() to this transform — keep scale() first and the origin centred. */
.loupe-map {
  position: absolute;
  left: 50%; top: 50%;
  width: 100px; height: 100px;
  margin-left: -50px; margin-top: -50px;
  transform-origin: center center;
  transform: scale(2.5);
}
/* The loupe crosshair reuses .crosshair, so it is pixel-identical to the main one.
   Only the outer box needs positioning — the arms and dot come from .crosshair. */
.loupe .loupe-cross {
  position: absolute;
  top: 50%; left: 50%;
  width: 46px; height: 46px;
  transform: translate(-50%, -50%);
  z-index: 2;
}

.reload-fab {
  position: absolute;
  right: 12px;
  bottom: calc(494px + env(safe-area-inset-bottom));
  z-index: 480;
  width: 44px; height: 44px;
  border: none; border-radius: 50%;
  background: var(--card); color: var(--ink);
  font-size: 20px; line-height: 1;
  box-shadow: var(--shadow); cursor: pointer;
}
.reload-fab:active { transform: scale(0.94); }

.loupe-fab {
  position: absolute;
  right: 12px;
  bottom: calc(432px + env(safe-area-inset-bottom));
  z-index: 480;
  width: 44px; height: 44px;
  border-radius: 22px;
  border: none;
  background: #fff;
  font-size: 20px;
  box-shadow: var(--shadow);
  cursor: pointer;
}
.loupe-fab:active { transform: scale(0.94); }
.loupe-fab.off { opacity: .45; }

/* Label on/off toggle — sits above the zoom buttons. Dimmed when labels are off,
   so the button itself shows the current state. */
.labels-fab {
  position: absolute;
  right: 12px;
  bottom: calc(370px + env(safe-area-inset-bottom));
  z-index: 480;
  width: 44px; height: 44px;
  border-radius: 22px;
  border: none;
  background: #fff;
  font-size: 20px;
  box-shadow: var(--shadow);
  cursor: pointer;
}
.labels-fab:active { transform: scale(0.94); }
.labels-fab.off { opacity: .45; }

/* Labels on the already-measured "ghost" roofs — smaller and softer than the
   active edge labels so they read as background context, not the current shape */
.ghost-gmap-label {
  text-shadow: 0 0 3px rgba(0,0,0,.95), 0 0 3px rgba(0,0,0,.95);
  opacity: .9;
}

/* End-line button (ridge mode) */
.end-line-btn {
  position: absolute;
  left: 12px;
  bottom: calc(84px + env(safe-area-inset-bottom));
  z-index: 480;
  background: #d85a30;
  color: #fff;
  border: none;
  border-radius: 999px;
  padding: 13px 18px;
  font-size: 15px;
  font-weight: 600;
  box-shadow: var(--shadow);
  cursor: pointer;
  white-space: nowrap;
}
.end-line-btn:active { transform: scale(0.96); }

/* Snap-to-roofs button (line mode) — sits above End line */
.snap-lines-btn {
  position: absolute;
  left: 12px;
  bottom: calc(136px + env(safe-area-inset-bottom));
  z-index: 480;
  background: #fff;
  color: var(--teal);
  border: none;
  border-radius: 999px;
  padding: 11px 16px;
  font-size: 14px;
  font-weight: 600;
  box-shadow: var(--shadow);
  cursor: pointer;
  white-space: nowrap;
}
.snap-lines-btn:active { transform: scale(0.96); }

/* How close a pin must be before it snaps — sits above Snap to roofs.
   Dimmed at the Off end so the state is readable at a glance. */
.snap-panel {
  position: absolute;
  left: 12px;
  bottom: calc(188px + env(safe-area-inset-bottom));
  z-index: 480;
  background: #fff;
  border-radius: 16px;
  padding: 8px 14px 10px;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.snap-panel label {
  font-size: 13px;
  font-weight: 600;
  color: var(--teal-dark);
  white-space: nowrap;
}
.snap-panel input[type="range"] {
  width: 148px;
  accent-color: var(--teal);
  margin: 0;
}
.snap-panel.off label { color: #64748b; }

/* Per-line rows in the save dialog */
.line-editor { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.line-row { display: flex; align-items: center; gap: 6px; font-size: 13px; flex-wrap: wrap; margin-bottom: 6px; }
.line-row .ll { flex: 1 0 100%; color: var(--ink); font-weight: 600; }
.line-row .lk { margin: 0; padding: 8px 8px; border: 1px solid var(--line); border-radius: 10px; font-size: 14px; }
.line-row .lp { width: 74px; margin: 0; padding: 9px 10px; border: 1px solid var(--line); border-radius: 10px; font-size: 15px; }
.line-row .lmeas { background: #ccfbf1; color: var(--teal-dark); border: none; border-radius: 8px; width: 40px; height: 36px; font-size: 15px; cursor: pointer; flex: 0 0 auto; }
.line-row .lu { color: var(--muted); }
.line-row .la { color: var(--teal); font-weight: 700; white-space: nowrap; }
.line-row .ldel { background: #fee2e2; color: var(--danger); border: none; border-radius: 8px; width: 36px; height: 36px; font-size: 14px; cursor: pointer; flex: 0 0 auto; }

/* Current-location floating button */
.locate-fab {
  position: absolute;
  right: 12px;
  bottom: calc(86px + env(safe-area-inset-bottom));
  z-index: 480;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: none;
  background: #fff;
  color: var(--teal);
  box-shadow: var(--shadow);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.locate-fab:active { transform: scale(0.94); }

/* Edge-length labels on the Google map (white text needs a shadow to be readable) */
.edge-gmap-label {
  text-shadow: 0 0 3px rgba(0,0,0,.9), 0 0 3px rgba(0,0,0,.9);
}

/* Job view */
.job-scroll { flex: 1; overflow-y: auto; padding: 12px; }
.job-address { margin: 0 0 12px; color: var(--muted); font-size: 14px; }
.job-areas { display: flex; flex-direction: column; gap: 8px; }
.job-area-item {
  background: var(--card); border-radius: 12px; padding: 12px 14px;
  box-shadow: 0 1px 3px rgba(0,0,0,.08); display: flex; align-items: center; gap: 10px; cursor: pointer;
}
.job-area-item .ja-thumb { width: 44px; height: 44px; border-radius: 8px; object-fit: cover; flex: 0 0 auto; background: #e2e8f0; }
.job-area-item .ja-body { flex: 1; min-width: 0; }
.job-area-item .ja-body h4 { margin: 0 0 2px; font-size: 15px; }
.job-area-item .ja-body .ja-meta { font-size: 12px; color: var(--muted); }
.job-area-item .ja-area { font-weight: 700; color: var(--teal); font-size: 15px; white-space: nowrap; }
.job-add { margin: 10px 0 4px; width: 100%; }
.job-hint { margin: 4px 2px 0; font-size: 12px; color: var(--muted); line-height: 1.4; }

.job-card { background: var(--card); border-radius: 12px; padding: 14px; margin-top: 12px; box-shadow: 0 1px 3px rgba(0,0,0,.08); }
.job-total-row { display: flex; justify-content: space-between; align-items: center; font-size: 16px; }
.job-total-row b { color: var(--teal); font-size: 20px; }

.paint-card { background: #f0fdfa; border: 1px solid #99f6e4; border-radius: 12px; padding: 14px; margin-top: 12px; }
.paint-card h3 { margin: 0 0 10px; font-size: 16px; color: var(--teal-dark); }
.paint-card label { display: block; font-size: 13px; font-weight: 600; color: var(--muted); margin-bottom: 10px; }
.paint-card input { width: 100%; margin-top: 5px; padding: 11px 12px; border: 1px solid var(--line); border-radius: 10px; font-size: 16px; }
.paint-result { font-size: 14px; line-height: 1.7; color: var(--teal-dark); margin-top: 4px; }
.paint-result .litres { font-size: 24px; font-weight: 800; color: var(--teal); }

.job-actions { display: flex; gap: 8px; padding: 10px 12px calc(10px + env(safe-area-inset-bottom)); background: #f8fafc; border-top: 1px solid var(--line); }
.job-actions .act { flex: 1; }

/* Quote builder + price book */
.qt-btn { display: block; width: 100%; margin-bottom: 8px; text-align: left; font-size: 16px; padding: 16px 14px; box-shadow: none; border: 1px solid var(--line); }
.qform label { display: block; font-size: 13px; font-weight: 600; color: var(--muted); margin-bottom: 10px; }
.qform input, .qform select, .qform textarea { width: 100%; margin-top: 4px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; font-size: 16px; font-family: inherit; color: var(--ink); background: #fff; }
.qform .half { display: flex; gap: 8px; }
.qform .half > label { flex: 1; min-width: 0; }
.q-sec { font-weight: 700; color: var(--teal-dark); margin: 16px 0 8px; font-size: 13px; text-transform: uppercase; letter-spacing: .4px; }
.q-line { display: flex; justify-content: space-between; gap: 8px; padding: 4px 0; border-bottom: 1px solid var(--line); font-size: 12.5px; }
.q-line .qn { color: var(--ink); min-width: 0; }
.q-line .qv { color: var(--muted); white-space: nowrap; }
.q-line .qt { font-weight: 700; white-space: nowrap; }
.q-result { background: #f0fdfa; border: 1px solid #99f6e4; border-radius: 12px; padding: 12px 14px; margin: 14px 0; font-size: 14px; line-height: 1.8; }
.q-result .big { font-size: 21px; font-weight: 800; color: var(--teal); }
/* Why a figure is missing, not just that it is. Shown when a quote covers no roof
   area, where a per-m² rate has nothing to divide by. */
.q-result .q-warn { display: block; color: var(--danger); font-style: normal; font-size: 13px; line-height: 1.5; margin: 6px 0; }
.q-extra-row { display: flex; gap: 6px; margin-bottom: 6px; }
.q-extra-row input { margin-top: 0; padding: 9px 10px; font-size: 14px; min-width: 0; }
.q-extra-row .xd { flex: 2; } .q-extra-row .xp { flex: 1; } .q-extra-row .xq { width: 64px; flex: 0 0 auto; }
.quote-item { background: var(--card); border-radius: 10px; padding: 10px 12px; margin-top: 8px; box-shadow: 0 1px 3px rgba(0,0,0,.08); display: flex; justify-content: space-between; align-items: center; gap: 8px; cursor: pointer; font-size: 13px; }
.quote-item .qi-total { font-weight: 700; color: var(--teal); white-space: nowrap; }
.pb-row { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; align-items: center; }
.pb-row input, .pb-row select { margin-top: 0; padding: 8px 9px; font-size: 13px; min-width: 0; }
.pb-row .pn { flex: 1 0 100%; } .pb-row .pv { flex: 1; }   /* name on its own line, values + controls wrap below */
.pb-labelrow { flex-wrap: nowrap; }
.logo-field { display: flex; align-items: center; gap: 10px; margin-top: 6px; }
.logo-preview { max-height: 54px; max-width: 150px; border: 1px solid var(--line); border-radius: 8px; background: #fff; padding: 4px; } .pb-row .pb-del { background: #fee2e2; color: var(--danger); border: none; border-radius: 8px; width: 34px; height: 34px; font-size: 13px; cursor: pointer; flex: 0 0 auto; }
.pb-add { background: #ccfbf1; color: var(--teal-dark); border: none; border-radius: 8px; padding: 8px 12px; font-size: 13px; font-weight: 600; cursor: pointer; margin-bottom: 10px; }
.pb-labelrow .pb-lbl { flex: 1; font-size: 13px; color: var(--ink); }
.pb-labelrow input { flex: 0 0 96px; max-width: 96px; }
.pb-move { background: #e2e8f0; color: var(--ink); border: none; border-radius: 8px; width: 30px; height: 34px; font-size: 13px; cursor: pointer; flex: 0 0 auto; }
.pb-move:disabled { opacity: .35; }
.pb-note { font-size: 11.5px; color: var(--muted); margin: 2px 0 8px; }
/* ---- Quote area picker ---- */
.qa-tools { display: flex; gap: 8px; margin-bottom: 8px; }
.qa-tools .act { flex: 1; padding: 8px; font-size: 13px; }
.qa-list { max-height: 45vh; overflow-y: auto; margin-bottom: 4px; }
.qa-item { display: flex; align-items: center; gap: 10px; padding: 10px 4px; border-bottom: 1px solid var(--line); cursor: pointer; }
.qa-item input[type="checkbox"] { width: 20px; height: 20px; flex: 0 0 auto; accent-color: var(--teal-dark); }
.qa-txt { display: flex; flex-direction: column; min-width: 0; }
.qa-txt b { font-size: 14px; color: var(--ink); }
.qa-sub { font-size: 12px; color: var(--muted); }

/* Checkbox option inside a quote form — the generic ".qform input" rule stretches
   inputs to full width, which would blow a checkbox up, so override it here. */
.qform label.q-check { display: flex; align-items: center; gap: 10px; color: var(--ink); }
.qform label.q-check input[type="checkbox"] { width: 20px; height: 20px; flex: 0 0 auto; margin-top: 0; accent-color: var(--teal-dark); }

/* ---- Pitch from photo ---- */
/* Opened FROM the save dialog, which is a .modal at z-index 800 — so this panel
   must outrank it or it opens invisibly underneath. Closing it reveals the save
   dialog again, which is exactly what we want. */
#pitchPhotoPanel { z-index: 900; }
.pp-choose { display: block; width: 100%; text-align: center; cursor: pointer; }
.pp-tips { margin-top: 16px; background: var(--card); border-radius: 12px; padding: 12px 14px; }
.pp-tips strong { display: block; margin-bottom: 6px; }
.pp-tips ul { margin: 0; padding-left: 18px; }
.pp-tips li { font-size: 13.5px; color: var(--muted); margin-bottom: 6px; line-height: 1.45; }

.pp-stage { flex: 1; display: flex; flex-direction: column; overflow-y: auto; }
.pp-canvas-wrap { position: relative; background: #0f172a; height: 46vh; flex: 0 0 auto; touch-action: none; }
.pp-canvas-wrap canvas#pitchCanvas { width: 100%; height: 100%; display: block; }
.pp-loupe {
  position: absolute; width: 110px; height: 110px; border-radius: 50%;
  border: 3px solid #fff; box-shadow: 0 3px 12px rgba(0,0,0,.5);
  pointer-events: none; z-index: 20;
}
.pp-prompt {
  background: var(--teal); color: #fff; padding: 11px 14px;
  font-size: 15px; font-weight: 600; text-align: center;
}
.pp-live { padding: 8px 14px; font-size: 14px; color: var(--muted); text-align: center; }

.pp-result { padding: 4px 14px 16px; }
.pr-main { text-align: center; line-height: 1; margin-bottom: 8px; }
#prValue { font-size: 64px; font-weight: 800; color: var(--teal-dark); }
.pr-deg { font-size: 34px; font-weight: 700; color: var(--teal-dark); }
.pr-badge {
  display: block; text-align: center; font-weight: 800; letter-spacing: 1px;
  padding: 8px; border-radius: 10px; font-size: 15px; margin-bottom: 8px;
}
.pr-badge.high { background: #dcfce7; color: #166534; }
.pr-badge.medium { background: #fef3c7; color: #92400e; }
.pr-badge.low { background: #fee2e2; color: #991b1b; }
.pr-range { text-align: center; font-size: 16px; font-weight: 600; margin-bottom: 10px; }
.pr-cands { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-bottom: 10px; }
.pr-cand {
  background: var(--card); border: 1px solid #e2e8f0; border-radius: 999px;
  padding: 9px 15px; font-size: 16px; font-weight: 700; cursor: pointer; color: var(--text);
}
.pr-cand.chosen { background: #ccfbf1; border-color: var(--teal); color: var(--teal-dark); }
.pp-caveat { font-size: 12.5px; color: var(--muted); line-height: 1.45; margin: 4px 0 10px; }
.pr-detail { background: var(--card); border-radius: 10px; padding: 10px 12px; margin-top: 8px; font-size: 14px; }
.pr-detail div { display: flex; justify-content: space-between; padding: 3px 0; }

/* Standard-pitch picker */
.pitch-pick-list { display: flex; flex-direction: column; gap: 6px; margin: 8px 0 4px; }
.pitch-pick {
  display: flex; align-items: center; gap: 10px;
  width: 100%; text-align: left; cursor: pointer;
  background: var(--card); border: 1px solid #e2e8f0; border-radius: 10px;
  padding: 11px 14px; font-size: 15px; color: var(--text);
}
.pitch-pick:active { transform: scale(0.99); }
.pitch-pick.current { border-color: var(--teal); background: #ccfbf1; }
.pitch-pick .pp-deg { font-weight: 700; font-size: 17px; min-width: 58px; }
.pitch-pick .pp-mult { color: var(--muted); font-size: 13px; min-width: 62px; }
.pitch-pick .pp-area { margin-left: auto; font-weight: 700; color: var(--teal-dark); }

/* Language toggle (client photo message) */
.lang-toggle { display: flex; gap: 8px; margin: 6px 0 10px; }
.lang-toggle .act { flex: 1; }
#photoAskText {
  width: 100%; font-size: 14px; line-height: 1.45;
  border: 1px solid #e2e8f0; border-radius: 10px; padding: 10px; resize: vertical;
}

/* Edit-mode banner */
.edit-banner {
  position: absolute;
  top: calc(env(safe-area-inset-top) + 64px);
  left: 10px; right: 10px;
  z-index: 480;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  background: #f59e0b; color: #1e293b;
  padding: 8px 12px; border-radius: 12px;
  box-shadow: var(--shadow); font-size: 13px;
}
.edit-cancel {
  background: rgba(0,0,0,.15); border: none; color: #1e293b;
  padding: 6px 12px; border-radius: 8px; font-weight: 600; cursor: pointer; white-space: nowrap;
}

/* ---------- In-app camera ----------
   Full screen: framing a roof from the ground needs the whole viewport, and the
   point of this screen is that he never leaves the app to use it. */
.cam-overlay {
  position: fixed; inset: 0; z-index: 2600;
  background: #000; display: flex; align-items: center; justify-content: center;
}
.cam-overlay.hidden { display: none; }
.cam-overlay video {
  width: 100%; height: 100%;
  /* cover, not contain: black bars waste the viewfinder on a phone. The frame that
     gets saved is what the video element shows, so the two must agree — see
     drawVideoFrame() in app.js, which crops to match. */
  object-fit: cover;
}
.cam-bar {
  position: absolute; left: 0; right: 0;
  bottom: calc(24px + env(safe-area-inset-bottom));
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 22px; gap: 12px;
}
.cam-btn {
  background: rgba(0,0,0,.55); color: #fff; border: 1px solid rgba(255,255,255,.35);
  border-radius: 999px; padding: 11px 16px; font-size: 15px; font-weight: 600;
  -webkit-tap-highlight-color: transparent;
}
/* Big and centred — this gets pressed one-handed, often at arm's length. */
.cam-shoot {
  width: 76px; height: 76px; border-radius: 50%;
  background: #fff; border: 5px solid rgba(255,255,255,.45);
  box-shadow: 0 0 0 2px rgba(0,0,0,.25);
  flex: 0 0 auto; -webkit-tap-highlight-color: transparent;
}
.cam-shoot:active { transform: scale(.93); }
.cam-count {
  position: absolute; top: calc(14px + env(safe-area-inset-top)); left: 0; right: 0;
  text-align: center; color: #fff; font-size: 14px; font-weight: 600;
  text-shadow: 0 1px 3px rgba(0,0,0,.8); pointer-events: none;
}
.cam-error {
  position: absolute; left: 24px; right: 24px; top: 50%; transform: translateY(-50%);
  background: #dc2626; color: #fff; border-radius: 12px; padding: 16px 18px;
  font-size: 15px; line-height: 1.5; text-align: center;
}
.cam-error.hidden { display: none; }
