/* Sunday Stays admin - brand palette pulled from the invoice PDF / logo:
   deep navy + warm gold + soft cream, serif display type (Playfair
   Display) for headings and the wordmark, Jost for everything else. */
:root {
  --bg: #f9f5eb;
  --panel: #fffdf9;
  --ink: #23343f;
  --muted: #6c7a83;
  --border: #e6dfcd;
  --brand: #294556;
  --brand-dark: #1b2f3b;
  --brand-ink: #fffdf9;
  --gold: #9e7838;
  --gold-light: #f2e9d5;
  --danger: #b3413a;
  --warn: #9e7838;
  --ok: #55735a;
  --pc-0: #294556;
  --pc-1: #9e7838;
  --pc-2: #55735a;
  --pc-3: #7a5c74;
  --pc-4: #b3413a;
  --pc-5: #3a6f9c;
  --radius: 12px;
  --shadow: 0 1px 2px rgba(35, 52, 63, 0.05), 0 4px 14px rgba(35, 52, 63, 0.06);
  --serif: "Playfair Display", Georgia, "Times New Roman", serif;
  --sans: "Jost", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--sans);
  background: var(--bg);
  color: var(--ink);
  line-height: 1.5;
}

h1, h2, h3 { font-family: var(--serif); font-weight: 600; line-height: 1.25; margin: 0 0 0.45em; color: var(--brand-dark); }
h1 { font-size: 1.75rem; }
h2 { font-size: 1.25rem; }
a { color: var(--brand); }
a:hover { color: var(--gold); }
.muted { color: var(--muted); }
code { background: var(--gold-light); padding: 1px 5px; border-radius: 4px; font-size: 0.85em; }
.share-link { margin-right: 8px; word-break: break-all; }

/* Wordmark - palm icon + serif "Sunday Stays", reused in the admin topbar,
   the login page and the cleaner-facing link header. */
.wordmark { display: inline-flex; align-items: center; gap: 0.5rem; font-family: var(--serif); font-weight: 600; font-size: 1.2rem; letter-spacing: 0.01em; color: var(--brand-dark); }
.wordmark-text { white-space: nowrap; }
.palm-icon { width: 22px; height: 22px; color: var(--gold); flex-shrink: 0; }

.topbar {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  padding: 0.85rem 1.75rem;
  background: var(--panel);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 1px 0 rgba(158, 120, 56, 0.15);
  flex-wrap: wrap;
}
.topbar-bare { justify-content: center; }
.brand { display: flex; align-items: center; gap: 0.6rem; }
.badge { font-family: var(--sans); font-size: 0.62rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.09em; color: var(--gold); border: 1px solid var(--gold); border-radius: 999px; padding: 2px 9px; }
.topbar nav { display: flex; gap: 0.15rem; flex-wrap: wrap; flex: 1; }
.navlink { padding: 0.42rem 0.75rem; border-radius: 999px; color: var(--ink); text-decoration: none; font-size: 0.88rem; font-weight: 500; transition: background 0.12s ease, color 0.12s ease; }
.navlink:hover { background: var(--gold-light); color: var(--brand-dark); }
.navlink.active { background: var(--brand); color: var(--brand-ink); }
.logout-form { margin-left: auto; }
/* Hidden on desktop - only shown at phone widths (see the media query
   below), where the full 11-link nav is too much to show expanded by
   default. */
.nav-toggle { display: none; }

.container { max-width: 960px; margin: 0 auto; padding: 1.75rem 1.5rem; }
.container-wide { max-width: 1360px; }

.page-head { display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.1rem; }

.panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.4rem;
  margin-bottom: 1.4rem;
}
/* A cleaner's job card that still needs their confirmation - same warm-red
   used elsewhere for "needs attention" (the admin schedule's overdue rows,
   pill-error) so it reads consistently as "this one needs you" rather than
   introducing a new colour meaning. */
