/* MyPWB — PWB Exterior Cleaning
   Palette taken from the official PWB logo:
   cyan "PWB" #29abe2 · deep blue "Exterior Cleaning" #1b3576 · orange houses #f7941e */
:root {
  /* How wide a page may get. Wide enough to use the screen, capped so a line of
     text never runs the full width of a 27-inch monitor. */
  --page-max: 1640px;
  --navy: #1b3576;
  --navy-2: #24439a;
  --blue: #1a9cd8;
  --blue-dark: #127fb4;
  --orange: #f7941e;
  --sky: #e8f5fc;
  --ink: #1c2733;
  --muted: #5c6b7a;
  --line: #dde5ec;
  --bg: #f4f7fa;
  --white: #ffffff;
  --ok: #1a7f4e;
  --ok-bg: #e3f4ea;
  --warn: #9a6700;
  --warn-bg: #fff3d6;
  --danger: #b3261f;
  --radius: 10px;
  --shadow: 0 1px 3px rgba(11, 42, 74, 0.08), 0 4px 14px rgba(11, 42, 74, 0.06);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  background: var(--bg);
  color: var(--ink);
  line-height: 1.55;
  font-size: 16px;
}
a { color: var(--blue-dark); text-decoration: none; }
a:hover { text-decoration: underline; }
h1 { font-size: 1.6rem; margin: 0 0 0.25rem; color: var(--navy); }
h2 { font-size: 1.15rem; margin: 0 0 0.75rem; color: var(--navy); }
h3 { font-size: 1rem; margin: 0 0 0.25rem; color: var(--navy); }
h2.mt { margin-top: 1.5rem; }
hr { border: none; border-top: 1px solid var(--line); margin: 1.25rem 0; }

.muted { color: var(--muted); margin: 0.1rem 0; }
.muted-sm { color: var(--muted); font-size: 0.85rem; }

