/* SRVCE — application styles.
 *
 * Loaded AFTER the theme, so these rules win on equal specificity without
 * needing !important. Keep this file small: anything that could be a theme
 * preset should be one, or the next theme change becomes an archaeology
 * project.
 */
/* ==========================================================================
   Design tokens
   ==========================================================================
   These were used throughout this file and defined NOWHERE - every var()
   silently resolved to nothing. Most of the time that degrades invisibly: a
   missing border colour just draws the default, a missing radius draws a
   square corner. It only became visible on the customer picker, where a
   dropdown with no background let the form show straight through it.

   Defined here at the top so there is one place to change them, and scoped to
   :root so the theme's own variables are untouched. */
:root {
  /* Surfaces. surface-2 is the raised one - menus, popovers - and has to be
     opaque, which is the whole reason this file exists. */
  --surface-1: #f4f6f8;
  --surface-2: #ffffff;

  --border: #dfe4e9;
  --border-strong: #b9c2cb;

  --text-primary: #1d2630;
  --text-secondary: #5b6b7a;
  --text-muted: #8a97a3;
  --text-accent: #0d6efd;
  --text-success: #1a7f4b;
  --text-warning: #8a6100;

  --bg-success: #e8f6ee;
  --bg-warning: #fdf3e0;

  --fill-primary: #2c3e50;

  --radius: 8px;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* The dark page theme moves the surfaces and text; borders and accents hold.
   Only the values that would be unreadable are restated. */
body[data-pc-theme="dark"] {
  --surface-1: #1f262e;
  --surface-2: #262f39;

  --border: #333d47;
  --border-strong: #4a5560;

  --text-primary: #e8edf2;
  --text-secondary: #a9b6c2;
  --text-muted: #7d8b98;

  --bg-success: #14301f;
  --bg-warning: #33270d;

  --fill-primary: #3d5568;
}


/* Wordmark. Helvetica and wide tracking, matching Chart so the two read as
   one product rather than a tool bolted into a dashboard. */
.srv-mark {
  font-family: Helvetica, "Helvetica Neue", Arial, sans-serif;
  font-size: 15px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: #fff;
  font-weight: 300;
}
.srv-mark b { font-weight: 700; }
.srv-mark-dark { color: #1d2630; font-size: 20px; }

/* Empty states. Used often enough in a young app to be worth naming. */
.srv-empty { padding: 56px 20px; text-align: center; }
.srv-empty i { font-size: 42px; opacity: .35; display: block; margin-bottom: 12px; }
.srv-empty h5 { margin-bottom: 6px; }
.srv-empty p { max-width: 460px; margin: 0 auto; }

/* A key/value table for record detail panes. */
.srv-kv td { padding: 9px 8px; vertical-align: top; }
.srv-kv td:first-child { width: 190px; font-weight: 600; }

/* Acting-as banner. Deliberately unmissable: the whole risk of support
   access is forgetting whose data is on screen. Amber for read-only, red
   when changes would be real. */
.srv-acting {
  position: sticky; top: 0; z-index: 1030;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 8px 16px; font-size: 13px; font-weight: 600; color: #1d2630;
}
.srv-acting.ro { background: #ffd76e; }
.srv-acting.rw { background: #ff8a7a; }
.srv-acting i  { margin-right: 5px; }



/* ==========================================================================
   Landing — light, with the brand photograph (25 Sep 2026)
   ==========================================================================
   Sign-in and signup. White page, mint card, navy type: the brand guide's
   light slides (the mint panel on white is its "Primary" logo page).

   DESKTOP (960px and wider) splits the screen. The left 52% is the
   photograph, fixed, so signup's long form scrolls past it; the page's own
   content is pushed right by the same amount. The photograph is a CSS
   background INSIDE the media query, so a phone never downloads it.

   Colours, all from the guide:
     navy #001321   green #36DD91   mint #EDF7F2   white #FFFFFF
     Cloud #EDEFF7  Smoke #D3D6E0   Space #9DA2B3  Graphite #6E7180

   Green is an accent here, never a surface for text: navy on it reads, but
   green type on white does not. The button is navy, the arrow and the focus
   ring are green. */

body.srv-landing { background: #FFFFFF; color: #001321; min-height: 100dvh; }

.srv-land {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: #FFFFFF;
  font-family: "Manrope", system-ui, -apple-system, "Segoe UI", sans-serif;
}

@media (min-width: 960px) {
  .srv-land { padding-left: 52vw; }
  .srv-land::before {
    content: "";
    position: fixed;
    top: 0; bottom: 0; left: 0;
    width: 52vw;
    background-color: #001321;               /* while it loads */
    background-image: url("../brand/login-signboard.jpg");
    background-image: image-set(url("../brand/login-signboard.webp") type("image/webp"),
                                url("../brand/login-signboard.jpg")  type("image/jpeg"));
    background-size: cover;
    background-position: 55% 50%;            /* keeps the sign in frame */
  }
  /* To use the tablet instead: the two login-signboard names become
     login-tablet, and the position 46% 50%. */
}

.srv-land-main {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 24px 24px;
}

.srv-land-sheet { width: 100%; max-width: 400px; }

/* Rule, logo, rule - the title block from August, in the guide's grey. */
.srv-land-rule { height: 1px; background: #D3D6E0; }

.srv-land-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 2px 16px;
}

/* Only reached if a page still prints the name as type. */
.srv-land-mark {
  font-size: clamp(34px, 9vw, 44px);
  font-weight: 800;
  letter-spacing: .12em;
  line-height: 1;
  margin: 0;
  color: #001321;
}

.srv-land-est {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .14em;
  color: #6E7180;
  white-space: nowrap;
}

.srv-land-sub {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #6E7180;
  margin: 12px 2px 0;
}

.srv-land-form { margin-top: 28px; }

.srv-land-form form {
  background: #EDF7F2;
  border-radius: 14px;
  padding: 24px 22px 22px;
  color: #001321;
}
.srv-land-form form .srv-land-rule { background: #D3D6E0; }

.srv-land-form .form-label {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .02em;
  color: #001321;
  margin-bottom: 6px;
}
.srv-land-form .form-text { color: #6E7180; font-size: 12.5px; }
.srv-land-form .form-check-label { color: #001321; }
.srv-land-form .form-check-input { border-color: #BCBFCC; }
.srv-land-form .form-check-input:checked { background-color: #001321; border-color: #001321; }
.srv-land-form .form-check-input:focus { box-shadow: 0 0 0 3px rgba(54,221,145,.35); border-color: #001321; }

.srv-land-form .form-control {
  height: 44px;
  background: #FFFFFF;
  border: 1px solid #D3D6E0;
  border-radius: 8px;
  color: #001321;
  font-size: 15px;
}
.srv-land-form .form-control:focus {
  background: #FFFFFF;
  border-color: #001321;
  box-shadow: 0 0 0 3px rgba(54,221,145,.35);
  color: #001321;
}

.srv-land-form .btn-primary {
  height: 46px;
  border-radius: 8px;
  background: #001321;
  border-color: #001321;
  color: #EDF7F2;
  font-weight: 700;
  letter-spacing: .02em;
}
.srv-land-form .btn-primary:hover,
.srv-land-form .btn-primary:focus,
.srv-land-form .btn-primary:active {
  background: #0B2A3F; border-color: #0B2A3F; color: #FFFFFF;
}
.srv-land-form .btn-primary:focus-visible { box-shadow: 0 0 0 3px rgba(54,221,145,.5); }

.srv-land-form .alert { border-radius: 8px; font-size: 13px; }

/* The second call to action, on white beside the card. */
.srv-land-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: 46px;
  margin-top: 14px;
  border: 1px solid #D3D6E0;
  border-radius: 8px;
  background: transparent;
  color: #001321;
  font-size: 13.5px;
  font-weight: 700;
  text-decoration: none;
  transition: background-color .15s ease, border-color .15s ease;
}
.srv-land-cta:hover { background: #EDF7F2; border-color: #36DD91; color: #001321; }
.srv-land-cta i { font-size: 15px; color: #1FB573; }

/* The small line under signup ("Own several businesses?"). */
.srv-land-alt { text-align: center; margin: 16px 0 0; font-size: 13px; color: #6E7180; }
.srv-land-alt a { color: #001321; font-weight: 700; text-decoration: underline;
                  text-decoration-color: #36DD91; text-underline-offset: 3px; text-decoration-thickness: 2px; }

.srv-land-foot {
  border-top: 1px solid #EDEFF7;
  padding: 14px 20px;
  text-align: center;
  font-size: 11px;
  letter-spacing: .04em;
  color: #6E7180;
}

@media (max-height: 700px) {
  .srv-land-main { align-items: flex-start; padding-top: 34px; }
}


/* Activity stream. One chronological list per property - notes, visits,
   invoices, skips. Service Autopilot keeps notes and activity in separate
   panels, which splits the story of a property across two places and leaves
   neither complete. */
.srv-stream-row {
  display: flex;
  gap: 12px;
  padding: 12px 0;
  border-top: 0.5px solid var(--border);
}
.srv-stream-row:first-child { border-top: 0; padding-top: 0; }
.srv-stream-row > i { font-size: 18px; color: var(--text-muted); flex: none; margin-top: 1px; }
.srv-stream-body { flex: 1; min-width: 0; font-size: 14px; line-height: 1.6; }
.srv-stream-meta { font-size: 12px; color: var(--text-muted); margin-top: 3px; }
.srv-stream-amt { font-variant-numeric: tabular-nums; font-weight: 500; white-space: nowrap; }


/* Business switcher, in the sidebar under the wordmark. Only rendered when
   there is more than one business to reach. */
.srv-switch { padding: 0 16px 4px; }
.srv-switch-btn {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 9px 11px;
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.12);
  border-radius: var(--radius);
  color: #fff; font-size: 13.5px; font-weight: 500; text-align: left;
}
.srv-switch-btn::after { display: none; }
.srv-switch-btn:hover { background: rgba(255,255,255,.1); }
.srv-switch-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.srv-switch-menu { min-width: 240px; }
.srv-switch-menu form { margin: 0; }
.srv-switch-menu .dropdown-item { padding: 8px 14px; }
.srv-switch-menu .dropdown-item small { font-size: 11.5px; }

/* Blue, not amber: switching businesses is routine work, unlike a support
   session, and colouring it like a warning would train people to ignore the
   ones that matter. */
.srv-acting.sw { background: #cfe2f3; }


/* Sidebar mark. Sized by WIDTH, not height.
   Sizing by height meant a 5:1 logo could only ever be 150px wide in a 250px
   sidebar - small, off-centre-looking, and with no obvious cause. The slot is
   250x50; the mark fills it and the height follows the aspect. */
.srv-brand-img {
  display: block;
  width: 100%;
  max-width: 250px;
  max-height: 56px;      /* stops a near-square upload growing the header */
  object-fit: contain;
  object-position: left center;
}

.srv-switch-icon {
  width: 22px; height: 22px; flex: none;
  border-radius: 4px; object-fit: contain; background: rgba(255,255,255,.08);
}
/* Fallback initial, so a business with no icon still lines up with those
   that have one rather than shifting the row. */
.srv-switch-initial {
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 500; color: var(--text-secondary);
  background: var(--surface-1);
}
.srv-switch-btn .srv-switch-icon { background: rgba(255,255,255,.12); }



/* ==========================================================================
   Branding page
   ========================================================================== */

.srv-bsec {
  padding: 11px 18px;
  background: var(--surface-1);
  border-bottom: 0.5px solid var(--border);
  font-size: 12px; font-weight: 500; color: var(--text-secondary);
}
.srv-bsec:not(:first-child) { border-top: 0.5px solid var(--border); }

.srv-brow {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 18px;
  border-bottom: 0.5px solid var(--border);
}
.srv-brow:last-child { border-bottom: 0; }

.srv-brow-label { width: 128px; flex: none; }
.srv-brow-name  { font-size: 13.5px; font-weight: 500; }
.srv-brow-where { font-size: 11.5px; color: var(--text-secondary); margin-top: 1px; }

/* Chequerboard, because these are transparent PNGs: a plain white well hides
   a white logo until it reaches an invoice. */
.srv-brow-prev {
  flex: none;
  display: flex; align-items: center; justify-content: center;
  border: 0.5px solid var(--border); border-radius: 6px; padding: 4px;
  background-image:
    linear-gradient(45deg, rgba(128,128,128,.13) 25%, transparent 25%),
    linear-gradient(-45deg, rgba(128,128,128,.13) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, rgba(128,128,128,.13) 75%),
    linear-gradient(-45deg, transparent 75%, rgba(128,128,128,.13) 75%);
  background-size: 12px 12px;
  background-position: 0 0, 0 6px, 6px -6px, -6px 0;
}
.srv-brow-prev img { max-width: 100%; max-height: 100%; object-fit: contain; }

.srv-brow-act  { display: flex; align-items: center; gap: 4px; margin: 0; }
.srv-brow-act label { cursor: pointer; }
.srv-brow-namef { display: flex; gap: 8px; flex: 1; max-width: 320px; margin: 0; }

/* ---- preview ---------------------------------------------------------- */

.srv-prev-label { font-size: 11.5px; color: var(--text-secondary); margin-bottom: 7px; }

.srv-prev-side { background: #1f2a33; border-radius: 8px; padding: 14px; }
/* Same rule as the real sidebar, so the preview cannot flatter an upload
   that will look wrong once it is live. */
.srv-prev-head { margin-bottom: 11px; }
.srv-prev-head img {
  display: block; width: 100%; max-width: 250px; max-height: 56px;
  object-fit: contain; object-position: left center;
}

.srv-prev-switch {
  display: flex; align-items: center; gap: 8px;
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.12);
  border-radius: 6px; padding: 7px 9px;
  color: #fff; font-size: 12px;
}
.srv-prev-ico {
  width: 20px; height: 20px; flex: none;
  border-radius: 4px; object-fit: contain; background: rgba(255,255,255,.12);
}
.srv-prev-ini {
  display: flex; align-items: center; justify-content: center;
  font-size: 10.5px; font-weight: 500;
}

.srv-prev-inv {
  background: #fff;
  border: 0.5px solid var(--border);
  border-radius: 8px;
  padding: 16px;
}
.srv-prev-inv img { max-height: 32px; max-width: 180px; object-fit: contain; display: block; }
.srv-prev-inv-name { font-size: 15px; font-weight: 500; color: #1d2630; }
.srv-prev-inv-meta { font-size: 11px; color: #5F6B63; line-height: 1.6; margin-top: 10px; }

@media (max-width: 1199px) {
  .srv-prev-side, .srv-prev-inv { max-width: 340px; }
}


/* Accent swatches. Big enough to judge a colour by, small enough that ten
   fit without scrolling. */
.srv-swatches { display: flex; flex-wrap: wrap; gap: 10px; }
.srv-swatch {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  cursor: pointer; padding: 7px 6px 6px; border-radius: var(--radius);
  border: 1.5px solid transparent; min-width: 62px;
}
.srv-swatch span { width: 34px; height: 34px; border-radius: 8px; display: block; }
.srv-swatch small { font-size: 11px; color: var(--text-secondary); }
.srv-swatch:hover { background: var(--surface-1); }
.srv-swatch.on { border-color: var(--border-strong); background: var(--surface-1); }
.srv-swatch.on small { color: var(--text-primary); font-weight: 500; }

/* The appearance rows reuse the branding row shape, but their controls sit
   right rather than filling the space. */
.srv-brow .btn-group { margin-left: auto; }

/* Checked state, defined here rather than relying on the theme's.
   The markup is right - input immediately followed by label - but the theme
   is 3 MB and something later in it was winning, so a selection did not show
   until the page reloaded. This file loads last, so this settles it.

   Worth doing explicitly anyway: a control that gives no feedback until you
   press Save is one people press twice. */
.srv-brow .btn-check:checked + .btn,
.srv-brow .btn-check:checked + .btn:hover {
  background: var(--fill-primary, #2c3e50);
  border-color: var(--fill-primary, #2c3e50);
  color: #fff;
  box-shadow: none;
}
.srv-brow .btn-check:focus-visible + .btn {
  box-shadow: 0 0 0 .2rem rgba(0,0,0,.12);
}

/* Swatch selection, driven by the radio itself rather than a class the
   server writes - so it responds to the click, not to the save. */
.srv-swatch:has(input:checked) {
  border-color: var(--border-strong);
  background: var(--surface-1);
}
.srv-swatch:has(input:checked) small {
  color: var(--text-primary);
  font-weight: 500;
}
.srv-swatch input:checked + span {
  box-shadow: 0 0 0 2px var(--surface-2), 0 0 0 4px var(--text-primary);
}


/* ==========================================================================
   Light sidebar corrections
   ==========================================================================
   The theme sets `.pc-submenu .pc-item.active > .pc-link { color: #fff }`
   with no dark-sidebar qualifier - correct when the sidebar is dark, and
   invisible now that light is the default. The active item simply vanished,
   leaving a bullet and no word.

   Scoped to :not([data-pc-sidebar-theme="dark"]) rather than applied
   generally, so the dark sidebar keeps the styling it was written for. */
body:not([data-pc-sidebar-theme="dark"]) .pc-sidebar .pc-submenu .pc-item.active > .pc-link,
body:not([data-pc-sidebar-theme="dark"]) .pc-sidebar .pc-submenu > .pc-item.active > .pc-link {
  color: var(--text-primary, #1d2630);
  font-weight: 500;
}

/* Same problem one level up: a collapsed section that happens to be active
   uses white for its own label. */
body:not([data-pc-sidebar-theme="dark"]) .pc-sidebar .pc-navbar > .pc-item.pc-hasmenu.active > .pc-link,
body:not([data-pc-sidebar-theme="dark"]) .pc-sidebar .pc-navbar > .pc-item.pc-trigger > .pc-link {
  color: var(--text-primary, #1d2630);
}

/* And the inactive submenu links, which sit at a contrast tuned for a dark
   panel and read as grey-on-white here. */
body:not([data-pc-sidebar-theme="dark"]) .pc-sidebar .pc-submenu .pc-item > .pc-link {
  color: var(--text-secondary, #5b6b7a);
}
body:not([data-pc-sidebar-theme="dark"]) .pc-sidebar .pc-submenu .pc-item > .pc-link:hover {
  color: var(--text-primary, #1d2630);
}


/* A PIN is read aloud or written down, so it is set large and monospaced
   with the digits grouped - 8 and B are a support call otherwise. */
.srv-pin {
  font-family: var(--font-mono, ui-monospace, Menlo, monospace);
  font-size: 32px;
  font-weight: 500;
  letter-spacing: .12em;
  padding: 14px 18px;
  border-radius: var(--radius);
  background: var(--surface-1);
  border: 0.5px solid var(--border);
  display: inline-block;
}


/* ==========================================================================
   Services
   ==========================================================================
   Each row is its own form, so a rate can be changed and saved without
   touching anything else. One big form would mean an error in one row
   discarding edits to all of them. */

.srv-svc {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px 18px;
  border-bottom: 0.5px solid var(--border);
  margin: 0;
}
.srv-svc:last-of-type { border-bottom: 0; }
.srv-svc.off { opacity: .55; }

.srv-svc-main { display: flex; align-items: center; gap: 9px; flex: 1 1 220px; min-width: 200px; }
.srv-svc-colour {
  width: 30px; height: 30px; flex: none; padding: 2px;
  border: 0.5px solid var(--border); border-radius: 6px; background: none; cursor: pointer;
}
.srv-svc-name { flex: 1; }

.srv-svc-price { display: flex; align-items: center; gap: 5px; flex: 0 0 auto; }
.srv-svc-cur { color: var(--text-secondary); font-size: 13px; }
.srv-svc-price input { width: 84px; text-align: right; font-variant-numeric: tabular-nums; }
.srv-svc-price select { width: 128px; }

.srv-svc-flags { display: flex; gap: 12px; flex-wrap: wrap; flex: 1 1 100%; }
.srv-svc-flag {
  display: flex; align-items: center; gap: 5px;
  font-size: 12px; color: var(--text-secondary); cursor: pointer; margin: 0;
}
.srv-svc-flag input:disabled + span { opacity: .5; cursor: not-allowed; }

.srv-svc-act { display: flex; align-items: center; gap: 4px; margin-left: auto; }
.srv-svc-used { font-size: 11.5px; color: var(--text-muted); white-space: nowrap; }

/* Template list */
.srv-tpl {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 16px; margin: 0;
  border-bottom: 0.5px solid var(--border);
}
.srv-tpl:last-of-type { border-bottom: 0; }
.srv-tpl-dot { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.srv-tpl-body { flex: 1; min-width: 0; }
.srv-tpl-name { display: block; font-size: 13.5px; font-weight: 500; }
.srv-tpl-body small { font-size: 11.5px; color: var(--text-secondary); }


/* Per-service totals on a property. Several numbers side by side, because a
   lawn figure and a hardscape figure are quoted and billed separately -
   adding them together produces a number nobody uses. */
.srv-svc-totals { display: flex; flex-wrap: wrap; gap: 26px; }
.srv-svc-total-n {
  font-size: 26px; font-weight: 500; line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.srv-svc-total-l { font-size: 12px; color: var(--text-secondary); margin-top: 1px; }


/* ==========================================================================
   Schedule
   ========================================================================== */

.srv-week { display: grid; grid-template-columns: repeat(7, 1fr); gap: 8px; }
.srv-day {
  display: flex; flex-direction: column; gap: 2px;
  padding: 10px 8px; border-radius: var(--radius);
  background: var(--surface-2); border: 0.5px solid var(--border);
  text-decoration: none; color: inherit; text-align: center;
}
.srv-day:hover { border-color: var(--border-strong); }
.srv-day.on { border-color: var(--border-strong); background: var(--surface-1); }
.srv-day.today .srv-day-num { color: var(--text-accent); }
.srv-day-name  { font-size: 11px; color: var(--text-secondary); text-transform: uppercase; }
.srv-day-num   { font-size: 19px; font-weight: 500; line-height: 1.1; }
.srv-day-count { font-size: 11px; color: var(--text-secondary); }

/* Route list */
.srv-route { list-style: none; margin: 0; padding: 0; }
.srv-stop {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px 18px;
  border-bottom: 0.5px solid var(--border);
  cursor: grab;
}
.srv-stop:last-child { border-bottom: 0; }
.srv-stop.drag { opacity: .4; }
.srv-stop.done    { background: var(--bg-success); }
.srv-stop.skipped { background: var(--bg-warning); }

/* A stop with no number came from another day and has not been placed. The
   dash is deliberately visible rather than blank - it is a decision waiting
   to be made, not missing data. */
.srv-stop-n {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-1); font-size: 12.5px; font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.srv-stop-body { flex: 1; min-width: 0; }
.srv-stop-name { display: block; font-weight: 500; font-size: 14px; text-decoration: none; }
.srv-stop-meta { display: block; font-size: 12.5px; color: var(--text-secondary); margin-top: 1px; }
.srv-stop-note {
  display: block; font-size: 12.5px; color: var(--text-secondary);
  margin-top: 3px; font-style: italic;
}
.srv-moved {
  display: inline-block; margin-left: 6px; padding: 1px 6px;
  border-radius: 4px; background: var(--bg-warning); color: var(--text-warning);
  font-size: 11px; font-style: normal;
}
.srv-stop-act { display: flex; align-items: center; gap: 4px; flex: none; }
.srv-stop-status { font-size: 12px; color: var(--text-secondary); text-transform: capitalize; }

@media (max-width: 767px) {
  .srv-week { grid-template-columns: repeat(4, 1fr); }
  .srv-stop { flex-wrap: wrap; }
  .srv-stop-act { width: 100%; justify-content: flex-end; }
}


/* ==========================================================================
   Routes
   ========================================================================== */

.srv-route-row {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 16px; border-bottom: 0.5px solid var(--border);
  text-decoration: none; color: inherit;
}
.srv-route-row:last-child { border-bottom: 0; }
.srv-route-row:hover { background: var(--surface-1); }
.srv-route-row.on { background: var(--surface-1); box-shadow: inset 3px 0 0 var(--border-strong); }
.srv-route-dot { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.srv-route-body { flex: 1; min-width: 0; }
.srv-route-name { display: block; font-size: 13.5px; font-weight: 500; }
.srv-route-body small { font-size: 11.5px; color: var(--text-secondary); }

.srv-route-stops { list-style: none; margin: 0; padding: 0; }

/* Route heading inside a day. One truck drives two routes in winter, so the
   second route's stop 1 needs to read as a new block rather than a mistake
   after the first route's stop 12. */
.srv-route-head {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 18px;
  background: var(--surface-1);
  border-bottom: 0.5px solid var(--border);
  font-size: 12px; font-weight: 500;
}

/* A gap wider than a normal cycle. Not an error - a fortnightly property is
   legitimately 14 days - so it is a flag to look at, not a warning. */
.srv-late { color: var(--text-warning); font-weight: 500; }


/* ==========================================================================
   Click-to-sequence
   ========================================================================== */

.seq-map-wrap { position: relative; }
.seq-map {
  height: 380px;
  width: 100%;
  border-bottom: 0.5px solid var(--border);
  background: var(--surface-1);
}
@media (max-width: 767px) {
  /* Taller on a phone, because the map is the interface there and a short
     one means constant panning. */
  .seq-map { height: 300px; }
}

.seq-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 16px;
  border-bottom: 0.5px solid var(--border);
  background: var(--surface-1);
}
.seq-count { font-size: 12.5px; color: var(--text-secondary); }
.seq-count.done { color: var(--text-success); font-weight: 500; }

/* Pins carry their own number, so it cannot drift out of step with the
   marker it belongs to. */
.seq-pin { background: none; border: 0; }
.seq-pin svg { display: block; filter: drop-shadow(0 1px 2px rgba(0,0,0,.3)); }
.seq-pin.active svg { filter: drop-shadow(0 2px 5px rgba(0,0,0,.45)); }

.seq-list { list-style: none; margin: 0; padding: 0; }
.seq-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 16px;
  border-bottom: 0.5px solid var(--border);
  cursor: pointer;
}
.seq-row:last-child { border-bottom: 0; }
.seq-row.hot { background: var(--surface-1); }
.seq-row.done    { background: var(--bg-success); }
.seq-row.skipped { background: var(--bg-warning); }

/* Unsequenced stops sit quieter, so what is left to do is obvious without
   counting. */
.seq-row.todo .seq-name { color: var(--text-secondary); }
.seq-row.nopos { opacity: .6; cursor: default; }

.seq-n {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-1); border: 1px solid var(--border);
  font-size: 12.5px; font-weight: 500; font-variant-numeric: tabular-nums;
}
.seq-row:not(.todo) .seq-n {
  background: var(--fill-primary, #2c3e50); border-color: transparent; color: #fff;
}

.seq-body { flex: 1; min-width: 0; }
.seq-name { display: block; font-size: 14px; font-weight: 500; }
.seq-meta { display: block; font-size: 12px; color: var(--text-secondary); margin-top: 1px; }

.seq-acts { display: flex; align-items: center; gap: 2px; flex: none; }
.seq-status { font-size: 12px; color: var(--text-secondary); text-transform: capitalize; }
.seq-undo {
  border: 0; background: none; color: var(--text-muted);
  font-size: 17px; line-height: 1; padding: 2px 7px; cursor: pointer;
}
.seq-undo:hover { color: var(--text-primary); }

/* Room for a thumb. Ordering happens in a truck as often as at a desk. */
@media (max-width: 767px) {
  .seq-row { padding: 13px 14px; gap: 10px; }
  .seq-acts .btn { padding: 5px 10px; }
}


/* Property identity: parcel, lot size and where the position came from.
   Laid out as facts side by side rather than a sentence, because they are
   looked at rather than read. */
.srv-ident { display: flex; flex-wrap: wrap; gap: 22px; }
.srv-ident-k {
  display: block; font-size: 11px; text-transform: uppercase;
  letter-spacing: .04em; color: var(--text-secondary);
}
.srv-ident-v {
  display: block; font-size: 14px; font-weight: 500; margin-top: 1px;
  font-variant-numeric: tabular-nums;
}


/* Service restrictions. Advisory - nothing is blocked - but they have to be
   in front of whoever is ordering the day rather than filed on a page they
   would have to go and open. */
.srv-restrict {
  background: var(--bg-warning);
  color: var(--text-warning);
  font-size: 13px;
  padding: 9px 14px !important;
}
.seq-warn {
  display: block;
  margin-top: 3px;
  font-size: 12px;
  color: var(--text-warning);
  font-weight: 500;
}


/* One-field pickers: type, choose from the list below. */
.srv-pick { position: relative; z-index: 2; }
/* The card must not clip a list that hangs past its edge. */
.srv-pick-open, .card:has(.srv-pick-list:not([hidden])) { overflow: visible; }
.srv-pick-list {
  /* Well above the cards below it. 40 was enough in theory, but a card that
     creates its own stacking context would have trapped it - and the cost of
     being generous here is nothing. */
  position: absolute; z-index: 1000; left: 0; right: 0; top: 100%;
  margin: 2px 0 0; padding: 4px; list-style: none;
  background: var(--surface-2);
  border: 0.5px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: 0 6px 18px rgba(0,0,0,.14);
  max-height: 260px; overflow-y: auto;
}
.srv-pick-item {
  padding: 8px 10px; border-radius: 6px; cursor: pointer; font-size: 14px;
}
.srv-pick-item:hover, .srv-pick-item.on { background: var(--surface-1); }


/* Day pills. Big enough to tap, and reading as a set rather than a column of
   checkboxes - "Mon Wed Fri" is how somebody says it. */
.srv-pills { display: flex; flex-wrap: wrap; gap: 6px; }
.srv-pill { margin: 0; cursor: pointer; }
.srv-pill input { position: absolute; opacity: 0; pointer-events: none; }
.srv-pill span {
  display: inline-block;
  min-width: 46px; text-align: center;
  padding: 7px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
  font-size: 13px; font-weight: 500;
  color: var(--text-secondary);
  user-select: none;
}
.srv-pill input:checked + span {
  background: var(--fill-primary);
  border-color: var(--fill-primary);
  color: #fff;
}
.srv-pill input:focus-visible + span { box-shadow: 0 0 0 3px rgba(0,0,0,.12); }

/* The block the switch reveals, set apart so it reads as conditional. */
.srv-restrict-box {
  border-left: 3px solid var(--border-strong);
  padding: 14px 0 2px 16px;
  margin-bottom: 8px;
}


/* Yes / No, and the window row. The checked state is defined here for the
   same reason it is on the appearance page: the theme's own rule loses, and
   a control that shows no selection reads as broken. */
.btn-check:checked + .btn-outline-secondary {
  background: var(--fill-primary);
  border-color: var(--fill-primary);
  color: #fff;
}

/* Days and hours on one row - they answer the same question, and "Mon Wed
   Fri, after eight" is one thought rather than two. */
.srv-window { display: flex; gap: 18px; flex-wrap: wrap; align-items: flex-end; }
.srv-window-days { flex: 1 1 320px; min-width: 280px; }
.srv-window-time { flex: 0 0 130px; }
.srv-window-time input { width: 100%; }

@media (max-width: 575px) {
  .srv-window-time { flex: 1 1 45%; }
}


/* ==========================================================================
   Crew stop page
   ==========================================================================
   Built for a thumb on a tablet in a truck: few actions, large, and always
   in the same place. Nothing here is a smaller version of a desktop page. */

.srv-stop-page { background: var(--surface-1); }


.stop-head {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px; background: var(--surface-2);
  border-bottom: 0.5px solid var(--border);
  position: sticky; top: 0; z-index: 20;
}
.stop-back {
  font-size: 26px; line-height: 1; text-decoration: none;
  color: var(--text-secondary); padding: 4px 10px 8px 0;
}
.stop-title { flex: 1; min-width: 0; }
.stop-title h1 { font-size: 19px; margin: 0; font-weight: 600; }
.stop-title p  { font-size: 13px; margin: 2px 0 0; color: var(--text-secondary); }
.stop-n {
  flex: none; width: 34px; height: 34px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--fill-primary); color: #fff; font-weight: 600;
}

.stop-flash { padding: 11px 16px; font-size: 14px; }
.stop-flash.ok   { background: var(--bg-success); color: var(--text-success); }
.stop-flash.warn { background: var(--bg-warning); color: var(--text-warning); }

.stop-map { height: 300px; background: var(--surface-1); }
.stop-map.placing { cursor: crosshair; box-shadow: inset 0 0 0 3px #d9483b; }
.issue-pin { background: none; border: 0; }
.issue-pin svg { filter: drop-shadow(0 1px 3px rgba(0,0,0,.4)); }


.stop-notes { padding: 14px 16px; background: var(--surface-2);
              border-bottom: 0.5px solid var(--border); font-size: 14px; }
.stop-notes p { margin: 0 0 6px; }
.stop-notes p:last-child { margin-bottom: 0; }

.stop-issues { padding: 14px 16px; }
.stop-issues h2 { font-size: 12px; text-transform: uppercase; letter-spacing: .04em;
                  color: var(--text-secondary); margin: 0 0 8px; }
.issue { display: flex; gap: 10px; align-items: flex-start; padding: 9px 0; }
.issue-dot { width: 10px; height: 10px; border-radius: 50%; margin-top: 5px; flex: none; }
.issue.broken  .issue-dot { background: #d9483b; }
.issue.warning .issue-dot { background: #e0a326; }
.issue-body { font-size: 14px; }
.issue-body small { display: block; color: var(--text-secondary); font-size: 12px; }

/* Actions pinned to the bottom, where the thumb already is. */
.stop-act {
  flex: 0 0 auto;
  display: flex; gap: 8px; padding: 10px 12px;
  background: var(--surface-2); border-top: 0.5px solid var(--border);
  /* Clear of the home indicator on an iPad. */
  padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px));
}
.act {
  flex: 1; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 1px;
  min-height: 54px; padding: 8px 10px; border: 0; border-radius: 10px;
  font-size: 15px; font-weight: 600; text-decoration: none; cursor: pointer;
}
.act small { font-weight: 400; font-size: 11px; opacity: .85; }
.act-form { flex: 1; display: flex; }
.act-form .act { width: 100%; }
.act.drive { background: var(--surface-1); color: var(--text-primary); }
.act.go    { background: #1f7a4d; color: #fff; }
.act.done  { background: #1f7a4d; color: #fff; }
.act.flag  { background: var(--bg-warning); color: var(--text-warning); }
.act.ghost { background: var(--surface-1); color: var(--text-secondary); }
.act.state { background: var(--surface-1); color: var(--text-secondary); font-weight: 500; }

/* In flow rather than pinned. Pinned at a fixed offset it sat over the
   action bar on a short screen and floated above it on a tall one - the
   clipped "Next: 1107 Sioux Drive" in two of three screenshots. */
.stop-next {
  flex: 0 0 auto;
  padding: 10px 16px; font-size: 13.5px;
  background: var(--fill-primary); color: #fff;
  display: flex; gap: 12px; align-items: center;
}
.stop-next a { color: #fff; text-decoration: underline; }
.stop-next strong { flex: 1; }

/* The report sheet. Over the page rather than a separate screen, so the map
   stays visible - the pin has to be placed on it. */
.report-sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  background: var(--surface-2); border-top: 0.5px solid var(--border-strong);
  border-radius: 14px 14px 0 0; padding: 16px;
  padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -8px 28px rgba(0,0,0,.18);
  /* Scrollable, and never taller than the screen. Six kinds plus a note on a
     short landscape phone would otherwise put the buttons off the bottom. */
  max-height: 85vh; max-height: 85dvh;
  overflow-y: auto;
}
/* Above the action bar, so the sheet is never behind the thing that opened
   it. */
.stop-act { z-index: 30; }
.report-sheet h2 { font-size: 16px; margin: 0 0 12px; }
.report-sheet textarea { width: 100%; font-size: 15px; padding: 10px;
                         border: 1px solid var(--border); border-radius: 8px; }
.kinds { display: flex; gap: 8px; margin-bottom: 12px; }
.kind { flex: 1; margin: 0; cursor: pointer; }
.kind input { position: absolute; opacity: 0; }
.kind span {
  display: block; text-align: center; padding: 12px 8px;
  border: 2px solid var(--border); border-radius: 10px;
  font-size: 14px; font-weight: 600; color: var(--text-secondary);
}
.kind.broken  input:checked + span { border-color: #d9483b; background: #fdecea; color: #a5322a; }
.kind.warning input:checked + span { border-color: #e0a326; background: var(--bg-warning);
                                     color: var(--text-warning); }
.hint { font-size: 12.5px; color: var(--text-secondary); margin: 8px 0 12px; }
.hint.set { color: var(--text-success); font-weight: 500; }
.sheet-act { display: flex; gap: 8px; }

.seq-open { color: inherit; text-decoration: none; }
.seq-open:hover { text-decoration: underline; }


/* ==========================================================================
   Crew stop page on a wide screen
   ==========================================================================
   The page is built for an iPad in a truck - a single column with the
   actions pinned to the bottom of the viewport, which is right there and
   strange on a desktop, where it strands a bar across an empty screen.

   So above 900px it becomes what it actually is: a panel. The actions sit at
   the end of it rather than at the end of the window, and the whole thing
   stops pretending the browser is a phone. */

}

/* Nothing traced yet. The map alone is not an answer - it looks like the
   page failed rather than like a property nobody has measured. */
.stop-nochart {
  padding: 14px 16px;
  font-size: 13.5px;
  color: var(--text-secondary);
  background: var(--surface-2);
  border-bottom: 0.5px solid var(--border);
}
.stop-nochart a { font-weight: 500; }


/* ==========================================================================
   Crew stop: the map is the page
   ==========================================================================
   A crew opens this to LOOK at the property. Everything else is a handful of
   words, so it sits on the imagery rather than pushing it into a band too
   small to read at property scale.

   The map fills whatever height is left after the header, the next-stop bar
   and the actions - so there is no empty space below it and no fixed height
   that is wrong on every device. */


.stop {
  max-width: 720px; margin: 0 auto;
  min-height: 100vh;
  min-height: 100dvh;          /* dvh, so an iPad toolbar does not crop it */
  display: flex; flex-direction: column;
}

.stop-mapwrap { position: relative; flex: 1 1 auto; min-height: 240px; }
.stop-map { position: absolute; inset: 0; height: auto; }

/* Bottom LEFT, over the street rather than the lawn. Covering the thing they
   came to look at would be a poor trade for saving a row. */
.stop-chips {
  position: absolute; left: 10px; bottom: 10px; z-index: 500;
  display: flex; flex-wrap: wrap; gap: 6px; max-width: calc(100% - 74px);
  pointer-events: none;         /* never intercept a map drag */
}
.chip {
  background: rgba(255,255,255,.94);
  border-radius: 8px; padding: 6px 10px;
  box-shadow: 0 1px 4px rgba(0,0,0,.28);
}
.chip-k {
  display: block; font-size: 9.5px; text-transform: uppercase;
  letter-spacing: .05em; color: #5b6b7a; line-height: 1.2;
}
.chip-v { display: block; font-size: 15px; font-weight: 700; color: #1d2630; }
.chip-v.mono { font-family: var(--font-mono); font-size: 14px; }

/* Notes sit under the map and only exist when there is something to say. */
.stop-notes { flex: 0 0 auto; }



/* ==========================================================================
   Crew stop: phone, tablet, either orientation
   ==========================================================================
   These are two different problems. A phone in portrait has height and no
   width; a tablet in landscape has width and very little height. One layout
   cannot serve both - a full-height map is right on the first and leaves a
   200px letterbox on the second.

   So: stacked where there is height, side by side where there is not. */

/* ---- default: stacked. Phones, and tablets held upright. ---------------- */
.stop {
  max-width: 820px; margin: 0 auto;
  min-height: 100vh; min-height: 100dvh;
  display: flex; flex-direction: column;
}
/* The wrapper has to be a flex column in EVERY layout, not only landscape.
   It was a plain block in portrait, so the map's flex:1 had nothing to
   stretch against and collapsed to its minimum - the short map with an empty
   page underneath. */
.stop-body {
  flex: 1 1 auto;
  display: flex; flex-direction: column;
  min-height: 0;                /* or the map cannot shrink inside it */
}
.stop-mapwrap { flex: 1 1 auto; min-height: 160px; position: relative; }

/* ---- wide and short: side by side -------------------------------------- */
/* A tablet in landscape, or any window shorter than it is wide. The map
   takes the height it can get and the detail moves beside it rather than
   under it. */

@media (min-width: 820px) and (orientation: landscape) {
  /* No padding to subtract, because the page has none at this size. A
     full-height panel inside a padded page is taller than the viewport, and
     everything below the map falls off the bottom - which is exactly what
     "pushed down and hard to see" was. */
  .stop { max-width: none; height: 100vh; height: 100dvh; }

  .stop-body { flex-direction: row; }
  .stop-mapwrap { flex: 1 1 62%; }
  .stop-side {
    flex: 0 0 320px; display: flex; flex-direction: column;
    border-left: 0.5px solid var(--border);
    background: var(--surface-2); overflow-y: auto;
  }
  /* Chips are redundant when the panel is beside the map. */
  .stop-chips { display: none; }
  .stop-side .stop-facts { display: block; }
}

/* ---- the side panel, only used in the landscape layout ------------------ */
.stop-side { display: none; }
@media (min-width: 820px) and (orientation: landscape) {
  .stop-side { display: flex; }
}
.stop-side .fact-row {
  padding: 12px 16px; border-bottom: 0.5px solid var(--border);
}
.stop-side .fact-row .k {
  display: block; font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text-secondary);
}
.stop-side .fact-row .v { display: block; font-size: 17px; font-weight: 600; }

/* ---- phones: everything a little tighter, targets a little bigger ------- */
@media (max-width: 420px) {
  .stop-title h1 { font-size: 17px; }
  .stop-title p  { font-size: 12px; }
  .chip { padding: 5px 9px; }
  .chip-v { font-size: 14px; }
  .act { min-height: 58px; font-size: 14px; }
  .stop-act { gap: 6px; padding: 8px 8px calc(8px + env(safe-area-inset-bottom, 0px)); }
}

/* ---- very short windows: give the map what is left --------------------- */
@media (max-height: 520px) {
  .stop-mapwrap { min-height: 140px; }
  .act { min-height: 46px; }
  .stop-next { padding: 6px 16px; font-size: 12.5px; }
}


/* An armed button. Amber rather than red: this is "are you sure", not "this
   is dangerous", and a page of red buttons stops meaning anything.
   The colour is the signal, but the LABEL is the message - somebody who
   glances away and back needs to read what it now says, not decode a hue. */
[data-confirm].is-armed {
  background: #b46a00 !important;
  border-color: #b46a00 !important;
  color: #fff !important;
  animation: srv-arm .18s ease-out;
}
@keyframes srv-arm {
  from { transform: scale(.97); }
  to   { transform: scale(1); }
}
[data-confirm].is-working {
  opacity: .65;
  pointer-events: none;
}

/* Reduced motion: no pulse, colour and label still change. */
@media (prefers-reduced-motion: reduce) {
  [data-confirm].is-armed { animation: none; }
}


/* ==========================================================================
   Reports from the field
   ========================================================================== */

/* A quiet accent, not a red card. The dashboard should draw the eye to this
   without looking like something has gone badly wrong - most of these are a
   sprinkler head. */
.srv-alert-card { box-shadow: inset 3px 0 0 #e0a326; }

.srv-issue-row {
  display: flex; gap: 11px; align-items: flex-start;
  padding: 12px 18px;
  border-bottom: 0.5px solid var(--border);
  text-decoration: none; color: inherit;
}
.srv-issue-row:last-child { border-bottom: 0; }
.srv-issue-row:hover { background: var(--surface-1); }

.srv-issue-dot {
  width: 10px; height: 10px; border-radius: 50%; flex: none; margin-top: 5px;
}
.srv-issue-dot.broken  { background: #d9483b; }
.srv-issue-dot.warning { background: #e0a326; }

.srv-issue-body { flex: 1; min-width: 0; }
.srv-issue-note { display: block; font-size: 14px; font-weight: 500; }
.srv-issue-body small { display: block; font-size: 12px; color: var(--text-secondary); }

.srv-issue.broken  { box-shadow: inset 3px 0 0 #d9483b; }
.srv-issue.warning { box-shadow: inset 3px 0 0 #e0a326; }

/* "or ZIP" beside a label. Says what is actually needed rather than putting a
   red asterisk on both and meaning neither. */
.srv-req {
  font-size: 11px; font-weight: 400; color: var(--text-secondary);
  text-transform: none; letter-spacing: 0;
}


/* Invoice status. Words rather than colour alone - "sent" and "paid" are
   different facts, and a colour-blind reader should not have to guess. */
.srv-inv-status {
  display: inline-block; font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .04em;
  padding: 2px 8px; border-radius: 999px;
}
.srv-inv-status.draft { background: var(--surface-1); color: var(--text-secondary); }
.srv-inv-status.sent  { background: #e7f0fb; color: #1c5fa8; }
.srv-inv-status.paid  { background: var(--bg-success); color: var(--text-success); }
.srv-inv-status.void  { background: var(--surface-1); color: var(--text-muted);
                        text-decoration: line-through; }

/* Kind and category, on the service row. */
.srv-svc-meta { display: flex; gap: 6px; flex: 1 1 260px; }
.srv-svc-meta select { width: 110px; flex: none; }


/* Marker kinds, laid out as a grid rather than a row - six of them do not
   fit side by side on a phone, and a horizontal scroll hides half of them. */
/* --k is set per label from PHP, so each kind carries its own colour. The
   fallback matters: a marker whose kind lost its colour should still look
   selected rather than invisible. */
.kinds-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.kinds-grid .kind { --k: var(--fill-primary); }
.kinds-grid .kind span {
  border-color: var(--border);
  padding: 10px 4px;
  font-size: 13px;
}
.kinds-grid .kind input:checked + span {
  border-color: var(--k);
  color: #fff;
  background: var(--k);
}
@media (max-width: 380px) {
  .kinds-grid { grid-template-columns: repeat(2, 1fr); }
}


/* A backdrop behind the marker sheet. Not decoration: it makes plain that
   the sheet is the thing being answered, and gives somewhere to tap to
   dismiss it. Without one the sheet reads as part of the page and can be
   ignored - which is how a marker got saved with nobody having seen the
   choices. */
.sheet-backdrop {
  position: fixed; inset: 0; z-index: 55;
  background: rgba(15, 20, 25, .38);
}

/* Explicit inset, so the sheet spans the screen rather than inheriting a
   width from wherever it happens to sit in the document. */
.report-sheet {
  left: 0; right: 0; bottom: 0;
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
}

/* A draggable pin should look like one. */
.issue-pin { cursor: grab; }
.leaflet-marker-draggable { cursor: grab; }
.leaflet-dragging .leaflet-marker-draggable { cursor: grabbing; }