.panel-alert { border-color: #e0aea5; background: #fbf1ef; }

/* The one job a #job-<id> link (Text/WhatsApp notify, or a push
   notification) pointed at - a clear outline so "which one is this" is
   obvious the moment the page lands, separate from panel-alert's meaning
   of "needs your confirmation" since a highlighted job might already be
   confirmed. */
.job-highlight { outline: 3px solid #294556; outline-offset: 2px; }

.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 1rem; }
.card {
  display: block;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.1rem;
  text-decoration: none;
  color: var(--ink);
  transition: border-color 0.12s ease, transform 0.12s ease;
}
.card:hover { border-color: var(--gold); transform: translateY(-1px); }

.btn, button, .link-btn {
  font: inherit;
  cursor: pointer;
}
.btn {
  display: inline-block;
  background: var(--brand);
  color: var(--brand-ink);
  border: 1px solid var(--brand);
  border-radius: 999px;
  padding: 0.55rem 1.15rem;
  text-decoration: none;
  font-weight: 600;
  font-size: 0.88rem;
  letter-spacing: 0.01em;
  transition: background 0.12s ease, box-shadow 0.12s ease;
}
.btn:hover { background: var(--brand-dark); }
.btn-secondary { background: transparent; color: var(--brand); border: 1px solid var(--brand); }
.btn-secondary:hover { background: var(--gold-light); color: var(--brand-dark); }
.btn-danger { background: var(--danger); border-color: var(--danger); }
.btn-danger:hover { background: #93332d; }
.btn-small { padding: 0.35rem 0.8rem; font-size: 0.8rem; }
.btn-row { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.btn-secondary.btn-active { background: var(--brand); color: var(--brand-ink); }

.link-btn {
  background: none;
  border: none;
  color: var(--brand);
  text-decoration: underline;
  text-underline-offset: 2px;
  padding: 0;
  font-size: 0.9rem;
}
.link-btn:hover { color: var(--gold); }

.form { display: flex; flex-direction: column; gap: 0.85rem; max-width: 560px; }
.form label { display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.85rem; font-weight: 600; color: var(--brand-dark); }
.form input, .form select, .form textarea {
  font: inherit;
  padding: 0.55rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #fff;
  font-weight: 400;
  color: var(--ink);
}
.form input:focus, .form select:focus, .form textarea:focus,
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px var(--gold-light);
}
.form-inline { flex-direction: row; align-items: flex-end; flex-wrap: wrap; max-width: none; }
.form-inline label { flex: 0 0 auto; }
.form-inline .grow { flex: 1 1 240px; }
.checkbox-row { flex-direction: row !important; align-items: center; gap: 0.5rem !important; font-weight: 400 !important; }
.checkbox-row input { width: auto; }
.inline { display: inline; }
.photo-form { display: inline-block; }
.photo-label { cursor: pointer; }

/* Cleaning schedule "Notify" column - Text/WhatsApp deep links stacked over
   the manual notified toggle, kept compact since it lives in a table cell. */
.notify-cell { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; }
.notify-links { display: flex; gap: 8px; }

.table { width: 100%; border-collapse: collapse; margin: 1rem 0; }
.table th, .table td { text-align: left; padding: 0.6rem 0.65rem; border-bottom: 1px solid var(--border); font-size: 0.9rem; }
.table th { color: var(--muted); font-weight: 600; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.07em; }
.table tr.row-past { opacity: 0.5; }
.table tr.row-cancelled td { text-decoration: line-through; opacity: 0.55; }
.table tr.row-alert td { background: #f4e2df; }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 0.85rem; max-width: 720px; align-items: end; }
.form-grid button { grid-column: 1 / -1; justify-self: start; }
.form-grid .rpt-subhead, .form-grid > p { grid-column: 1 / -1; }
.form-computed { grid-column: 1 / -1; font-size: 0.9rem; padding: 0.4rem 0; }
.form-computed-total { font-size: 1.05rem; padding-top: 0.6rem; border-top: 1px solid var(--border); margin-top: 0.2rem; }
.rpt-subhead { margin: 1.5rem 0 0.25rem; font-size: 1rem; font-family: var(--serif); }
.truncate { max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.pill { display: inline-block; font-size: 0.72rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; padding: 3px 10px; border-radius: 999px; background: var(--gold-light); color: var(--brand-dark); }
.pill-muted { background: #eee9de; color: var(--muted); }
.pill-error { background: #f4e2df; color: var(--danger); }
.pill-pending { background: var(--gold-light); color: var(--warn); }
.pill-in_progress { background: #e2ebf1; color: var(--pc-5); }
.pill-done { background: #e6ede4; color: var(--ok); }
.pill-cancelled { background: #f4e2df; color: var(--danger); }
.pill-not_needed { background: #eee9de; color: var(--muted); }
.table tr.row-muted td { opacity: 0.55; }

/* Cleaning schedule: topline row + its collapsible "Details" row. */
.table tr.job-row td { vertical-align: middle; }
.table tr.job-detail-row td { border-top: none; padding: 0; }
.job-detail { background: #faf8f2; padding: 14px 18px; border-radius: 8px; margin: 4px 0 10px; }
.job-detail-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; padding-bottom: 10px; border-bottom: 1px solid var(--border); }
.job-detail-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 16px; }
.job-detail-grid > div > .muted.small { margin-bottom: 4px; }

.list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.4rem; }
.list li { padding: 0.4rem 0; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }

.checklist { list-style: none; padding: 0; margin: 0; }
.checklist li { display: flex; align-items: center; gap: 0.6rem; padding: 0.6rem 0; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
.checklist li.done .item-label { text-decoration: line-through; color: var(--muted); }
.check-btn { background: none; border: none; font-size: 1.3rem; line-height: 1; padding: 0; color: var(--brand); }
.item-label { flex: 1 1 auto; }
.thumb img { height: 42px; width: 42px; object-fit: cover; border-radius: 6px; border: 1px solid var(--border); }

.flash { padding: 0.75rem 1.05rem; border-radius: 9px; margin-bottom: 1.1rem; font-size: 0.9rem; border: 1px solid transparent; }
.push-banner-row { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; flex-wrap: wrap; }
.flash-info { background: #e6edf1; color: var(--brand-dark); border-color: #d3e0e7; }
.flash-success { background: #e6ede4; color: var(--ok); border-color: #d4e3d1; }
.flash-error { background: #f4e2df; color: var(--danger); border-color: #ecccc6; }

.empty-cta { text-align: center; padding: 2.25rem; background: var(--panel); border: 1px dashed var(--gold); border-radius: var(--radius); margin-bottom: 1.4rem; }

/* Calendar */
.cal-head { display: flex; align-items: center; justify-content: center; gap: 1rem; margin-bottom: 0.75rem; }
.cal-head h2 { margin: 0; }
.cal-multi { display: flex; gap: 1.75rem; align-items: flex-start; }
.cal-month { flex: 1 1 0; min-width: 0; }
.cal-month-label { font-family: var(--serif); font-size: 1.05rem; margin: 0 0 0.5rem; text-align: center; }
.legend { display: flex; gap: 0.9rem; flex-wrap: wrap; margin-bottom: 0.75rem; font-size: 0.8rem; }
.legend-item { display: flex; align-items: center; gap: 0.35rem; }
.dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }
.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 3px; min-width: 0; }
.cal-dow { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); text-align: center; padding-bottom: 4px; overflow: hidden; }
.cal-cell { min-height: 72px; min-width: 0; overflow: hidden; background: var(--panel); border: 1px solid var(--border); border-radius: 7px; padding: 4px; font-size: 0.72rem; }
.cal-cell.out-month { opacity: 0.35; }
.cal-cell.today { border-color: var(--gold); border-width: 2px; }
.cal-daynum { font-weight: 700; margin-bottom: 2px; }
.cal-bar { display: block; color: #fff; border-radius: 4px; padding: 1px 4px; margin-bottom: 2px; text-decoration: none; font-size: 0.68rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.small { font-size: 0.8rem; }

/* Property-row timeline (alternate view of the dashboard calendar) */
.gantt { min-width: 0; }
.gantt-header { display: flex; align-items: flex-end; margin-bottom: 4px; }
.gantt-header .gantt-label { flex: 0 0 150px; }
.gantt-header .gantt-track { flex: 1 1 auto; }
.gantt-daynum { text-align: center; font-size: 0.62rem; font-weight: 700; color: var(--muted); }
.gantt-row { display: flex; align-items: stretch; margin-bottom: 6px; }
.gantt-label {
  flex: 0 0 150px; display: flex; align-items: center; gap: 6px; padding-right: 8px;
  font-size: 0.78rem; font-weight: 600; color: var(--ink); text-decoration: none; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.gantt-label:hover { color: var(--brand); }
.gantt-label .dot { flex-shrink: 0; }
.gantt-track { flex: 1 1 auto; display: grid; position: relative; min-width: 0; background: var(--panel); border: 1px solid var(--border); border-radius: 7px; min-height: 34px; }
.gantt-cell { grid-row: 1; min-height: 34px; border-right: 1px solid var(--border); }
.gantt-cell:last-child { border-right: none; }
.gantt-cell.today { background: var(--gold-light); }
.gantt-bar {
  grid-row: 1; align-self: center; z-index: 2; margin: 4px 1px; color: #fff; border-radius: 4px;
  padding: 3px 6px; text-decoration: none; font-size: 0.68rem; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; min-height: 22px; display: flex; align-items: center;
}
.gantt-blocked {
  grid-row: 1; align-self: stretch; z-index: 1; margin: 2px 0; border-radius: 4px;
  background: repeating-linear-gradient(45deg, var(--border), var(--border) 4px, transparent 4px, transparent 9px);
}

/* Financial report */
.rpt-scroll { overflow-x: auto; }
.rpt-table { width: 100%; border-collapse: collapse; font-size: 0.82rem; min-width: 1100px; }
.rpt-table th {
  background: var(--brand); color: #fff; text-align: left; padding: 0.55rem 0.65rem;
  font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.06em; position: sticky; top: 0;
}
.rpt-table td { padding: 0.5rem 0.65rem; border-bottom: 1px solid var(--border); white-space: nowrap; }
.rpt-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.rpt-table td.rpt-notes { white-space: normal; max-width: 220px; font-size: 0.78rem; color: var(--muted); }
.rpt-month-row td { background: var(--brand-dark); color: #fff; font-weight: 700; padding: 0.45rem 0.65rem; font-size: 0.78rem; font-family: var(--serif); }
.rpt-subtotal td { background: var(--gold-light); font-weight: 700; border-top: 1px solid var(--border); }
.rpt-cancelled td { text-decoration: line-through; opacity: 0.5; }
.rpt-totals td { background: var(--brand-dark); color: #fff; font-weight: 700; border-top: 2px solid var(--gold); }
.rpt-channel { font-weight: 600; }
.rpt-channel-airbnb { color: #b3413a; }
.rpt-channel-bookingcom { color: #3a6f9c; }
.rpt-channel-vrbo { color: #7a5c74; }

/* Per-property check-in/out calendar */
.pcal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 3px; }
.pcal-cell { min-height: 92px; min-width: 0; overflow: hidden; background: var(--panel); border: 1px solid var(--border); border-radius: 7px; padding: 4px; font-size: 0.72rem; }
.pcal-cell.out-month { opacity: 0.35; }
.pcal-cell.today { border-color: var(--gold); border-width: 2px; }
.pcal-avail { color: var(--ok); background: #e6ede4; border-radius: 4px; padding: 2px 4px; font-size: 0.68rem; margin-top: 2px; }
.pcal-entry { display: block; color: #fff; border-radius: 4px; padding: 2px 4px; margin-bottom: 2px; text-decoration: none; font-size: 0.68rem; line-height: 1.25; }
.pcal-in { font-weight: 700; }
.pcal-out { opacity: 0.88; }
.pcal-mid { opacity: 0.92; }
.pcal-tag, .pcal-name { display: block; font-weight: 400; opacity: 0.9; font-size: 0.6rem; }

.pc-0 { background: var(--pc-0); } .dot.pc-0 { background: var(--pc-0); }
.pc-1 { background: var(--pc-1); } .dot.pc-1 { background: var(--pc-1); }
.pc-2 { background: var(--pc-2); } .dot.pc-2 { background: var(--pc-2); }
.pc-3 { background: var(--pc-3); } .dot.pc-3 { background: var(--pc-3); }
.pc-4 { background: var(--pc-4); } .dot.pc-4 { background: var(--pc-4); }
.pc-5 { background: var(--pc-5); } .dot.pc-5 { background: var(--pc-5); }

.login-body { display: flex; align-items: center; justify-content: center; min-height: 100vh; background: linear-gradient(180deg, #f9f5eb 0%, #f2e9d5 100%); }
.login-card { background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); padding: 2.25rem 2rem; width: 320px; display: flex; flex-direction: column; align-items: center; gap: 0.9rem; text-align: center; }
.login-mark { color: var(--gold); }
.login-mark .palm-icon { width: 34px; height: 34px; }
.login-card h1 { font-size: 1.6rem; margin: 0; }
.login-sub { margin: -0.3rem 0 0.4rem; font-size: 0.85rem; }
.login-card label { display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.85rem; font-weight: 600; width: 100%; text-align: left; color: var(--brand-dark); }
.login-card input { padding: 0.55rem 0.65rem; border: 1px solid var(--border); border-radius: 8px; font: inherit; width: 100%; }
.login-card .btn { width: 100%; text-align: center; }

@media (max-width: 900px) {
  .cal-multi { flex-direction: column; }
  .cal-month:nth-child(2) { display: none; }
}

@media (max-width: 640px) {
  .container { padding: 1.1rem; }
  .table { display: block; overflow-x: auto; }
  .cal-cell { min-height: 54px; }
  .gantt-label { flex-basis: 92px; font-size: 0.7rem; }
  .gantt { overflow-x: auto; }

  /* The admin nav bar (not the bare cleaner-facing header, which only ever
     has the wordmark + a small logout link) has 11 links in it - too many
     to show expanded on a phone screen without burying the actual page
     content below a wall of nav pills. Below this width it collapses
     behind a "Menu" toggle instead (see public/app.js for the click
     handler): wordmark + toggle share the top row, and tapping the toggle
     drops the full nav open on its own row underneath. The
     change-password/log-out row stays visible underneath either way,
     since it's short and you'll want it right after signing in. */
  .topbar:not(.topbar-bare) { align-items: center; }
  .topbar:not(.topbar-bare) .nav-toggle { margin-left: auto; }
  .topbar:not(.topbar-bare) nav { flex: none; flex-basis: 100%; display: none; }
  .topbar:not(.topbar-bare) nav.nav-open { display: flex; }
  .topbar:not(.topbar-bare) .logout-form { flex-basis: 100%; margin-left: 0; display: flex; justify-content: flex-end; }
  .nav-toggle {
    display: inline-flex;
    align-items: center;
    padding: 0.4rem 0.8rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--panel);
    font: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--brand-dark);
  }
}

.grid-legend { display:flex; flex-wrap:wrap; gap:10px; margin: 6px 0 10px; font-size: 0.78rem; color: var(--muted); }

/* Cleaning schedule page only - tighter vertical rhythm between the header,
   the intro paragraph, the property/cleaner filters and the grid/list
   toggle, so the table sits higher on the page without as much scrolling.
   Scoped to these page-specific classes rather than the shared
   .page-head/.form/.muted rules, which are reused across every other page
   in the app. */
.page-head-tight { margin-bottom: 0.6rem; }
.cleaning-intro { margin: 0.3rem 0 0.75rem; }
.cleaning-filters { margin: 0 0 0.5rem; }
.grid-legend .swatch { display:inline-block; width:10px; height:10px; border-radius:2px; margin-right:4px; vertical-align:middle; }
.grid-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: 8px; }
.grid-table { border-collapse: collapse; width: max-content; min-width: 100%; }
.grid-table th, .grid-table td { border: 1px solid var(--border); text-align: center; font-size: 0.85rem; padding: 9px 6px; min-width: 62px; white-space: nowrap; }
.grid-table th { background: var(--panel); font-weight: 600; }
.grid-table .grid-property-col { position: sticky; left: 0; background: var(--panel); text-align: left; padding: 9px 14px; font-weight: 600; z-index: 1; min-width: 165px; font-size: 0.88rem; }
.grid-table th.grid-today { background: #fff8e6; }
.grid-table td.grid-today { box-shadow: inset 0 0 0 2px var(--brand-dark); }
.grid-table td a { display:block; color: inherit; text-decoration: none; }
/* Cleaning-status colouring now lives further down, on .grid-clean-cell
   (one bold consistent block colour) plus a per-status text-colour tweak. */

.pill-linen { background: #ece1f7; color: #6b4fa0; }

.grid-table tr.grid-booking-row td { border-top: 2px solid var(--border); }
.grid-table td.grid-booking-cell { text-align: left; padding-left: 8px; font-weight: 600; font-size: 0.8rem; color: #3a3a3a; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: default; }

/* Custom hover tooltip (see data-tooltip in routes/cleaning.js and the JS
   in app.js that drives this) - styled and sized to actually be noticed,
   unlike a plain browser title tooltip. position:fixed + JS-computed
   coordinates keep it above the grid's own scroll container instead of
   being clipped by it. */
.js-tooltip {
  position: fixed;
  z-index: 1000;
  background: var(--brand-dark);
  color: var(--brand-ink);
  padding: 9px 13px;
  border-radius: 8px;
  font-size: 0.82rem;
  line-height: 1.45;
  box-shadow: var(--shadow);
  pointer-events: none;
  max-width: 260px;
  white-space: normal;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.12s ease;
}
.js-tooltip.visible { opacity: 1; visibility: visible; }
.js-tooltip strong { display: block; font-size: 0.9rem; margin-bottom: 2px; }
.grid-legend .swatch { flex-shrink: 0; }
.pill-cleaning-only { background: #e4efe3; color: #3f6b3a; }

/* Invoice preview page: the booking table/form gets the full page width
   (it has up to 10 columns including a Dates column - squeezed into a
   narrow side-by-side column it was wrapping onto 3-4 lines per row and
   forcing a horizontal scrollbar even at reasonable widths). The PDF
   preview is a separate panel stacked BELOW it instead - it starts empty
   ("Click Preview PDF" placeholder) and only fills in once that button's
   actually clicked, so it's not permanently eating screen space either. */
.invoice-layout { display: flex; flex-direction: column; gap: 1.25rem; }
.invoice-layout-main { min-width: 0; }
/* #invoice-form holds the booking table (often 9+ columns) as well as the
   Invoice details/Extra charges fields - the ordinary .form max-width:
   560px (right for a normal stacked field form) was squeezing that table
   down regardless of how wide the page itself is, forcing the exact
   scrolling this page is meant to avoid. Un-cap the form itself and keep
   the narrower fields tidy with their own max-width instead. */
#invoice-form { max-width: none; }
#invoice-form .invoice-field-narrow { max-width: 360px; }
.invoice-preview-pane iframe { width: 100%; max-width: 760px; height: 80vh; min-height: 500px; border: 1px solid var(--border); border-radius: 8px; background: #fff; display: block; margin: 0 auto 0.75rem; }
.invoice-preview-pane #invoice-download-link { max-width: 760px; margin: 0 auto; display: block; text-align: center; }
.invoice-dates-cell { white-space: nowrap; }
@media (max-width: 900px) {
  .invoice-preview-pane iframe { height: 60vh; }
}

/* Today's checklist (Dashboard) - a few compact grouped lists rather than
   one long undifferentiated one, so it's scannable at a glance. */
.panel-checklist { border-left: 4px solid var(--warn, #b8860b); }
.checklist-group { margin-bottom: 1rem; }
.checklist-group:last-child { margin-bottom: 0; }
.checklist-heading { margin: 0 0 0.4rem; font-size: 0.95rem; }

/* Cleaning schedule grid: the checkout-day cleaning cell now sits in the
   same row as its booking's bar (see buildMergedRowSegments in
   routes/cleaning.js) rather than a separate row underneath - this thick
   inset frame is what visually ties it to the bar immediately to its left. */
/* One bold, consistent fill for every cleaning block, regardless of
   status - so it reads clearly against the softer per-booking bar colours
   instead of blending in. Status is now shown via the icon/text colour
   (see the .grid-clean-cell.grid-cell-* rules below) rather than the
   background hue, except "overdue" which still gets its own alarm colour
   since that one genuinely needs to break the pattern and grab attention.
   The frame(s) tying a clean to its booking, flagging a same-day
   turnover, and marking "today" are all applied as inline box-shadow
   rings from routes/cleaning.js (stacked outward in that order) rather
   than from CSS, since the booking-tie ring's colour has to match that
   specific booking. */
.grid-clean-cell { background: var(--brand-dark); color: var(--brand-ink); font-weight: 700; }
.grid-clean-cell a { color: inherit; }
.grid-clean-cell.grid-cell-unassigned { color: #f6b8ab; }
.grid-clean-cell.grid-cell-waiting { color: #f0cf8c; }
.grid-clean-cell.grid-cell-overdue { background: var(--danger); color: var(--brand-ink); }
.grid-clean-cell.grid-cell-arrived { color: #bcd7ea; }
.grid-clean-cell.grid-cell-done { color: rgba(255, 253, 249, 0.65); font-weight: 500; }
.grid-clean-cell.grid-cell-na { background: var(--panel); color: var(--muted); font-weight: 400; opacity: 0.7; }