/* ---------- Top bar ---------- */
.topbar { background: var(--navy); color: #fff; }
.topbar-inner {
  max-width: var(--page-max); margin: 0 auto; padding: 0.6rem 1.25rem;
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
}
.brand { display: flex; align-items: center; gap: 0.6rem; color: #fff; }
.brand:hover { text-decoration: none; }
.brand-mark {
  background: linear-gradient(135deg, #29abe2, var(--blue-dark)); color: #fff; font-weight: 800; letter-spacing: 0.5px;
  padding: 0.35rem 0.55rem; border-radius: 8px; font-size: 1rem;
}
.brand-tag { color: var(--orange); }
.brand-icon {
  height: 34px; width: 34px; object-fit: contain;
  background: #fff; border-radius: 8px; padding: 2px;
  box-shadow: 0 1px 4px rgba(0,0,0,0.25);
}
.pw-wrap { position: relative; display: block; }
.pw-wrap input { padding-right: 4.5rem; }
.pw-toggle {
  position: absolute; right: 5px; top: 50%; transform: translateY(-50%);
  background: none; border: none; cursor: pointer;
  color: var(--blue-dark); font-weight: 600; font-size: 0.85rem; font-family: inherit;
  padding: 0.35rem 0.6rem;
}
.pw-toggle:hover { text-decoration: underline; }
.login-logo { max-width: 210px; height: auto; display: block; margin: 0 auto; }
.brand-mark-lg { font-size: 1.4rem; padding: 0.5rem 0.8rem; display: inline-block; }
.brand-text { display: flex; flex-direction: column; line-height: 1.15; }
.brand-name { font-weight: 700; font-size: 1.05rem; }
.brand-tag { font-size: 0.68rem; opacity: 0.75; }
.mainnav { display: flex; gap: 0.15rem; flex-wrap: wrap; flex: 1; }
.mainnav a {
  color: rgba(255,255,255,0.85); padding: 0.45rem 0.7rem; border-radius: 8px; font-size: 0.95rem;
}
.mainnav a:hover { background: var(--navy-2); text-decoration: none; color: #fff; }
.mainnav a.active { background: var(--blue); color: #fff; font-weight: 600; }
.logout-form { display: flex; align-items: center; gap: 0.6rem; margin-left: auto; }
.user-chip { font-size: 0.85rem; opacity: 0.85; }

/* ---------- Layout ---------- */
/* The page was pinned at 1200px, which on an ordinary office screen left a
   strip of empty grey down each side and squeezed seven days of calendar into
   the middle. There is no reason for the limit beyond the number itself, so it
   now follows the window and only stops where a screen gets genuinely wide.
   Data-entry forms keep their own sensible width below — a text box 1600px wide
   is not easier to fill in, just longer. */
.page { max-width: var(--page-max); margin: 0 auto; padding: 1.25rem 1.25rem 3rem; }
.page-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-bottom: 1.1rem;
}
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; align-items: start; }
.grid-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 1rem; }
@media (max-width: 820px) { .grid-2 { grid-template-columns: 1fr; } }

.card {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.1rem 1.2rem; margin-bottom: 1rem; box-shadow: var(--shadow);
}
.card.narrow { max-width: 640px; }
.card.wide { max-width: 900px; }
.card-link { display: block; color: inherit; transition: transform 0.08s ease, box-shadow 0.08s ease; }
.card-link:hover { text-decoration: none; transform: translateY(-2px); box-shadow: 0 6px 20px rgba(11,42,74,0.12); }
.card-good { border-left: 4px solid var(--ok); }
.card-highlight { border-left: 4px solid var(--blue); }
.center-page { margin: 3rem auto; text-align: center; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-block; border: 1px solid transparent; border-radius: 8px; cursor: pointer;
  padding: 0.55rem 1rem; font-size: 0.95rem; font-weight: 600; font-family: inherit;
  text-align: center; transition: background 0.1s ease;
}
.btn:hover { text-decoration: none; }
.btn-primary { background: var(--blue); color: #fff; }
.btn-primary:hover { background: var(--blue-dark); }
.btn-outline { background: #fff; color: var(--blue-dark); border-color: var(--blue); }
.btn-outline:hover { background: var(--sky); }
.btn-ghost { background: transparent; color: inherit; border-color: rgba(255,255,255,0.4); }
.page .btn-ghost { color: var(--muted); border-color: var(--line); }
/* Outlined, not solid: destructive actions shouldn't look like the primary one. */
.btn-danger { background: #fff; color: #a11; border-color: #d88; }
.btn-danger:hover { background: #fdeaea; border-color: #a11; }
.btn-sm { padding: 0.3rem 0.65rem; font-size: 0.85rem; }
.btn-block { width: 100%; }
.btn-row { display: flex; gap: 0.4rem; flex-wrap: wrap; align-items: center; }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }

/* ---------- Forms ---------- */
.stack { display: flex; flex-direction: column; gap: 0.85rem; max-width: 920px; }
.stack label { display: flex; flex-direction: column; gap: 0.25rem; font-weight: 600; font-size: 0.92rem; color: var(--navy); }
.stack label .muted-sm { font-weight: 400; }
input[type="text"], input[type="email"], input[type="tel"], input[type="password"],
input[type="date"], input[type="number"], input[type="search"], select, textarea {
  font-family: inherit; font-size: 1rem; padding: 0.55rem 0.7rem;
  border: 1px solid var(--line); border-radius: 8px; background: #fff; color: var(--ink);
  width: 100%;
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--blue); outline-offset: 1px; border-color: var(--blue); }
input[disabled] { background: var(--bg); color: var(--muted); }
textarea { resize: vertical; }
fieldset.checks { border: 1px solid var(--line); border-radius: 8px; padding: 0.6rem 0.8rem; margin: 0; }
fieldset.checks legend { font-weight: 600; font-size: 0.9rem; color: var(--navy); padding: 0 0.3rem; }
label.check { display: flex; flex-direction: row; align-items: center; gap: 0.5rem; font-weight: 400; padding: 0.2rem 0; }
label.check input { width: auto; }

.service-list { border: 1px solid var(--line); border-radius: 10px; overflow: hidden; background: #fff; }
.service-line { display: flex; flex-direction: row; align-items: center; justify-content: space-between; gap: 0.75rem; padding: 0.6rem 0.9rem; border-bottom: 1px solid var(--line); }
.service-line:last-child { border-bottom: none; }
.service-line:has(.service-checkbox:checked) { background: var(--bg); }
.service-check-label { flex: 1; margin: 0; padding: 0; font-weight: 500; }
input.service-price-input { width: 110px; max-width: 110px; flex: 0 0 110px; font-size: 0.9rem; padding: 0.4rem 0.55rem; text-align: right; }
input.service-custom-note { flex: 1; min-width: 120px; font-size: 0.85rem; padding: 0.4rem 0.55rem; }
.price-summary { font-size: 0.88rem; color: var(--navy); background: var(--bg); border-radius: 8px; padding: 0.5rem 0.75rem; }
.price-summary strong { font-size: 1rem; }

/* Enquiry pipeline stages. Each carries a distinct label as well as a colour —
   colour alone must never be the only signal. */
.badge-stage-new          { background: #f3e8fd; color: #7a3ec2; }
.badge-stage-site_visit   { background: var(--sky); color: var(--blue-dark); }
.badge-stage-quoting      { background: var(--warn-bg); color: var(--warn); }
.badge-stage-quote_sent   { background: #fff3cd; color: #8a6100; }
.badge-stage-accepted     { background: var(--ok-bg); color: var(--ok); }
.badge-stage-scheduled    { background: var(--sky); color: var(--blue-dark); }
.badge-stage-completed    { background: var(--ok-bg); color: var(--ok); }
.badge-stage-lost         { background: #eee; color: #777; }

/* The single "what do I do next" control on a ticket. */
.next-step-row { display: flex; gap: 0.6rem; flex-wrap: wrap; align-items: center; margin-top: 0.6rem; }
.next-step-row select, .next-step-row input[type="text"] { width: auto; min-width: 170px; }
.next-step-row form { display: flex; gap: 0.6rem; align-items: center; flex-wrap: wrap; }
.overdue-text { color: var(--danger); font-weight: 600; }

.quote-total-box { background: var(--bg); border-radius: 8px; padding: 0.75rem 0.9rem; }
.quote-total-row { display: flex; justify-content: space-between; gap: 1rem; font-size: 0.92rem; padding: 0.15rem 0; }
.quote-total-grand { border-top: 1px solid var(--line); margin-top: 0.35rem; padding-top: 0.45rem; font-size: 1.05rem; color: var(--navy); }

/* Reminder queue: overdue split into workable groups rather than one huge list */
.bucket-tabs { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 1rem; }
.bucket-tab {
  flex: 1 1 150px; min-width: 140px; background: var(--white); border: 1px solid var(--line);
  border-radius: 10px; padding: 0.6rem 0.8rem; color: inherit; text-align: left;
  display: flex; flex-direction: column; gap: 0.1rem;
}
.bucket-tab:hover { text-decoration: none; border-color: var(--blue); }
.bucket-tab.active { border-color: var(--navy); background: var(--navy); color: #fff; box-shadow: var(--shadow); }
.bucket-count { font-size: 1.5rem; font-weight: 800; line-height: 1.1; }
.bucket-label { font-size: 0.78rem; opacity: 0.85; }
.bucket-sub { font-size: 0.7rem; opacity: 0.7; }
.reminder-actions { display: flex; gap: 0.3rem; flex-wrap: wrap; align-items: center; }

.preview-modal {
  position: fixed; inset: 0; background: rgba(11,26,45,0.55); z-index: 200;
  display: flex; align-items: center; justify-content: center; padding: 1rem;
}
/* A class that sets its own display must also handle [hidden], or the native
   hidden attribute silently does nothing (author styles beat the UA rule). */
.preview-modal[hidden] { display: none; }
.preview-box {
  background: var(--white); border-radius: 12px; padding: 1.2rem; max-width: 560px; width: 100%;
  max-height: 80vh; overflow-y: auto; box-shadow: 0 10px 40px rgba(0,0,0,0.25);
}
.preview-text { white-space: pre-wrap; font-family: inherit; font-size: 0.92rem;
  background: var(--bg); padding: 0.8rem; border-radius: 8px; margin: 0.5rem 0 1rem; }

.time-range-row { display: flex; gap: 1rem; }
.time-range-row label { flex: 1; }

input.date-input-lg { font-size: 1.15rem; padding: 0.75rem 0.9rem; cursor: pointer; max-width: 260px; }

.contact-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.6rem; }
.contact-grid + .contact-grid-2nd { margin-top: 0.45rem; }
@media (max-width: 700px) { .contact-grid { grid-template-columns: 1fr; } }

.crew-list { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.crew-chip {
  border: 1px solid var(--line); border-radius: 999px; padding: 0.4rem 0.9rem; margin: 0;
  background: #fff; cursor: pointer;
}
.crew-chip:has(input:checked) { background: var(--navy); border-color: var(--navy); color: #fff; }

.address-autocomplete-wrap { position: relative; }
.address-suggestions {
  display: none; position: absolute; top: 100%; left: 0; right: 0; z-index: 50;
  background: var(--white); border: 1px solid var(--line); border-top: none;
  border-radius: 0 0 8px 8px; box-shadow: 0 4px 10px rgba(0,0,0,0.08); max-height: 240px; overflow-y: auto;
}
.address-suggestion-item { padding: 0.5rem 0.75rem; cursor: pointer; font-size: 0.9rem; }
.address-suggestion-item:hover { background: var(--bg); }
/* Addresses we've already worked at are the answer most of the time, so they're
   grouped and tinted rather than mixed in with new ones from Google. */
.address-suggestion-head {
  padding: 0.35rem 0.75rem; font-size: 0.72rem; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--muted); background: var(--bg);
  border-bottom: 1px solid var(--line); position: sticky; top: 0;
}
.address-suggestion-known { background: #f2f9f3; }
.address-suggestion-known:hover { background: #e4f2e7; }
.known-property-info {
  margin: -0.4rem 0 0.6rem; padding: 0.5rem 0.7rem; font-size: 0.85rem;
  background: #f2f9f3; border: 1px solid #cfe6d4; border-radius: 6px; color: #245c33;
}
.known-property-info a { color: #245c33; }
.inline-form { display: inline-flex; gap: 0.35rem; align-items: center; }
.inline-form input[type="date"] { width: auto; padding: 0.3rem 0.4rem; font-size: 0.85rem; }
.filter-bar { display: flex; gap: 0.5rem; margin-bottom: 1rem; flex-wrap: wrap; align-items: center; }
.filter-bar input[type="search"] { max-width: 320px; }
.filter-bar select { width: auto; }
.filter-bar input[type="date"] { width: auto; }
.filter-inline { display: flex; align-items: center; gap: 0.4rem; font-size: 0.88rem; color: var(--muted); white-space: nowrap; }
.mt-sm { margin-top: 0.6rem; }

/* ---------- Tables ---------- */
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 0.93rem; }
th { text-align: left; color: var(--muted); font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.04em; padding: 0.5rem 0.6rem; border-bottom: 2px solid var(--line); white-space: nowrap; }
td { padding: 0.6rem; border-bottom: 1px solid var(--line); vertical-align: top; }
tr:last-child td { border-bottom: none; }
.row-muted { opacity: 0.55; }
.row-flagged { background: var(--warn-bg); }

/* ---------- Badges ---------- */
.badge {
  display: inline-block; padding: 0.15rem 0.55rem; border-radius: 999px;
  font-size: 0.78rem; font-weight: 700; white-space: nowrap;
}
.badge-ok { background: var(--ok-bg); color: var(--ok); }
.badge-warning { background: var(--warn-bg); color: var(--warn); }
.badge-danger { background: #fdE7e7; color: #b3261f; }
.badge-role { background: var(--sky); color: var(--blue-dark); }
/* Booked the work on someone else's property — distinct at a glance from an owner. */
.badge-thirdparty { background: #efe4fb; color: #6b3aa8; }
.badge-status-requested { background: #f3e8fd; color: #7a3ec2; }
.badge-status-booked { background: var(--sky); color: var(--blue-dark); }
.badge-status-in_progress { background: var(--warn-bg); color: var(--warn); }
.badge-status-complete { background: var(--ok-bg); color: var(--ok); }
.badge-status-cancelled { background: #eee; color: #777; }
.badge-enquiry-inquiry { background: #f3e8fd; color: #7a3ec2; }
.badge-enquiry-pending_reply { background: var(--warn-bg); color: var(--warn); }
.badge-enquiry-pending_decision { background: var(--sky); color: var(--blue-dark); }
.badge-enquiry-confirmed { background: var(--ok-bg); color: var(--ok); }
.badge-enquiry-rejected { background: #eee; color: #777; }

/* ---------- Flash ---------- */
.flash { border-radius: 8px; padding: 0.8rem 1rem; margin-bottom: 1rem; font-size: 0.95rem; }
.flash-success { background: var(--ok-bg); color: var(--ok); border: 1px solid #bfe5cf; }
.flash-error { background: #fde7e7; color: #b3261f; border: 1px solid #f5c6c4; }
.flash-warning { background: var(--warn-bg); color: var(--warn); border: 1px solid #f0dfae; }

/* ---------- Stats ---------- */
.stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 0.75rem; margin-bottom: 1rem; }
.stat {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 0.8rem 1rem; box-shadow: var(--shadow);
}
.stat-num { display: block; font-size: 1.7rem; font-weight: 800; color: var(--navy); line-height: 1.2; }
.stat-label { color: var(--muted); font-size: 0.82rem; }
.stat-danger .stat-num { color: #b3261f; }

/* ---------- Job lines / due lists ---------- */
.job-line {
  display: flex; align-items: center; gap: 0.75rem; padding: 0.55rem 0;
  border-bottom: 1px solid var(--line); flex-wrap: wrap;
}
.job-line:last-of-type { border-bottom: none; }
.job-line > div { flex: 1; min-width: 180px; }
.due-list { list-style: none; margin: 0; padding: 0; }
.due-list li { display: flex; align-items: center; gap: 0.6rem; padding: 0.45rem 0; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.due-list li:last-child { border-bottom: none; }
.link-list { list-style: none; margin: 0; padding: 0; }
.link-list li { padding: 0.35rem 0; border-bottom: 1px solid var(--line); }
.link-list li:last-child { border-bottom: none; }

/* ---------- Timeline ---------- */
.timeline { position: relative; }
.timeline-item { display: flex; gap: 1rem; padding: 0.9rem 0; border-bottom: 1px solid var(--line); }
.timeline-item:last-child { border-bottom: none; }
.timeline-date { flex: 0 0 105px; font-weight: 700; color: var(--blue-dark); font-size: 0.9rem; padding-top: 0.15rem; }
.timeline-body { flex: 1; min-width: 0; }
.timeline-body p { margin: 0.35rem 0; }
.photo-row { display: flex; gap: 0.6rem; flex-wrap: wrap; margin-top: 0.5rem; }
.photo { margin: 0; }
.photo img { width: 130px; height: 100px; object-fit: cover; border-radius: 8px; border: 1px solid var(--line); }
.photo figcaption { font-size: 0.75rem; color: var(--muted); text-align: center; }

/* ---------- Mini bars ---------- */
.mini-bars { list-style: none; margin: 0; padding: 0; }
.mini-bars li { display: flex; align-items: center; gap: 0.5rem; padding: 0.3rem 0; }
.mini-bar-label { flex: 0 0 45%; font-size: 0.85rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mini-bar { height: 10px; background: var(--blue); border-radius: 5px; min-width: 6px; }

/* ---------- Calendar ---------- */
.calendar-card { padding: 0.75rem; }
.calendar { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-dow { text-align: center; font-size: 0.75rem; font-weight: 700; color: var(--muted); text-transform: uppercase; padding: 0.3rem 0; }
.cal-cell { background: var(--bg); border-radius: 6px; min-height: 84px; padding: 0.3rem; font-size: 0.8rem; }
.cal-empty { background: transparent; }
.cal-today { outline: 2px solid var(--blue); background: var(--sky); }
.cal-daynum { font-weight: 700; color: var(--muted); font-size: 0.75rem; }
.cal-job {
  display: block; background: var(--white); border-left: 3px solid var(--blue);
  border-radius: 4px; padding: 0.2rem 0.35rem; margin-top: 0.25rem; color: var(--ink);
  font-size: 0.72rem; line-height: 1.3; box-shadow: 0 1px 2px rgba(0,0,0,0.08);
  overflow: hidden;
}
.cal-job:hover { text-decoration: none; background: var(--sky); }
.cal-job-in_progress { border-left-color: var(--warn); }
.cal-job-complete { border-left-color: var(--ok); opacity: 0.7; }
.cal-job-requested { border-left-color: #7a3ec2; }

/* ---------- Week view ---------- */
/* Narrow screens scroll the week sideways rather than shrinking seven days into
   slivers — a 40px-wide Wednesday is not a calendar. */
.week-card { background: var(--white); border: 1px solid var(--line); border-radius: 12px; overflow-x: auto; margin-bottom: 1rem; }
.week-header-row, .week-allday-row, .week-grid-body { min-width: 780px; }
.week-header-row, .week-allday-row { display: flex; }
.week-gutter-spacer { flex: 0 0 52px; }
.week-day-header {
  flex: 1; text-align: center; padding: 0.5rem 0.25rem; border-left: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.week-day-name { font-size: 0.7rem; color: var(--muted); text-transform: uppercase; font-weight: 700; }
.week-day-num { font-size: 0.95rem; font-weight: 700; color: var(--navy); display: inline-block; width: 26px; height: 26px; line-height: 26px; border-radius: 50%; margin-top: 2px; }
.week-day-header.today .week-day-num { background: var(--blue); color: #fff; }
.week-allday-row { border-bottom: 2px solid var(--navy); min-height: 30px; background: var(--bg); padding: 3px 0; }
.week-gutter-label { flex: 0 0 52px; font-size: 0.62rem; color: var(--muted); text-transform: uppercase; text-align: right; padding-right: 6px; font-weight: 700; align-self: center; }
.week-allday-cell { flex: 1; border-left: 1px solid var(--line); padding: 2px 4px; display: flex; flex-direction: column; gap: 2px; }
.week-allday-chip {
  display: block; background: var(--sky); border-left: 3px solid var(--blue); border-radius: 3px;
  padding: 2px 6px; font-size: 0.75rem; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.week-allday-chip:hover { text-decoration: none; background: #d8ecfa; }
.week-grid-body { display: flex; position: relative; }
.week-time-gutter { flex: 0 0 52px; }
.week-hour-label { height: var(--hour-px, 60px); font-size: 0.74rem; color: var(--muted); text-align: right; padding-right: 6px; position: relative; }
.week-hour-label span { position: relative; top: -0.6em; }
.week-days { display: flex; flex: 1; position: relative; }
.week-day-col {
  flex: 1; position: relative; border-left: 1px solid var(--line);
  background-image: repeating-linear-gradient(to bottom, var(--line) 0, var(--line) 1px, transparent 1px, transparent var(--hour-px, 60px));
}
/* Room to read. A block has to say WHOSE job it is without being opened, so the
   text is the size of ordinary small print rather than the smallest the browser
   will draw, and the words wrap instead of being cut off mid-name. */
.week-job-block {
  position: absolute; border-radius: 5px; border-left: 4px solid var(--blue); background: var(--sky);
  font-size: 0.78rem; line-height: 1.3; padding: 3px 6px; overflow: hidden; cursor: grab;
  box-shadow: 0 1px 3px rgba(0,0,0,0.15); touch-action: none; user-select: none;
  display: flex; flex-direction: column; gap: 1px;
}
.week-job-block .sched-title { overflow: hidden; }
.week-job-where { font-size: 0.72rem; color: #5b6b76; overflow: hidden; }
.week-job-complete .week-job-where { color: #8a9aa6; }
.week-job-block:hover { background: #d8ecfa; }
.week-job-block.dragging { opacity: 0.75; z-index: 50; box-shadow: 0 4px 10px rgba(0,0,0,0.3); cursor: grabbing; }
.week-job-in_progress { border-left-color: var(--warn); background: var(--warn-bg); }
.week-job-requested { border-left-color: #7a3ec2; background: #f3e8fd; }
/* A finished job stays on the calendar — the day still happened — but it has to be
   obvious at a glance which of a past day's jobs are still waiting to be closed off.
   Without this a completed job looked exactly like an unfinished one, and three of
   Monday's jobs sat unfinished for two days because the calendar gave no sign. */
.week-job-complete { background: #eef1f3; border-left-color: #8a9aa6; }
.week-job-complete .sched-title, .week-job-complete .week-job-time { color: #6b7a86; }
.week-job-complete .week-job-time::before { content: '✓ '; color: #2e8b57; font-weight: 700; }
.week-allday-chip.week-job-complete { background: #eef1f3; color: #6b7a86; }
.week-job-time { font-weight: 700; }
.week-resize-handle { position: absolute; left: 0; right: 0; bottom: 0; height: 7px; cursor: ns-resize; }
.week-current-time { position: absolute; left: 0; right: 0; height: 2px; background: #e53935; z-index: 40; display: none; pointer-events: none; }
.week-current-time::before { content: ''; position: absolute; left: -4px; top: -3px; width: 8px; height: 8px; border-radius: 50%; background: #e53935; }

/* ---------- Login ---------- */
.login-body { background: linear-gradient(160deg, var(--navy) 0%, var(--navy-2) 55%, var(--blue-dark) 100%); min-height: 100vh; margin: 0; }
.login-wrap { min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 1.5rem 1rem; }
.login-card {
  background: var(--white); border-radius: 14px; box-shadow: 0 12px 40px rgba(0,0,0,0.3);
  padding: 2rem 1.8rem; width: 100%; max-width: 400px;
}
.login-brand { text-align: center; margin-bottom: 1.25rem; }
.login-brand h1 { margin-top: 0.9rem; font-size: 1.35rem; }
.login-help { font-size: 0.85rem; text-align: center; margin-top: 1.25rem; }
.login-footer { color: rgba(255,255,255,0.75); font-size: 0.85rem; margin-top: 1.25rem; text-align: center; }
.login-footer a { color: #fff; }

/* ---------- Staff clock ---------- */
.staff-card { max-width: 420px; }
.staff-name-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.staff-name-btn { padding: 1.1rem 0.5rem; font-size: 1.05rem; text-align: center; }
.staff-pin-input {
  font-size: 2rem; letter-spacing: 0.6em; text-align: center; font-weight: 700;
  padding: 0.6rem 0 0.6rem 0.6em;
}
.staff-result-icon { font-size: 2.6rem; display: block; margin-bottom: 0.4rem; }
.staff-hours-summary {
  display: flex; justify-content: space-around; text-align: center; margin: 1.25rem 0;
  padding: 1rem 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.staff-hours-summary .stat-num { display: block; font-size: 1.6rem; font-weight: 800; color: var(--navy); }
.staff-hours-summary .stat-label { color: var(--muted); font-size: 0.8rem; }

/* ---------- Footer ---------- */
.footer { text-align: center; color: var(--muted); font-size: 0.85rem; padding: 1.5rem 1rem 2.5rem; }
.footer p { margin: 0.2rem 0; }
.footer-small { font-size: 0.75rem; }

/* ---------- Mobile ---------- */
@media (max-width: 640px) {
  .topbar-inner { padding: 0.5rem 0.75rem; }
  .brand-tag { display: none; }
  .mainnav { order: 3; flex: 0 0 100%; width: 100%; flex-wrap: nowrap; overflow-x: auto; padding-bottom: 0.2rem; }
  .mainnav a { white-space: nowrap; font-size: 0.88rem; padding: 0.4rem 0.55rem; }
  .user-chip { display: none; }
  .page { padding: 1rem 0.75rem 2.5rem; }
  .timeline-item { flex-direction: column; gap: 0.15rem; }
  .timeline-date { flex: none; }
  .cal-cell { min-height: 60px; }
}

/* ---------- Dashboard: KPI strip, two-column body ---------- */
.kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  margin-bottom: 18px;
}
.kpi {
  background: #fff;
  border: 1px solid var(--line, #dbe3ea);
  border-left: 4px solid var(--brand, #29abe2);
  border-radius: 12px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-height: 88px;
  justify-content: center;
}
.kpi-label { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: #5d6f7d; font-weight: 700; }
.kpi-value { font-size: 26px; font-weight: 800; line-height: 1.1; color: #12212e; }
.kpi-value small { font-size: 12px; font-weight: 600; color: #5d6f7d; margin-left: 2px; }
.kpi-sub { font-size: 12px; color: #5d6f7d; }
.kpi-good { border-left-color: #12794a; }
.kpi-good .kpi-value { color: #12794a; }
.kpi-bad { border-left-color: #b3261e; }
.kpi-bad .kpi-value { color: #b3261e; }
.kpi-warn { color: #b3261e; font-weight: 600; }
.kpi-open { font-size: 12px; color: var(--blue-dark); white-space: nowrap; }
.inv-head { margin: 0.9rem 0 0.2rem; font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.03em; color: var(--muted); }
.inv-subtotal { display: flex; justify-content: space-between; align-items: baseline;
  padding: 0.35rem 0 0.1rem; font-size: 0.88rem; border-top: 1px solid var(--line); margin-top: 0.3rem; }
.inv-total { display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; }
.inv-total strong { font-size: 1.1rem; color: var(--navy); }
.inv-total .muted-sm { flex-basis: 100%; }
.kpi-loading { border-left-color: #c7d3dc; color: #5d6f7d; }
/* Not-yet-connected sources are visibly inert rather than showing a fake zero. */
.kpi-off-card { border-left-color: #c7d3dc; background: #fafbfc; }
.kpi-off { color: #9db4c4; }

/* Schedule sits in a narrow right-hand column so it can't dominate the page. */
/* The right-hand rail is a list of short lines — invoice numbers, addresses. On a
   wide screen a proportional column stretched them across half a metre of glass,
   so it is held to a readable width and the extra room goes to the work. */
.dash-grid { display: grid; grid-template-columns: minmax(0, 1.9fr) minmax(300px, 440px); gap: 16px; align-items: start; }
.dash-main, .dash-side { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
@media (max-width: 900px) { .dash-grid { grid-template-columns: 1fr; } }

.card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.card-head h2 { margin: 0; font-size: 16px; }
.card-attention { border-left: 4px solid #d98200; }
.card-quiet { background: #fafbfc; }

/* Action rows: tag, detail, button — the three things needed to decide. */
.att-row { display: grid; grid-template-columns: 92px 1fr auto; gap: 10px; align-items: center; padding: 10px 0; border-bottom: 1px solid #f0f4f7; }
.att-tag { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; padding: 3px 7px; border-radius: 6px; text-align: center; }
.att-new { background: #e8f4fc; color: #0b7cc1; }
.att-stale { background: #fff6e5; color: #8a5a00; }
/* A visit that's booked is calm — it's in the diary. One whose date has passed with
   nothing recorded is the loudest thing on the page: someone has to ask why. */
.att-booked { background: #eaf6ee; color: #256b38; }
.att-overdue { background: #fdeaea; color: #a11; }
.att-act { display: flex; gap: 6px; align-items: center; }
.att-foot { padding-top: 10px; font-size: 13px; color: #5d6f7d; }

.mini-row { display: flex; justify-content: space-between; gap: 8px; align-items: flex-start; padding: 7px 0; border-bottom: 1px solid #f0f4f7; font-size: 14px; }
.mini-price { font-weight: 700; white-space: nowrap; }
.sched-day { font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: #5d6f7d; margin: 14px 0 4px; display: flex; justify-content: space-between; gap: 8px; }
.sched-day:first-child { margin-top: 0; }

.connect-box { background: #fafbfc; border: 1px dashed var(--line, #dbe3ea); border-radius: 10px; padding: 14px 16px; }
.connect-box p { margin: 0 0 6px; }
.connect-box p:last-child { margin-bottom: 0; }

@media (max-width: 640px) {
  .att-row { grid-template-columns: 1fr; }
  .att-act { justify-content: flex-start; }
  .kpi-value { font-size: 22px; }
}
.setup-steps { margin: 8px 0 8px 18px; padding: 0; font-size: 14px; }
.setup-steps li { margin-bottom: 8px; }
.code-line { margin: 4px 0; }
.code-line code { display: inline-block; background: #eef3f7; border: 1px solid var(--line, #dbe3ea); border-radius: 6px; padding: 4px 8px; font-size: 13px; word-break: break-all; }


/* Secondary totals under the money cards: same grid as .stat-row, dialled down
   so counts do not compete with the dollar figures above them. */
.stat-row-compact .stat { background: #fafbfc; }
.stat-row-compact .stat-num { font-size: 1.35rem; }
.cam-block { border: 1px dashed var(--line, #dbe3ea); border-radius: 10px; padding: 14px 16px; margin: 14px 0; background: #fafbfc; }
.cam-block .label-text { font-weight: 700; margin-bottom: 4px; }
.cam-block p { margin: 0 0 10px; }

/* ---------- Combined work list: stage filter + stage badges ---------- */
.stage-bar { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.stage-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; border: 1px solid var(--line, #dbe3ea); border-radius: 999px;
  background: #fff; font-size: 13px; font-weight: 600; color: #5d6f7d; text-decoration: none;
}
.stage-chip:hover { border-color: #9db4c4; }
.stage-chip.active { background: #12212e; border-color: #12212e; color: #fff; }
.stage-count { font-size: 12px; opacity: .75; }
.stage-chip.active .stage-count { opacity: .9; }

/* Stage badges follow the pipeline: grey while it's talk, blue once it's real
   work, green when done, red when lost. */
.badge-stage-new          { background: #eef3f7; color: #40566a; }
.badge-stage-site_visit   { background: #ede7fb; color: #5b3fc4; }
.badge-stage-quoting      { background: #fff6e5; color: #8a5a00; }
.badge-stage-quote_sent   { background: #fff0d6; color: #8a5a00; }
.badge-stage-accepted     { background: #e0f2fb; color: #0b6fa8; }
.badge-stage-scheduled    { background: #e8f4fc; color: #0b7cc1; }
.badge-stage-completed    { background: #e6f5ee; color: #12794a; }
.badge-stage-lost         { background: #fdecea; color: #b3261e; }

/* Property-picking list: many rows, scanned quickly, ticked in bulk. */
.pick-list { max-height: 360px; overflow-y: auto; border: 1px solid var(--line, #dbe3ea); border-radius: 10px; margin-bottom: 12px; }
.pick-row { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-bottom: 1px solid #f0f4f7; cursor: pointer; }
.pick-row:last-child { border-bottom: none; }
.pick-row:hover { background: #f7fafc; }
.pick-row input { width: 17px; height: 17px; flex: none; }
.stack-form { display: flex; flex-direction: column; gap: 12px; max-width: 480px; }
.req { color: #b3261e; }

/* Tiles are links now — keep the card look, but make it clear they're clickable. */
a.stat { text-decoration: none; color: inherit; display: flex; flex-direction: column; gap: 2px; transition: border-color .12s, transform .12s; }
a.stat:hover { border-color: var(--brand, #29abe2); transform: translateY(-1px); }
a.stat:hover .stat-label { color: var(--brand, #29abe2); }
.warn-banner { background: #fff6e5; border: 1px solid #f3dcae; color: #8a5a00; border-radius: 10px; padding: 12px 14px; margin-bottom: 14px; font-size: 14px; }

/* Source tag on a KPI card — quiet, but always there, so nobody has to remember
   which numbers come from Xero and which from the calendar. */
.kpi-src {
  display: inline-block; font-size: 9px; font-weight: 700; letter-spacing: .03em;
  text-transform: none; padding: 1px 6px; border-radius: 999px;
  background: #eef3f7; color: #5d6f7d; vertical-align: middle; margin-left: 2px;
}
.kpi-good .kpi-src { background: #e6f5ee; color: #12794a; }
.kpi-bad .kpi-src { background: #fdecea; color: #b3261e; }

/* ---------- Coming up: each day its own panel ----------
   Stacked rather than side by side (three narrow columns wrapped the job names),
   but each day is a self-contained card with its own tinted header so the eye
   separates them instantly instead of reading one long list. */
.day-cols { display: flex; flex-direction: column; gap: 12px; }
.day-col {
  min-width: 0;
  border: 1px solid var(--line, #dbe3ea);
  border-radius: 12px;
  overflow: hidden;
  background: #fff;
}
.day-head {
  display: flex; align-items: baseline; gap: 10px;
  padding: 9px 14px;
  background: #f4f7f9;
  border-bottom: 1px solid var(--line, #dbe3ea);
}
.day-name { font-size: 13px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; color: #12212e; }
.day-date { font-size: 12px; color: #5d6f7d; }
.day-total { font-size: 12px; font-weight: 700; color: #40566a; margin-left: auto; white-space: nowrap; }
.day-col .mini-row { padding: 9px 14px; }
.day-col .mini-row:last-child { border-bottom: none; }
.day-empty { font-size: 13px; padding: 12px 14px; margin: 0; }

/* Today is the one that matters before 8am, so it gets real colour. The other two
   are deliberately quiet — they're context, not today's work. */
.day-col:nth-child(1) { border-color: #9fd4f0; box-shadow: 0 1px 3px rgba(11,124,193,.10); }
.day-col:nth-child(1) .day-head { background: #e8f4fc; border-bottom-color: #9fd4f0; }
.day-col:nth-child(1) .day-name,
.day-col:nth-child(1) .day-total { color: #0b7cc1; }

.day-col:nth-child(2) .day-head { background: #f4f7f9; }
.day-col:nth-child(3) { background: #fcfdfe; }
.day-col:nth-child(3) .day-head { background: #fafbfc; }
.day-col:nth-child(3) .day-name { color: #5d6f7d; }

/* ---------- Next-due interval chips on the completion form ---------- */
.due-block { margin-top: 14px; }
.due-block .label-text { font-weight: 700; margin-bottom: 2px; }
.due-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0; }
.due-chip input { position: absolute; opacity: 0; pointer-events: none; }
.due-chip span {
  display: inline-block; padding: 9px 16px; border: 2px solid var(--line, #dbe3ea);
  border-radius: 999px; font-weight: 700; font-size: 14px; background: #fff;
  cursor: pointer; color: #40566a;
}
.due-chip span:hover { border-color: #9db4c4; }
.due-chip input:checked + span { border-color: var(--brand, #0b7cc1); background: #e8f4fc; color: #0b7cc1; }
/* "None" reads as a deliberate choice, not a mistake — but still stands apart. */
.due-chip.due-none input:checked + span { border-color: #8a5a00; background: #fff6e5; color: #8a5a00; }
.due-exact { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; }
.due-exact input[type=date] { max-width: 200px; }
.due-note { color: #8a5a00; font-weight: 600; }
/* When None is chosen the exact date is meaningless, so it fades out of the way. */
.due-block.is-none .due-exact label { opacity: .45; }
.ok-text { color: #12794a; font-weight: 600; }
.warn-text { color: #8a5a00; font-weight: 600; }

/* Xero comparison: colour the row by how confident the suggestion is. */
.badge-verdict-xero_better { background: #e6f5ee; color: #12794a; }
.badge-verdict-keep_mypwb  { background: #eef3f7; color: #40566a; }
.badge-verdict-review      { background: #fff6e5; color: #8a5a00; }
tr.verdict-review td { background: #fffdf7; }
