/* Revista Insights — base stylesheet: tokens, cards, tables, modals, toolbar,
   then the review-card, statement-chip, and dashboard-bar styles. */
@import url('https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700;900&family=Merriweather+Sans:wght@400;600;700;800&family=IBM+Plex+Mono:wght@400;500;600&display=swap');

:root {
  --bg: #eef1f6;
  --white: #fff;
  --border: #e3e7ee;
  --border2: #cfd6e1;
  --accent: #2563a8;
  --accent-dk: #1b4c85;
  --accent-light: #e8f0fa;
  --accent2: #16a06e;
  --accent2-light: #e6f6f1;
  --warn: #c0392b;
  --warn-light: #fdf0ef;
  --amber: #b7791f;
  --amber-light: #fdf6e3;
  --text: #182034;
  --text2: #58627a;
  --text3: #98a1b5;
  --shadow: 0 1px 3px rgba(23, 32, 58, .07), 0 1px 2px rgba(23, 32, 58, .05);
  --shadow-md: 0 6px 22px rgba(23, 32, 58, .13);
  --radius: 10px;
  --radius-lg: 14px;
  --sans: 'Lato', sans-serif;
  --heading: 'Merriweather Sans', sans-serif;
  /* figures in dense tables: tabular by design, so columns of means line up */
  --mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* entry-type colors */
  --t-call: #7a4515;        --t-call-light: #f6ebdf;  /* dark brown/orange, matches eCW */
  --t-pto: #16a06e;         --t-pto-light: #e6f6f1;
  --t-office: #0e7f8a;      --t-office-light: #e3f4f6;
  --t-sick: #c0392b;        --t-sick-light: #fdf0ef;
  --t-hours_taken: #b7791f; --t-hours_taken-light: #fdf6e3;
  --t-hours_worked: #6d4fa3;--t-hours_worked-light: #f1ecfa;
  --t-bonus: #a8862d;       --t-bonus-light: #faf3dd;
  --t-non_pto: #5a6478;     --t-non_pto-light: #eef0f4;
  --t-saturday: #345c9c;    --t-saturday-light: #e7edf8;
  --t-late: #8a2f5e;        --t-late-light: #f7e8f0;
  --t-month_hours: #5b6d2f; --t-month_hours-light: #eef2e0;

  /* statement hours ledger: taken/worked mirror the workbook's red/green */
  --t-taken: #b42318;       --t-taken-light: #fdeeec;
  --t-worked: #1e7f3c;      --t-worked-light: #e9f5ec;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: var(--bg); color: var(--text); font-family: var(--sans); font-size: 14px; }
.hidden { display: none !important; }
.muted { color: var(--text2); }
.small { font-size: 12px; }
.dim { color: var(--text3); }
.mono { font-variant-numeric: tabular-nums; }
a { color: var(--accent); }

/* ── Top bar ── */
.topbar {
  background: var(--white); border-bottom: 1px solid var(--border);
  padding: 0 22px; display: flex; align-items: center; gap: 20px;
  height: 54px; box-shadow: var(--shadow); position: sticky; top: 0; z-index: 100;
}
.logo {
  font-family: var(--heading); font-size: 17px; font-weight: 800; color: var(--accent);
  white-space: nowrap; text-decoration: none; display: flex; align-items: center; gap: 9px;
}
.logo img { height: 28px; width: 28px; }
.logo-dot { width: 8px; height: 8px; background: var(--accent2); border-radius: 50%; }
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 12px; }
.user-chip { font-size: 13px; color: var(--text2); white-space: nowrap; }
.user-chip b { color: var(--text); }

.tabs { display: flex; gap: 2px; }
.tab {
  font-family: var(--heading); font-size: 13px; font-weight: 600;
  border: none; background: none; cursor: pointer; color: var(--text2);
  padding: 17px 13px 14px; border-bottom: 3px solid transparent;
  text-decoration: none; display: inline-block; white-space: nowrap;
}
.tab:hover { color: var(--accent); }
.tab.active { color: var(--accent); border-bottom-color: var(--accent); }

/* ── Layout ── */
.page { max-width: 1500px; margin: 22px auto; padding: 0 22px 70px; }
h1 { font-family: var(--heading); font-size: 21px; font-weight: 800; margin-bottom: 4px; }
.page-sub { color: var(--text2); margin-bottom: 18px; font-size: 13px; }
.card {
  background: var(--white); border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow); padding: 18px 20px; margin-bottom: 18px;
}
.card h2 { font-family: var(--heading); font-size: 15px; font-weight: 700; margin-bottom: 12px; }
h2.work-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
h2.work-head .count { color: var(--text3); font-weight: 400; font-size: 13px; }
h2.work-head .spacer { flex: 1; }

/* ── Meters (progress bars) ── */
.meter { height: 7px; border-radius: 99px; background: #e8ecf3; overflow: hidden; }
.meter > i { display: block; height: 100%; border-radius: 99px; min-width: 0; transition: width .25s; }
.meter.thin { height: 5px; }

/* ── Provider cards grid ── */
.pcards { display: grid; grid-template-columns: repeat(auto-fill, minmax(310px, 1fr)); gap: 16px; }
.pcard {
  background: var(--white); border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow); padding: 16px 18px 14px; cursor: pointer; position: relative;
  transition: box-shadow .15s, transform .15s, border-color .15s;
  display: flex; flex-direction: column; gap: 10px;
}
.pcard:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); border-color: var(--border2); }
.pcard .pc-head { display: flex; align-items: baseline; gap: 8px; }
.pcard .pc-name { font-family: var(--heading); font-size: 16.5px; font-weight: 800; color: var(--text); }
.pcard .pc-cred { font-size: 12px; color: var(--text3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
.pcard .pc-year { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--text2); }
.pcard .pc-year .meter { flex: 1; }
.pcard .pc-year .meter > i { background: var(--border2); }
.pc-rows { display: grid; gap: 8px; }
.pc-row { display: grid; grid-template-columns: 52px 1fr auto; gap: 10px; align-items: center; }
.pc-row .lbl { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--text3); }
.pc-row .val { font-size: 12px; font-variant-numeric: tabular-nums; color: var(--text2); white-space: nowrap; }
.pc-row .val b { color: var(--text); font-size: 13px; }
.pc-foot { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 2px; }
.pcard.empty { justify-content: center; align-items: flex-start; color: var(--text3); }

/* ── Pills / badges / chips ── */
.badge {
  display: inline-block; padding: 2px 9px; border-radius: 999px;
  font-size: 11.5px; font-weight: 700; white-space: nowrap;
}
.badge.blue { background: var(--accent-light); color: var(--accent); }
.badge.green { background: var(--accent2-light); color: var(--accent2); }
.badge.amber { background: var(--amber-light); color: var(--amber); }
.badge.red { background: var(--warn-light); color: var(--warn); }
.badge.grey { background: #eef0f4; color: var(--text2); }
.type-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%;
  margin-right: 6px; vertical-align: 0; }

.chip {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer; user-select: none;
  border: 1px solid var(--border2); background: var(--white); color: var(--text2);
  border-radius: 999px; padding: 4px 12px; font-size: 12px; font-weight: 700;
  font-family: var(--heading); transition: all .12s;
}
.chip:hover { border-color: var(--accent); color: var(--accent); }
.chip.on { background: var(--text); border-color: var(--text); color: #fff; }
.chip.on .type-dot { outline: 2px solid rgba(255,255,255,.35); }
.chip-row { display: flex; gap: 8px; flex-wrap: wrap; }

/* ── Tables ── */
table { width: 100%; border-collapse: collapse; }
th {
  text-align: left; font-family: var(--heading); font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; color: var(--text3);
  padding: 8px 10px; border-bottom: 2px solid var(--border); white-space: nowrap;
}
td { padding: 7px 10px; border-bottom: 1px solid var(--border); vertical-align: middle; }
tr:last-child td { border-bottom: none; }
tr.rowlink { cursor: pointer; }
tr.rowlink:hover td { background: var(--accent-light); }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
.table-wrap { overflow-x: auto; }

/* ── Buttons / forms ── */
.btn {
  font-family: var(--heading); font-size: 13px; font-weight: 700; cursor: pointer;
  border: 1px solid var(--border2); background: var(--white); color: var(--text);
  padding: 7px 15px; border-radius: 8px; white-space: nowrap; transition: all .12s;
}
.btn:hover { border-color: var(--accent); color: var(--accent); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn.primary:hover { background: var(--accent-dk); color: #fff; }
.btn.success { background: var(--accent2); border-color: var(--accent2); color: #fff; }
.btn.success:hover { background: #108a5d; color: #fff; }
.btn.danger { background: var(--white); border-color: #f3c9c4; color: var(--warn); }
.btn.danger:hover { background: var(--warn-light); border-color: var(--warn); }
.btn.ghost { border-color: transparent; background: none; color: var(--text2); }
.btn.ghost:hover { color: var(--accent); }
.btn.small { padding: 4px 10px; font-size: 12px; }
.btn.block { width: 100%; }
.btn:disabled { opacity: .5; cursor: default; }

input[type=text], input[type=number], input[type=date], input[type=month],
input[type=password], input[type=search], select, textarea {
  font-family: var(--sans); font-size: 14px; color: var(--text);
  border: 1px solid var(--border2); border-radius: 8px; padding: 7px 11px;
  background: var(--white); width: 100%;
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--accent-light); border-color: var(--accent); }
textarea { resize: vertical; min-height: 70px; }
label.f { display: grid; gap: 5px; font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em; color: var(--text2); }
label.f .small.dim { text-transform: none; letter-spacing: 0; font-weight: 400; }
.frow { display: flex; gap: 12px; }
.frow > * { flex: 1; }
.check { display: flex; align-items: center; gap: 7px; font-size: 13px;
  color: var(--text); text-transform: none; letter-spacing: 0; font-weight: 400; }
.check input { width: auto; }

/* ── Toolbar ── */
.toolbar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 16px; }
.toolbar input[type=search] { max-width: 280px; }
.toolbar .spacer { flex: 1; }
.seg { display: inline-flex; border: 1px solid var(--border2); border-radius: 8px; overflow: hidden; background: var(--white); }
.seg button {
  font-family: var(--heading); font-size: 12px; font-weight: 700; cursor: pointer;
  border: none; background: none; color: var(--text2); padding: 7px 14px;
}
.seg button.active { background: var(--accent); color: #fff; }
/* segs used as form fields: fill the row with evenly sized buttons */
label.f .seg { display: flex; width: 100%; }
label.f .seg button { flex: 1; text-align: center; padding: 8px 10px; }

/* ── Login ── */
.login-wrap { min-height: 100vh; display: grid; place-items: center; padding: 20px; }
.login-card {
  background: var(--white); border: 1px solid var(--border); border-radius: 14px;
  box-shadow: var(--shadow-md); padding: 30px; width: 380px;
}
.login-logo {
  font-family: var(--heading); font-size: 21px; font-weight: 800; color: var(--accent);
  display: flex; align-items: center; gap: 10px; margin-bottom: 4px;
}
.login-logo img { height: 36px; width: 36px; }
#login-form { margin-top: 18px; display: grid; gap: 12px; }
#login-form label { display: grid; gap: 5px; font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em; color: var(--text2); }
.login-hint { margin-top: 14px; line-height: 1.6; }
.error {
  background: var(--warn-light); color: var(--warn); border: 1px solid #f3c9c4;
  padding: 8px 10px; border-radius: 8px; font-size: 13px;
}

/* ── Modal ── */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(18, 25, 46, .5); z-index: 300;
  display: flex; overflow-y: auto; padding: 20px;
}
.modal {
  background: var(--white); border-radius: 14px; box-shadow: var(--shadow-md);
  width: 680px; max-width: 100%; margin: auto;
  max-height: calc(100vh - 40px); overflow-y: auto; padding: 24px;
}
.modal.slim { width: 470px; }
.modal h3 { font-family: var(--heading); font-size: 16px; font-weight: 800; margin-bottom: 14px; }
.modal .sect { display: grid; gap: 12px; margin-bottom: 14px; }
.modal .actions {
  display: flex; gap: 10px; justify-content: flex-end; position: sticky; bottom: 0;
  background: var(--white); padding-top: 12px; border-top: 1px solid var(--border);
}
.modal .actions .left { margin-right: auto; }

/* -- Clickable stat cards → allowance breakdown popup -- */
.stat.clickable { cursor: pointer; transition: box-shadow .12s; }
.stat.clickable:hover { box-shadow: var(--shadow-md); }
.stat .s-open { color: var(--text3); }
.adj-table { display: grid; gap: 7px; }
.adj-line { display: flex; align-items: baseline; gap: 10px; font-size: 13.5px; }
.adj-line .lbl { color: var(--text2); }
.adj-line .fill { flex: 1; border-bottom: 1px dotted var(--border2); }
.adj-line.total { border-top: 1px solid var(--border2); padding-top: 7px; }
.adj-line.grand b { font-size: 15px; }
.pos-amt { color: var(--accent2); }
.neg-amt { color: var(--warn); }
.adj-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px; background: #f5f7fb;
  border: 1px solid var(--border); border-radius: 8px; padding: 6px 10px; font-size: 13px;
  min-width: 0;   /* a long note must never widen the popup */
  cursor: pointer;
}
.adj-row:hover { border-color: var(--border2); }
.adj-row .adj-note { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.adj-row .badge { flex: 0 0 auto; }
.adj-row .adj-detail {
  flex-basis: 100%; display: grid; gap: 3px; font-size: 13px;
  margin-top: 4px; padding-top: 6px; border-top: 1px dashed var(--border2);
  cursor: default;
}
.adj-row .adj-date { color: var(--text3); font-size: 12px; white-space: nowrap; }
.adj-row .adj-note { flex: 1; min-width: 0; }
.adj-row .btn.small { padding: 2px 7px; }

/* ── Entry modal ── */
/* wide two-column add-entry: type & amount left, calendar & note right —
   everything visible at once, no scrolling to reach the calendar */
.modal.wide { width: 1040px; }
.e-cols { display: grid; grid-template-columns: 320px 1fr; gap: 22px;
  align-items: start; margin-bottom: 14px; }
.e-cols .sect { margin-bottom: 0; align-content: start; }
.e-cols .type-tiles { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 900px) { .e-cols { grid-template-columns: 1fr; } }
.tile-label { font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text2); margin-bottom: -6px; }
/* the amount slot keeps a constant height whatever the entry type (input,
   chips, static text, or nothing) so the calendar below never jumps */
.amt-row { align-items: end; min-height: 58px; }
.amt-row #e-amt-wrap { flex: 0 0 150px; }
/* chips line up with the input box itself, not the label above it */
.amt-row .chip-row { flex: 1; align-items: center; min-height: 33px; }
.vhide { visibility: hidden; }
.type-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.type-tile {
  display: flex; align-items: center; gap: 7px; cursor: pointer; user-select: none;
  border: 1.5px solid var(--border2); border-radius: 8px; padding: 8px 10px;
  font-family: var(--heading); font-size: 12px; font-weight: 700; color: var(--text2);
  transition: all .12s; white-space: nowrap;
}
.type-tile:hover { border-color: var(--tc); color: var(--tc); }
.type-tile.on { background: var(--tl); border-color: var(--tc); color: var(--tc); }
.type-tile.more { border-style: dashed; color: var(--text3); justify-content: center; }
.type-tile.more:hover { border-color: var(--accent); color: var(--accent); }
.e-preview {
  background: #f5f7fb; border: 1px solid var(--border); border-radius: 8px;
  padding: 9px 12px; font-size: 13.5px;
}
/* in the actions bar (add-entry modal): one box per affected balance */
.actions .e-preview {
  align-self: center; background: none; border: none; padding: 0;
  font-size: 13px; display: flex; gap: 8px; flex-wrap: wrap;
}
.actions .e-preview .e-pill {
  background: #f5f7fb; border: 1px solid var(--border); border-radius: 8px;
  padding: 6px 12px; white-space: nowrap;
}
.e-preview .ok { color: var(--accent2); }
.e-preview .bad { color: var(--warn); }
/* day-picker (quick add + entry modal) */
.dp-grid .cal-cell { height: 54px; min-height: 0; overflow: hidden; cursor: pointer; }
.dp-cell:hover { border-color: var(--pc); }
.dp-cell.outside { cursor: default; }
.dp-cell.sel-full, .dp-cell.sel-half { background: var(--pl); border-color: var(--pc); }
.dp-cell.sel-half { border-style: dashed; }
.dp-cell.sel-full .d, .dp-cell.sel-half .d { color: var(--pc); }
/* the day that was clicked to open the modal — kept visible while stamping */
.dp-cell.origin { outline: 2px dotted var(--accent); outline-offset: 1.5px; }
.dp-today {
  position: absolute; bottom: 1px; right: 3px; pointer-events: none;
  font-family: var(--heading); font-size: 8px; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase; color: var(--accent);
}
.dp-amt { display: block; font-size: 10px; font-weight: 700; color: var(--pc); }
.dp-dots { display: block; margin-top: 1px; }
.dp-dots .type-dot { width: 6px; height: 6px; margin-right: 3px; }

/* contract-year modal: template field groups */
.ygroup { border: 1px solid var(--border); border-left: 3px solid var(--gc, var(--border2));
  border-radius: 8px; padding: 10px 12px; }
.yg-title { font-family: var(--heading); font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; color: var(--text2); margin-bottom: 8px;
  display: flex; align-items: center; }

.mq-short { color: var(--warn); font-weight: 700; }

/* call-schedule import */
.imp-chip { display: inline-block; background: #eef1f7; color: var(--text2);
  border-radius: 99px; padding: 2px 10px; font-size: 12px; font-weight: 600; }
.imp-chip.ok { background: var(--t-call-light); color: var(--t-call); }
.imp-chip.warn { background: #fdeeea; color: var(--warn); }
.imp-names { display: grid; gap: 8px; margin: 10px 0; }
.imp-name { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: #fdeeea; border: 1px solid #f6d5cc; border-radius: 8px; padding: 8px 12px; }
.imp-name select { margin-left: auto; width: auto; min-width: 220px; }
.imp-skip { font-size: 13px; color: var(--text2); margin-top: 6px;
  display: flex; align-items: baseline; gap: 8px; }
.imp-issues { margin-top: 10px; padding: 8px 12px; border-radius: 8px;
  background: #fdeeea; color: var(--warn); }
.imp-go { display: flex; align-items: center; gap: 14px; }
.imp-go-n { font-family: var(--heading); font-size: 18px; font-weight: 700; }
td.days, th.days { font-variant-numeric: tabular-nums; }
.mq-sub { font-size: 11px; color: var(--text3); font-weight: 400; margin-top: 1px; }

.l-results { display: grid; gap: 8px; }
.l-row {
  display: flex; align-items: center; gap: 10px; background: #f5f7fb;
  border: 1px solid var(--border); border-radius: 8px; padding: 8px 12px; font-size: 13.5px;
}
.l-row .l-lbl { font-family: var(--heading); font-weight: 700; min-width: 90px; }
.l-row input { width: 90px; }
.l-row .raw { color: var(--text3); font-size: 12px; }
@media (max-width: 560px) { .type-tiles { grid-template-columns: repeat(2, 1fr); } }

/* -- Day popup (click a calendar day that already has entries) -- */
.day-list { display: grid; gap: 8px; }
.day-row {
  display: flex; align-items: center; gap: 10px; background: #f5f7fb;
  border: 1px solid var(--border); border-radius: 8px; padding: 8px 12px; font-size: 13.5px;
  min-width: 0;   /* a long nowrap note must never widen the popup */
}
.day-row.pick { cursor: pointer; }
.day-row.pick:hover { border-color: var(--accent); background: var(--white); box-shadow: var(--shadow); }
.day-row .day-main { font-family: var(--heading); font-weight: 700; white-space: nowrap; }
.day-row .day-prov { color: var(--accent); text-decoration: none; }
.day-row .day-prov:hover { text-decoration: underline; }
.day-row .day-amt { color: var(--text3); }
.day-row .day-note {
  flex: 1; min-width: 0; text-align: right; color: var(--text2); font-size: 12.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* -- Right-click quick-add menu (provider calendar) -- */
.ctx-menu {
  position: fixed; z-index: 300; min-width: 200px;
  background: var(--white); border: 1px solid var(--border2); border-radius: 10px;
  box-shadow: var(--shadow-md); padding: 5px; font-size: 13px;
}
.ctx-title {
  font-family: var(--heading); font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em; color: var(--text2);
  padding: 6px 9px 4px;
}
.ctx-item {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 9px; border-radius: 7px; cursor: pointer; user-select: none;
}
.ctx-item:hover { background: #f0f4fa; }
.ctx-already { margin-left: auto; padding-left: 10px; }
.ctx-sep { border-top: 1px solid var(--border); margin: 4px 6px; }

/* -- TEST-copy ribbon (only rendered when the app runs on a non-live port) -- */
.test-ribbon {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 500;
  background: repeating-linear-gradient(-45deg, #b3540e, #b3540e 14px, #9a4407 14px, #9a4407 28px);
  color: #fff; text-align: center; font-family: var(--heading);
  font-size: 12px; font-weight: 700; letter-spacing: .05em;
  padding: 5px 10px; pointer-events: none;
}

/* ── Toast / spinner ── */
.toast {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
  background: var(--text); color: #fff; padding: 10px 18px; border-radius: 10px;
  font-size: 13px; z-index: 400; box-shadow: var(--shadow-md); max-width: 80vw;
}
.toast.bad { background: var(--warn); }
.spinner {
  width: 26px; height: 26px; border: 3px solid var(--border);
  border-top-color: var(--accent); border-radius: 50%; margin: 40px auto;
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── Provider page: hero ── */
.hero {
  background: linear-gradient(135deg, var(--accent) 0%, #3b7fc4 55%, #2f9d84 130%);
  color: #fff; border-radius: var(--radius-lg); box-shadow: var(--shadow-md);
  padding: 20px 24px 18px; margin-bottom: 18px;
}
.hero .hero-top { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.hero .back-btn { font-size: 19px; line-height: 1; padding: 3px 13px 5px; border-radius: 999px;
  align-self: center; }
.hero h1 { color: #fff; font-size: 24px; margin: 0; }
.hero .cred { color: rgba(255,255,255,.75); font-size: 13px; }
.hero .hero-top .spacer { flex: 1; }
.hero .badge.inact { background: rgba(255,255,255,.2); color: #fff; }
.hero-contract { margin-top: 12px; font-size: 13px; color: rgba(255,255,255,.92);
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.hero-contract .ctype {
  background: #fff; color: var(--accent); font-family: var(--heading);
  font-weight: 800; font-size: 11px; padding: 3px 11px; border-radius: 999px;
  text-transform: uppercase; letter-spacing: .05em; white-space: nowrap;
}
.hero-contract .dim2 { color: rgba(255,255,255,.65); }
.yg-divider { font-family: var(--heading); font-size: 12px; font-weight: 800;
  text-transform: uppercase; letter-spacing: .06em; color: var(--text2);
  border-top: 2px solid var(--border); padding-top: 14px; margin-top: 4px; }
.hero-controls { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
.hero-controls select {
  width: auto; min-width: 230px; background: rgba(255,255,255,.14); color: #fff;
  border-color: rgba(255,255,255,.35); font-weight: 700;
}
.hero-controls select option { color: var(--text); }
.hero-controls .btn.hbtn {
  background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.35); color: #fff;
}
.hero-controls .btn.hbtn:hover { background: rgba(255,255,255,.28); color: #fff; }
.hero-controls .btn.solid { background: #fff; border-color: #fff; color: var(--accent); }
.hero-controls .btn.solid:hover { background: #eaf2fb; }
.hero-progress { display: flex; align-items: center; gap: 10px; margin-top: 14px; font-size: 12px; color: rgba(255,255,255,.85); }
.hero-progress .meter { flex: 1; background: rgba(255,255,255,.22); }
.hero-progress .meter > i { background: #fff; }

/* ── Provider page: stat cards ── */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(185px, 1fr)); gap: 14px; margin-bottom: 18px; }
.stat {
  background: var(--white); border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow); padding: 14px 16px 13px; border-top: 3px solid var(--border2);
}
.stat .s-label { font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .07em; color: var(--text2); margin-bottom: 6px; display: flex; justify-content: space-between; }
.stat .s-main { display: flex; align-items: baseline; gap: 6px; margin-bottom: 8px; }
.stat .s-value { font-family: var(--heading); font-size: 24px; font-weight: 800; line-height: 1; }
.stat .s-of { font-size: 12px; color: var(--text3); }
.stat .s-sub { font-size: 11.5px; color: var(--text2); margin-top: 7px; line-height: 1.45; }
.stat.neg .s-value { color: var(--warn); }
.stat.pos .s-value { color: var(--accent2); }

/* ── Provider page: main grid ── */
.prov-grid { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 18px; align-items: start; }
.pg-rail .card { padding: 16px 18px; }
.notes-box { white-space: pre-wrap; font-size: 12.5px; color: var(--text2); line-height: 1.55;
  max-height: 260px; overflow-y: auto; }
.audit-diff { font-size: 11.5px; color: var(--text3); margin-top: 2px; white-space: pre-wrap; }
.aud-list { display: grid; }
.aud-item { padding: 9px 0; border-bottom: 1px solid var(--border); font-size: 12.5px; }
.aud-item:last-child { border-bottom: none; }
.aud-item .when { color: var(--text3); font-size: 11px; }
.aud-item .who { font-weight: 700; }

/* ── Entries list ── */
.ent-row { display: grid; grid-template-columns: 74px auto 1fr auto auto; gap: 10px;
  align-items: center; padding: 7px 4px; border-bottom: 1px solid var(--border); font-size: 13px; }
.ent-row:last-child { border-bottom: none; }
.ent-row:hover { background: #f7f9fc; }
.ent-row .d { font-variant-numeric: tabular-nums; color: var(--text2); }
.ent-row .amt { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
.ent-row .nt { color: var(--text3); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Month calendar ── */
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.cal-head { font-family: var(--heading); font-size: 10px; font-weight: 700;
  text-transform: uppercase; color: var(--text3); text-align: center; padding: 3px 0; }
.cal-cell {
  background: var(--white); border: 1px solid var(--border); border-radius: 7px;
  min-height: 64px; padding: 4px 6px; font-size: 12px; position: relative;
}
.cal-cell.wknd { background: #f6f8fb; }
.cal-cell.other { background: transparent; border-color: transparent; }
.cal-cell.today { border-color: var(--accent); border-width: 2px; }
.cal-cell.outside { background: #f2f4f8; opacity: .55; }
.cal-cell .d { font-weight: 700; color: var(--text3); font-size: 10.5px; }
.cal-cell.clickable { cursor: pointer; }
.cal-cell.clickable:hover { border-color: var(--accent); box-shadow: var(--shadow); }
.cal-ev {
  display: block; border-radius: 5px; padding: 1px 5px; margin-top: 2px;
  font-size: 10.5px; font-weight: 700; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; cursor: pointer; text-decoration: none;
}
.cal-ev.half { opacity: .78; font-style: italic; }
.cal-more-ev { display: block; font-size: 10px; font-weight: 700; color: var(--text3);
  margin-top: 2px; cursor: default; }
.cal-legend { display: flex; gap: 8px; flex-wrap: wrap; margin: 4px 0 14px; }

/* single-month view: fixed-height cells so busy days never stretch the grid */
.cal-nav { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.cal-nav .cal-title { font-family: var(--heading); font-size: 15px; font-weight: 800;
  min-width: 150px; text-align: center; }
.cal-big .cal-cell { height: 104px; min-height: 0; overflow: hidden; }
.cal-big .cal-ev { font-size: 11px; }
/* whole day tinted when the provider takes call that day */
.cal-big .cal-cell.has-call { background: var(--t-call-light); border-color: #dcc3a4; }
.cal-big .cal-cell.has-call .d { color: var(--t-call); }
#big-cal .cal-cell { height: 128px; min-height: 0; overflow: hidden; }

/* ── Rules ── */
.rule-row { display: flex; gap: 10px; align-items: flex-start; padding: 9px 0;
  border-bottom: 1px solid var(--border); }
.rule-row:last-child { border-bottom: none; }
.rule-row .txt { flex: 1; line-height: 1.55; }

@media (max-width: 1000px) {
  .prov-grid { grid-template-columns: 1fr; }
}
@media (max-width: 720px) {
  .tabs { overflow-x: auto; }
  .frow { flex-direction: column; }
  .hero-controls select { min-width: 0; }
}

/* ── provider statement (workbook-style tables to send to a provider) ──── */
.rep-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.rep-bar h2 { font-family: var(--heading); font-size: 15px; font-weight: 700; }
.rep-bar h2 .count { color: var(--text3); font-weight: 400; font-size: 13px; }
.rep-bar .spacer { flex: 1; }
.rep-bar .back-btn { font-size: 17px; line-height: 1; padding: 3px 12px 5px; border-radius: 999px; }
.report { max-width: 920px; margin: 0 auto; }

/* letterhead */
.rep-head {
  display: flex; align-items: flex-end; gap: 16px; margin: 10px 2px 20px;
  padding-bottom: 14px; border-bottom: 3px double var(--border2);
}
.rep-head h1 { font-size: 25px; margin: 0 0 3px; }
.rep-head .sub { color: var(--text2); font-size: 13px; }
.rep-head .sub b { color: var(--text); }
.rep-brand {
  margin-left: auto; display: flex; align-items: center; gap: 8px;
  font-family: var(--heading); font-size: 14px; font-weight: 800; color: var(--text3);
}
.rep-brand img { height: 26px; width: 26px; opacity: .85; }

/* each table is a card accented in its entry-type color (--sc / --scl) */
.rep-sec { border-top: 3px solid var(--sc); padding: 16px 20px 10px; }
.rep-sec-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.rep-sec-head h2 { display: flex; align-items: center; margin: 0; }
.rep-sec .type-dot { background: var(--sc); width: 10px; height: 10px; margin-right: 8px; }
.rep-pills { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; }
.rep-pill {
  background: var(--scl); color: var(--sc); font-family: var(--heading);
  font-size: 11px; font-weight: 700; padding: 3px 11px; border-radius: 999px;
  white-space: nowrap;
}

.rep-table th { font-size: 10px; padding: 7px 12px; border-bottom: 2px solid var(--border2); }
.rep-table td { padding: 7px 12px; font-size: 13px; border-bottom: 1px solid #edf0f5; }
.rep-table tbody tr:nth-child(even) td { background: #f8fafd; }
.rep-table td.lbl {
  font-family: var(--heading); font-weight: 700; font-size: 12px;
  color: var(--text2); white-space: nowrap;
}
.rep-table td.days { font-variant-numeric: tabular-nums; letter-spacing: .01em; }
.rep-table tr.empty td { color: var(--text3); }
.rep-table tr.empty td.days, .rep-table tr.empty td.num { color: #c9cfda; }
.rep-table td.num.pos { color: var(--accent2); font-weight: 600; }
.rep-table td.num.neg { color: var(--warn); font-weight: 600; }
.rep-table tfoot td { font-weight: 700; background: #f2f5f9; border-bottom: 1px solid var(--border); }
.rep-table tfoot tr:first-child td { border-top: 2px solid var(--border2); }
.rep-table tfoot td.lbl { text-transform: uppercase; font-size: 10.5px; letter-spacing: .05em; color: var(--text); }
.rep-table tfoot tr.final td { background: var(--scl); color: var(--sc); border-bottom: none; }
.rep-table tfoot tr.final td.lbl { color: var(--sc); }
.rep-table tfoot tr.final td.num { font-size: 14.5px; }
.rep-table tfoot tr.final td.num.neg { color: var(--warn); }

/* hours ledger: two mirrored halves, equal widths, split down the middle */
.rep-hours { table-layout: fixed; }
.rep-hours .split { border-left: 2px solid var(--border2); }
.rep-hours:not(.with-notes) th:nth-child(1),
.rep-hours:not(.with-notes) th:nth-child(4) { width: 28%; }
.rep-hours.with-notes th:nth-child(1), .rep-hours.with-notes th:nth-child(5) { width: 12%; }
.rep-hours.with-notes th:nth-child(2), .rep-hours.with-notes th:nth-child(4) { width: 11%; }
.rep-hours td { overflow: hidden; text-overflow: ellipsis; }

@media print {
  .topbar, .no-print, .toast { display: none !important; }
  body { background: #fff; font-size: 12px; }
  .page { max-width: none; margin: 0; padding: 0; }
  .report { max-width: none; }
  .card { box-shadow: none; border: none; border-radius: 0; margin-bottom: 16px; }
  .rep-head { margin-top: 0; }
  .rep-sec { break-inside: avoid; border-top-width: 2.5px; padding: 10px 0 4px; }
  .rep-table th { color: #444; }
  .rep-pill, .rep-table tbody tr:nth-child(even) td, .rep-table tfoot td,
  .rep-table tfoot tr.final td, .rep-sec, .type-dot {
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
}

/* ── issues triage ─────────────────────────────────────────────────────── */
.bulkbar { display: flex; gap: 8px; align-items: center; margin-bottom: 12px;
  padding: 8px 12px; background: var(--accent-light); border: 1px solid var(--border2);
  border-radius: 8px; font-size: 13px; }
.bulkbar span { color: var(--text2); margin-right: 4px; }
.issue-group { margin-bottom: 14px; padding-top: 6px; }
.ig-head { display: flex; gap: 10px; align-items: center; padding: 4px 2px 8px; }
.ig-name { font-weight: 700; font-size: 15px; color: var(--text); text-decoration: none; }
a.ig-name:hover { color: var(--accent); }
.issue-note { margin-top: 3px; font-size: 12px; color: var(--text2);
  border-left: 3px solid var(--amber); padding-left: 8px; }
tr.dim td { opacity: .62; }

/* ═══ Google Reviews — app-specific ═══════════════════════════════════════ */

/* sentiment tokens */
:root {
  --pos: #1e7f3c;  --pos-light: #e9f5ec;
  --neg: #b42318;  --neg-light: #fdeeec;
  --mixed: #b7791f; --mixed-light: #fdf6e3;
  --neutral: #5a6478; --neutral-light: #eef0f4;
  --star: #e8a417;
}

/* ── review cards ── */
.rev-list { display: grid; gap: 12px; }
.rev-card {
  background: var(--white); border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow); padding: 14px 18px 12px;
}
.rev-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.rev-stars { color: var(--star); font-size: 14px; letter-spacing: 1px; white-space: nowrap; }
.rev-stars .off { color: var(--border2); }
.rev-who { font-family: var(--heading); font-weight: 700; }
.who-link { color: inherit; text-decoration: none; border-bottom: 1px dotted currentColor; }
.who-link:hover { color: var(--accent); border-bottom-style: solid; }
.rev-loc { color: var(--accent); font-size: 12.5px; font-weight: 700; }
.rev-date { color: var(--text3); font-size: 12px; margin-left: auto; white-space: nowrap; }
.rev-body { margin-top: 8px; font-size: 13.5px; line-height: 1.55; color: var(--text);
  white-space: pre-wrap; }
.rev-body.clamp { display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical;
  overflow: hidden; }
.rev-more { font-size: 12px; color: var(--accent); cursor: pointer; margin-top: 3px;
  display: inline-block; }
.rev-summary { margin-top: 8px; font-size: 12.5px; color: var(--text2);
  border-left: 3px solid var(--border2); padding-left: 9px; font-style: italic; }
.rev-reply { margin-top: 8px; background: #f5f7fb; border-radius: 8px; padding: 8px 12px;
  font-size: 12.5px; color: var(--text2); }
.rev-reply b { color: var(--text); }
.rev-tags { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }

/* statement chips: green = praise, red = complaint */
.stmt {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
  border-radius: 999px; padding: 3px 11px; font-size: 11.5px; font-weight: 700;
  background: var(--pos-light); color: var(--pos); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; cursor: default;
}
.stmt.neg { background: var(--neg-light); color: var(--neg); }
.stmt .who { border-left: 1px solid currentColor; padding-left: 6px; opacity: .85; }
.stmt .who.unmatched { opacity: .55; font-style: italic; }

.badge.pos { background: var(--pos-light); color: var(--pos); }
.badge.neg { background: var(--neg-light); color: var(--neg); }
.badge.mixed { background: var(--mixed-light); color: var(--mixed); }
.badge.neutral { background: var(--neutral-light); color: var(--neutral); }

/* ── dashboard: category praise/complaint bars ── */
.cat-rows { display: grid; gap: 9px; }
.cat-row { display: grid; grid-template-columns: 170px 1fr 92px; gap: 12px;
  align-items: center; font-size: 12.5px; }
.cat-row .lbl { font-family: var(--heading); font-weight: 700; color: var(--text2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cat-row .nums { text-align: right; font-variant-numeric: tabular-nums;
  color: var(--text3); white-space: nowrap; }
.cat-row .nums .p { color: var(--pos); font-weight: 700; }
.cat-row .nums .n { color: var(--neg); font-weight: 700; }
.duo-track { height: 5px; border-radius: 99px; background: #eef1f6; }
.duo { display: flex; gap: 2px; height: 100%; }
.duo i { height: 100%; border-radius: 99px; min-width: 4px; opacity: .85; }
.duo .p { background: var(--pos); }
.duo .n { background: var(--neg); }

/* ── dashboard: staff leaderboard ── */
.lead-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 860px) { .lead-cols { grid-template-columns: 1fr; } }
.lead-row { display: flex; align-items: center; gap: 10px; padding: 6px 2px;
  border-bottom: 1px solid var(--border); font-size: 13px; }
.lead-row:last-child { border-bottom: none; }
.lead-row .nm { font-weight: 700; }
.lead-row .nm a { color: var(--text); text-decoration: none; }
.lead-row .nm a:hover { color: var(--accent); }
.lead-row .rl { color: var(--text3); font-size: 11px; }
.lead-row .meter { flex: 1; }
.lead-row .ct { font-variant-numeric: tabular-nums; font-weight: 700; min-width: 26px;
  text-align: right; }

/* ── staff cards ── */
.staff-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
  gap: 14px; }
.staff-card { background: var(--white); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow); padding: 14px 16px;
  cursor: pointer; transition: box-shadow .15s, transform .15s; }
.staff-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.staff-card .sc-name { font-family: var(--heading); font-weight: 800; font-size: 15px; }
.staff-card .sc-counts { display: flex; gap: 8px; margin-top: 8px; }
/* ── staff list (the ranked, leaderboard-shaped view of the same cards) ── */
.staff-list { background: var(--white); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow); overflow: hidden; }
.staff-list th { padding: 9px 14px; background: #f7f9fc; }
.staff-list td { padding: 8px 14px; font-size: 13px; }
.staff-list tbody tr:last-child td { border-bottom: none; }
.staff-list td.nm { font-family: var(--heading); font-weight: 700; }
.staff-list th.rk, .staff-list td.rk { width: 44px; text-align: right; padding-right: 4px;
  color: var(--text3); font-variant-numeric: tabular-nums; }
.staff-list td.rk.top { color: var(--accent); font-weight: 800; }
.staff-list td.num.p { color: var(--pos); font-weight: 700; }
.staff-list td.num.n { color: var(--neg); font-weight: 700; }
.staff-list td.num.thin-evidence { color: var(--text3); }
.staff-list th.sortable { cursor: pointer; user-select: none; }
.staff-list th.sortable:hover { color: var(--accent); background: var(--accent-light); }
.staff-list th.sortable.on { color: var(--accent); }
.staff-list th .ar { display: inline-block; width: 10px; margin-left: 3px; }
.staff-list .pctcol { width: 130px; }
.staff-list .rate-cell { display: flex; align-items: center; gap: 8px; }
.staff-list .rate-cell .meter { flex: 1; min-width: 40px; }
.staff-list .rate-cell .pct { font-variant-numeric: tabular-nums; font-weight: 700;
  min-width: 34px; text-align: right; }

.mention-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: #f5f7fb; border: 1px solid var(--border); border-radius: 8px;
  padding: 8px 12px; font-size: 13px; }
.mention-row .raw { font-family: var(--heading); font-weight: 700; }

/* ── staff picker popup ──────────────────────────────────────────────────
   The list a <datalist> would not let us style. Fixed so it can sit over
   modals; scroll-behavior:smooth is what makes arrow-key travel glide rather
   than jump, and the thin custom scrollbar keeps a long list from looking
   like a wall of text. */
.sp-pop {
  position: fixed; z-index: 400; overflow-y: auto; scroll-behavior: smooth;
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  background: var(--white); border: 1px solid var(--border2);
  border-radius: 10px; box-shadow: var(--shadow-md); padding: 4px;
}
.sp-pop::-webkit-scrollbar { width: 9px; }
.sp-pop::-webkit-scrollbar-track { background: transparent; }
.sp-pop::-webkit-scrollbar-thumb {
  background: #d3dae5; border-radius: 99px; border: 2px solid var(--white);
}
.sp-pop::-webkit-scrollbar-thumb:hover { background: var(--border2); }
.sp-pop { scrollbar-width: thin; scrollbar-color: #d3dae5 transparent; }
/* Name on top, hint under it. Side by side, the hint competed with the name
   for a narrow popup's width and pushed three-word names onto three lines —
   and it has more to say now that it names the office too. */
.sp-row {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  padding: 6px 10px; border-radius: 7px; cursor: pointer; font-size: 13px;
  line-height: 1.35;
}
.sp-row.on { background: var(--accent-light); }
.sp-row .sp-nm { font-family: var(--heading); font-weight: 700; color: var(--text); }
.sp-row .sp-hint { font-size: 11.5px; color: var(--text3); }
.sp-row.on .sp-hint { color: var(--accent); }
.sp-none, .sp-more { padding: 8px 10px; font-size: 12px; color: var(--text3); }
.sp-more { border-top: 1px solid var(--border); margin-top: 4px; }
/* an AI suggestion sits under the row it belongs to, colour-keyed by how much
   the model trusts it -- the reason is always shown, because a suggestion you
   cannot check is one you should not accept */
.mention-sugg { font-size: 12px; line-height: 1.45; margin: 4px 0 0 34px;
  padding: 6px 10px; border-radius: 7px; border-left: 3px solid var(--border2);
  background: #f8fafd; color: var(--text2); }
.mention-sugg b { font-family: var(--heading); }
.mention-sugg.conf-high { border-left-color: var(--pos); background: var(--pos-light); }
.mention-sugg.conf-high b { color: var(--pos); }
.mention-sugg.conf-medium { border-left-color: var(--amber); background: var(--amber-light); }
.mention-sugg.conf-medium b { color: var(--amber); }
.mention-sugg.conf-low, .mention-sugg.unsure { border-left-color: var(--text3); }
.loose-h .btn { margin-left: 10px; vertical-align: 1px; }
.mention-row select { width: auto; min-width: 190px; margin-left: auto; }

/* ── sync tab ── */
.conn-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%;
  margin-right: 7px; background: var(--warn); vertical-align: 0; }
.conn-dot.ok { background: var(--accent2); }
.job-bar { display: flex; align-items: center; gap: 12px; margin-top: 10px;
  font-size: 13px; }
.job-bar .meter { flex: 1; }
.job-msg { font-size: 12.5px; color: var(--text2); margin-top: 6px; }
.setup-steps { font-size: 13px; line-height: 1.7; color: var(--text2); }
.setup-steps code { background: #f0f3f8; border-radius: 5px; padding: 1px 6px;
  font-size: 12px; }

/* ── verify tab ── */
.stmt.unsure { outline: 1.5px dashed var(--amber); outline-offset: 1px; }
.stmt .q { margin-left: 2px; color: var(--amber); }
.stmt .q.ok { color: inherit; opacity: .7; }
.v-rows { display: grid; gap: 7px; margin-top: 12px; }
.v-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  background: #f5f7fb; border: 1px solid var(--border); border-radius: 8px;
  padding: 7px 10px; font-size: 13px; }
.v-row.rejected { opacity: .55; }
.v-row.rejected .v-excerpt { text-decoration: line-through; }
.v-row select { width: auto; max-width: 200px; padding: 4px 8px; font-size: 12.5px; }
.v-row .v-sent { min-width: 96px; }
.v-row .v-sent.positive { background: var(--pos-light); border-color: var(--pos); color: var(--pos); }
.v-row .v-sent.negative { background: var(--neg-light); border-color: var(--neg); color: var(--neg); }
.v-row .v-excerpt { flex: 1; min-width: 180px; color: var(--text2); font-style: italic;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v-row .v-acts { display: flex; gap: 5px; }
.v-row .v-acts .btn { padding: 3px 9px; }

/* fix-statement modal: the full review text, so the correction is judged in
   context. pre-wrap lives ONLY on the inner text div — on the container it
   would render the HTML template's own indentation as stray whitespace. */
.fix-review { background: #f5f7fb; border: 1px solid var(--border); border-radius: 8px;
  padding: 10px 12px; font-size: 13px; line-height: 1.55; color: var(--text);
  max-height: 220px; overflow-y: auto; margin-bottom: 14px; }
.fix-review .fr-text { white-space: pre-wrap; }

/* unlinked-mention expander: the reviews behind a raw name */
.mention-wrap { display: grid; gap: 6px; }
.mention-detail { display: grid; gap: 10px; padding: 2px 0 6px 24px; }
.md-item { border-left: 3px solid var(--border2); padding-left: 10px; }
.md-review { font-size: 12.5px; color: var(--text2); line-height: 1.55;
  white-space: pre-wrap; max-height: 150px; overflow-y: auto; margin-top: 3px; }
.md-review mark { background: var(--amber-light); color: var(--amber);
  font-weight: 700; border-radius: 3px; padding: 0 2px; }

/* ── standardized review cards + full-review modal ── */
.rev-card.click { cursor: pointer; transition: box-shadow .15s, border-color .15s, transform .15s; }
.rev-card.click:hover { box-shadow: var(--shadow-md); border-color: var(--border2); transform: translateY(-1px); }
.rev-body.clamp2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; margin-top: 7px; }
/* our reply, one line on a card: enough to see that it was answered and in
   what tone, the whole thing is in the modal */
.rev-reply.clamp1 { display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical;
  overflow: hidden; }

/* ── reviews, card view ──
   Compact tiles, several to a row, the same shape as the Staff cards. The
   full-width cards are the LIST view — one entry per line, the whole summary
   and every tag on show. A tile is for scanning a wall of reviews. */
.rev-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 14px; align-items: start; }
/* the spinner and the empty-state notice are not tiles — they take the row */
.rev-cards > .spinner, .rev-cards > .card { grid-column: 1 / -1; }
.rev-tile { display: flex; flex-direction: column; gap: 5px;
  background: var(--white); border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow); padding: 12px 15px 13px; cursor: pointer;
  transition: box-shadow .15s, border-color .15s, transform .15s; }
.rev-tile:hover { box-shadow: var(--shadow-md); border-color: var(--border2);
  transform: translateY(-2px); }
.rt-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.rt-top .rev-date { margin-left: 0; }
.rt-who { font-family: var(--heading); font-weight: 800; font-size: 14.5px; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rt-loc { color: var(--accent); font-size: 12px; font-weight: 700; margin-top: -3px; }
.rt-meta { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 1px; }
/* Four lines of the patient's own words — never the AI summary, which at this
   size would read as a quote. White-space collapses here, unlike everywhere
   else the review text appears: at a four-line clamp, a blank line between
   paragraphs spends a quarter of the preview on nothing. The full-width card
   and the modal keep the breaks. */
.rt-body { font-size: 12.5px; line-height: 1.5; color: var(--text2); white-space: normal;
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
  margin-top: 2px; }
.rt-counts { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 2px; }
/* AI summary: clearly labeled as AI-written — never styled like a quote */
.rev-summary { margin-top: 9px; font-size: 13px; font-style: normal; color: var(--text);
  background: var(--accent-light); border-left: 3px solid var(--accent);
  border-radius: 0 8px 8px 0; padding: 7px 11px; line-height: 1.5; }
.ai-tag { display: inline-block; font-family: var(--heading); font-size: 9.5px; font-weight: 800;
  text-transform: uppercase; letter-spacing: .07em; color: var(--accent);
  background: var(--white); border-radius: 4px; padding: 1px 6px; margin-right: 8px;
  vertical-align: 1px; }
.rm-body { background: #f5f7fb; border: 1px solid var(--border); border-radius: 8px;
  padding: 12px 14px; font-size: 13.5px; line-height: 1.6; white-space: pre-wrap;
  max-height: 45vh; overflow-y: auto; }

/* person page: one block per review, its tags inside */
.pg-rev { background: #f5f7fb; border: 1px solid var(--border); border-radius: 8px;
  padding: 9px 12px; }
.pg-tag { display: flex; align-items: center; gap: 9px; padding: 4px 0; font-size: 13px; }
.pg-tag .pg-exc { flex: 1; min-width: 140px; color: var(--text2); }
.pg-tag .btn.small { padding: 2px 8px; }

/* AI point summaries are paraphrases, not quotes — no italics anywhere */
.v-row .v-excerpt { font-style: normal; }

.pg-rev.click { cursor: pointer; transition: border-color .12s, box-shadow .12s; }
.pg-rev.click:hover { border-color: var(--accent); box-shadow: var(--shadow); }

/* review modal: two columns — editable tags left, the review text right */
.rm-cols { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: 20px; align-items: start; margin-bottom: 6px; }
@media (max-width: 900px) { .rm-cols { grid-template-columns: 1fr; } }
.rm-col-head { font-family: var(--heading); font-size: 11px; font-weight: 800;
  text-transform: uppercase; letter-spacing: .06em; color: var(--text2); margin-bottom: 8px; }
.rm-cols .rm-body { max-height: none; }
.v-row input.v-staff { width: auto; max-width: 190px; padding: 4px 8px; font-size: 12.5px; }
.modal.wide .v-row select.v-cat { max-width: 170px; }

/* review modal, refined: review LEFT (own scroll), tags RIGHT. Inside the
   modal each tag stacks on two lines — controls above, the full wrapping
   excerpt + status + verdict below — instead of one crushed flex line. */
.rm-cols { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); }
.rm-cols .rm-body { max-height: 62vh; overflow-y: auto; }
.modal.wide .v-row { display: grid; gap: 6px 8px; align-items: center;
  grid-template-columns: auto minmax(0, 1fr) minmax(0, 1fr) auto;
  grid-template-areas: "sent cat staff acts" "exc exc exc state"; }
.modal.wide .v-row .v-sent { grid-area: sent; }
.modal.wide .v-row .v-cat { grid-area: cat; width: 100%; max-width: none; }
.modal.wide .v-row input.v-staff { grid-area: staff; width: 100%; max-width: none; }
.modal.wide .v-row .v-acts { grid-area: acts; }
.modal.wide .v-row .v-excerpt { grid-area: exc; white-space: normal;
  overflow: visible; font-size: 12.5px; line-height: 1.45; }
.modal.wide .v-row .v-state { grid-area: state; justify-self: end; }

/* review modal: tags column scrolls internally (like the review side), and the
   sticky Close bar seals the modal's bottom padding so nothing peeks under it */
.modal.wide #rm-tags { max-height: 56vh; overflow-y: auto; padding-right: 4px; }
.modal.wide { padding-bottom: 0; }
.modal.wide .actions { margin: 0 -24px; padding: 12px 24px 18px;
  border-radius: 0 0 14px 14px; }

/* ── dashboard: sentiment spectrum ──────────────────────────────────────────
   A diverging stacked bar per category, mirroring the Surveys app's Spectrum.
   Both sides grow outward from a shared centre line, so the balance between
   praise and complaint reads across rows at a glance — which a left-anchored
   bar (the old .duo) could not do.

   Segment classes are namespaced spec-seg, NOT .seg: .seg is already the
   segmented button group in this app's CSS. */
.spec-list { display: grid; }
.spec-row { display: flex; align-items: center; gap: 16px; padding: 9px 0;
  border-bottom: 1px solid var(--border); cursor: pointer; }
.spec-row:last-child { border-bottom: none; }
.spec-row:hover { background: var(--bg); }
.spec-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.spec-name { width: 190px; flex-shrink: 0; font-family: var(--heading);
  font-size: 13px; font-weight: 700; color: var(--text2); line-height: 1.3; }

.spec-track { flex: 1; position: relative; height: 22px; display: flex; }
.spec-mid { position: absolute; left: 50%; top: -2px; bottom: -2px; width: 1px;
  background: var(--border2); z-index: 1; }
.spec-l { width: 50%; display: flex; justify-content: flex-end; }
.spec-r { width: 50%; display: flex; }
.spec-seg { height: 16px; align-self: center; min-width: 2px; }
.spec-l .spec-seg:first-child { border-radius: 3px 0 0 3px; }
.spec-r .spec-seg:last-child  { border-radius: 0 3px 3px 0; }
.spec-seg.sneg { background: var(--neg); }
.spec-seg.mneg { background: #e6a8a1; }
.spec-seg.mpos { background: #8fcfae; }
.spec-seg.spos { background: var(--pos); }

.spec-val { width: 116px; text-align: right; flex-shrink: 0; }
.spec-val b { display: block; font-variant-numeric: tabular-nums; font-size: 13.5px; }
.spec-val span { font-size: 11px; color: var(--text3); }
.spec-val .split { color: var(--amber); font-weight: 700; }

.spec-scale { cursor: default; }
.spec-scale:hover { background: none; }
.spec-lane { display: flex; justify-content: space-between; align-items: center;
  height: auto; font-size: 10px; color: var(--text3);
  text-transform: uppercase; letter-spacing: .05em; }

/* ── dashboard: monthly trend ─────────────────────────────────────────────── */
.trend { display: flex; gap: 7px; align-items: flex-end; height: 140px; }
.trend-col { flex: 1; display: flex; flex-direction: column;
  justify-content: flex-end; height: 100%; }
.trend-stack { flex: 1; display: flex; flex-direction: column;
  justify-content: flex-end; }
.trend-neg { background: var(--neg); border-radius: 3px 3px 0 0; min-height: 1px; }
.trend-pos { background: var(--pos); border-radius: 0 0 3px 3px; min-height: 1px; }
.trend-lbl { text-align: center; font-size: 10px; color: var(--text3);
  padding-top: 5px; font-variant-numeric: tabular-nums; }

@media (max-width: 760px) {
  .spec-name { width: 116px; }
  .spec-val { width: 92px; }
}

/* ── fractional star rating ─────────────────────────────────────────────────
   4.7 lights four stars and 70% of the fifth. Two identical star rows stacked,
   the gold one clipped to a width — both layers inherit the same font metrics,
   so the glyphs register exactly on top of each other.

   letter-spacing is deliberately 0: with spacing, the clip boundary after k
   stars falls at k*(glyph + gap), so a fraction would cover part of the gap
   and read slightly high. Adjacent glyphs make the percentage exact. */
.rating { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
.star-num { color: var(--star); font-weight: 800; font-variant-numeric: tabular-nums; }
.stars-frac { position: relative; display: inline-block; line-height: 1;
  letter-spacing: 0; font-size: 12px; }
.stars-frac .base { color: var(--border2); }
.stars-frac .fill { position: absolute; left: 0; top: 0; bottom: 0;
  overflow: hidden; color: var(--star); }
.rating.lg .star-num { font-family: var(--heading); font-size: 24px; line-height: 1; }
.rating.lg .stars-frac { font-size: 15px; }

/* ── provenance badges ──────────────────────────────────────────────────────
   Which source(s) a review reached us from. Deliberately quiet — this is
   metadata about our own collection, not about the review. */
.srcs { display: inline-flex; gap: 4px; align-items: center; }
.src { font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; padding: 1px 6px; border-radius: 3px;
  background: var(--neutral-light); color: var(--text2); white-space: nowrap; }
.src.scrape   { background: #f2eef8; color: #6b4fa0; }
.src.places   { background: var(--accent2-light); color: var(--accent2); }
.src.workbook { background: var(--amber-light); color: var(--amber); }
.src.business { background: var(--accent-light); color: var(--accent); }
.src.corrob   { background: var(--pos-light); color: var(--pos); }
.rev-date.approx { border-bottom: 1px dotted var(--text3); cursor: help; }

/* ── staff card: the rate the sentiment sorts use ───────────────────────────
   Shown on every card so the ordering is legible rather than mysterious, with
   an explicit note when there are too few mentions to mean much. */
.sc-rate { display: flex; align-items: baseline; gap: 8px; margin-top: 7px;
  font-size: 11.5px; flex-wrap: wrap; }
.sc-rate > span:first-child { font-weight: 700; color: var(--text2); }
.sc-rate .good { color: var(--pos); }
.sc-rate .bad { color: var(--neg); }

/* ── dashboard: locations list + selected location's card ──────────────────
   The list scrolls; the card stays put beside it. */
.off-wrap { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1.05fr);
  gap: 16px; align-items: start; }
@media (max-width: 900px) { .off-wrap { grid-template-columns: 1fr; } }

.off-list { max-height: 560px; overflow-y: auto; display: grid; gap: 2px;
  padding-right: 4px; }
.off-row { display: grid; grid-template-columns: 10px 1fr auto 18px; gap: 10px;
  align-items: center; padding: 8px 9px; border-radius: 8px; cursor: pointer;
  border: 1px solid transparent; }
.off-row:hover { background: var(--bg); }
.off-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.off-row.sel { background: var(--accent-light); border-color: var(--accent); }
.off-dot { width: 10px; height: 10px; border-radius: 50%; }
.off-name { font-family: var(--heading); font-weight: 700; font-size: 13.5px; }
.off-sub { font-size: 11.5px; color: var(--text3); }
.off-right { text-align: right; }
.off-stars { display: flex; justify-content: flex-end; }
/* the list is dense, so the stars ride smaller here than on the stat card */
.off-stars .star-num { font-size: 12.5px; }
.off-stars .stars-frac { font-size: 10px; }
.off-split { font-size: 11px; font-variant-numeric: tabular-nums; display: flex; gap: 5px;
  justify-content: flex-end; }
.off-split .p { color: var(--pos); font-weight: 700; }
.off-split .n { color: var(--neg); font-weight: 700; }
.off-go { text-decoration: none; color: var(--text3); font-size: 15px; text-align: center; }
.off-go:hover { color: var(--accent); }

.off-pane { min-height: 200px; }
.off-hint { padding: 24px 8px; }

/* ── staff provenance ───────────────────────────────────────────────────────
   Whether a real roster sync produced this person, or they were invented here
   by linking a review mention to a new record. */
.sc-office { font-size: 11.5px; color: var(--text2); font-weight: 600; margin-top: 1px; }
.sc-src { font-size: 10.5px; font-weight: 700; margin-top: 5px; }
.sc-src.ok { color: var(--text3); }
.sc-src.bad { color: var(--warn); }

.unver-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  background: var(--bg); border-radius: 8px; flex-wrap: wrap; }
.unver-who { display: flex; flex-direction: column; min-width: 190px; }
.unver-pick { width: auto; min-width: 240px; margin-left: auto; }

/* Two kinds of loose end — ad-hoc staff rows and unlinked mentions — share one
   collapsible card, separated rather than merged so each keeps its own action. */
.loose-sect + .loose-sect { margin-top: 20px; padding-top: 16px;
  border-top: 1px solid var(--border); }
.loose-h { font-family: var(--heading); font-size: 13.5px; font-weight: 800;
  margin: 0 0 6px; display: flex; align-items: baseline; gap: 8px; }
.loose-h .count { font-size: 11.5px; font-weight: 600; color: var(--text3); }

/* ── ask ────────────────────────────────────────────────────────────────────
   Finding is free and instant; reading costs money. The UI keeps those two
   steps visibly apart so nobody spends without meaning to. */
/* ── Ask: the assistant ──────────────────────────────────────────────────────────
   This page is not a chat. Finding reviews is free and reading them costs money, so
   the two steps stay laid out where you can see them. What is borrowed is the
   dressing: his avatar and name plate, the starter pills, the bot bubble his
   answers arrive in, and the three blinking dots while he reads. Bubble,
   typing and starter rules are copied token-for-token from the other apps so
   he looks like one assistant across all four. */
.ask-head { display: flex; align-items: center; gap: 11px; margin-bottom: 14px; }
.charles-ava { width: 44px; height: 44px; border-radius: 50%; flex: none;
  display: grid; place-items: center; color: var(--accent);
  background: var(--accent-light); border: 1px solid var(--border2); }
.charles-ava.thinking { animation: charlesBlink 1.2s infinite both; }
.ask-head .ch-name { font-family: var(--heading); font-weight: 700; font-size: 15px;
  line-height: 1.15; }
.ask-head .ch-name small {
  display: block; font-family: var(--sans); font-weight: 400; font-size: 11.5px;
  color: var(--text3); margin-top: 1px;
}

.charles-msg {
  max-width: 92%; padding: 11px 14px; border-radius: 12px; font-size: 14px;
  line-height: 1.6; overflow-wrap: anywhere;
}
.charles-bot {
  align-self: flex-start; background: var(--white); border: 1px solid var(--border);
  border-bottom-left-radius: 4px;
}
.charles-user {
  align-self: flex-end; background: var(--accent); color: #fff;
  border-bottom-right-radius: 4px; white-space: pre-wrap; font-size: 13.5px;
}
.charles-typing { display: inline-flex; gap: 4px; padding: 3px 0; }
.charles-typing i {
  width: 6px; height: 6px; border-radius: 50%; background: var(--text3);
  animation: charlesBlink 1s infinite both;
}
.charles-typing i:nth-child(2) { animation-delay: .2s; }
.charles-typing i:nth-child(3) { animation-delay: .4s; }
@keyframes charlesBlink { 0%, 80%, 100% { opacity: .25; } 40% { opacity: 1; } }

.charles-starters { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.charles-starters button {
  font: inherit; font-size: 12px; text-align: left; color: var(--accent);
  background: var(--white); border: 1px solid var(--border2); border-radius: 14px;
  padding: 6px 11px; cursor: pointer; transition: background .12s, border-color .12s;
}
.charles-starters button:hover { background: var(--accent-light); border-color: var(--accent); }

/* ── Ask: the thread ── */
.ask-followup { display: flex; gap: 8px; margin-top: 6px; }
.ask-followup input {
  flex: 1; border: 1px solid var(--border2); border-radius: 9px; padding: 9px 12px;
  font-family: var(--sans); font-size: 13.5px; background: var(--white);
}
.ask-followup input:focus { border-color: var(--accent); outline: none; }
/* a proposed search is an offer, not something that happens on its own */
.ask-suggest {
  align-self: flex-start; max-width: 92%; display: flex; align-items: center;
  gap: 10px; flex-wrap: wrap; font-size: 12.5px; color: var(--amber);
  background: var(--amber-light); border-left: 3px solid var(--amber);
  border-radius: 0 8px 8px 0; padding: 8px 12px;
}
.ask-thread-meta {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 11.5px; padding-top: 4px; border-top: 1px solid var(--border);
}
.ask-thread-meta .dim { flex: 1; }

.ask-bar { display: flex; gap: 10px; }
.ask-bar input { flex: 1; font-size: 15px; padding: 11px 14px; }
.chip { font-size: 12px; padding: 5px 11px; border-radius: 99px; cursor: pointer;
  border: 1px solid var(--border2); background: var(--white); color: var(--text2); }
.chip:hover { border-color: var(--accent); color: var(--accent); }

.ask-hits { display: grid; gap: 8px; }
.ask-hit { border: 1px solid var(--border); border-radius: 9px; padding: 10px 12px;
  cursor: pointer; }
.ask-hit:hover { border-color: var(--accent); background: var(--bg); }
.ah-head { display: flex; align-items: center; gap: 9px; margin-bottom: 5px;
  flex-wrap: wrap; }

/* full-bleed footer of the card, on the panel grey the assistant sits on elsewhere;
   the negative margins cancel the .card padding (18px 20px) exactly */
.ask-answer { display: flex; flex-direction: column; gap: 10px; background: var(--bg);
  border-top: 1px solid var(--border); margin: 18px -20px -18px; padding: 16px 20px;
  border-radius: 0 0 var(--radius-lg) var(--radius-lg); }
.aa-meta { font-size: 12px; color: var(--text3); align-self: flex-start; }
.aa-body { font-size: 14.5px; line-height: 1.65; }
.aa-body h4 { font-family: var(--heading); font-size: 14.5px; font-weight: 800;
  margin: 16px 0 6px; }
.aa-body p { margin: 0 0 10px; }
.aa-body ul { margin: 0 0 10px; padding-left: 20px; }
.aa-body li { margin-bottom: 4px; }

/* search snippets: an excerpt centred on the match, not the opening lines */
.ah-snip { font-size: 13.5px; line-height: 1.55; color: var(--text2); }
.ah-snip mark { background: var(--amber-light); color: var(--text);
  font-weight: 700; border-radius: 3px; padding: 0 2px; }

/* a label that sits beside its control instead of above it, so it lines up
   with the segmented toggle next to it */
.inline-f { display: flex; align-items: center; gap: 8px; }
.inline-f > span { font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .07em; color: var(--text2); white-space: nowrap; }
.inline-f select { width: auto; }

/* ── location card beside the list ──────────────────────────────────────── */
.loc-card { background: var(--white); border: 1px solid var(--border2);
  border-radius: 10px; box-shadow: var(--shadow-md); padding: 11px 12px;
  animation: lc-in .18s ease-out; }
@keyframes lc-in { from { opacity: 0; transform: translateX(8px); } }

.lc-load { display: grid; place-items: center; min-height: 120px; }
.lc-x { position: absolute; top: 8px; right: 9px; border: none; background: none;
  font-size: 19px; line-height: 1; color: var(--text3); cursor: pointer; }
.lc-x:hover { color: var(--text); }
.lc-title { font-family: var(--heading); font-weight: 800; font-size: 13.5px; padding-right: 16px; }
.lc-sub { font-size: 10px; color: var(--text3); line-height: 1.3; margin-top: 1px; }

.lc-stats { display: grid; grid-template-columns: repeat(3,1fr); gap: 6px;
  margin: 9px 0; padding: 7px 0; border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border); text-align: center; }
.lc-stats b { display: block; font-family: var(--heading); font-size: 14px;
  font-variant-numeric: tabular-nums; }
.lc-stats b.good { color: var(--pos); } .lc-stats b.bad { color: var(--neg); }
.lc-stats span { font-size: 10px; color: var(--text3); }

.lc-sect { margin-bottom: 9px; }
.lc-h { font-size: 10px; font-weight: 800; text-transform: uppercase;
  letter-spacing: .07em; color: var(--text3); margin-bottom: 5px; }
/* the bar is length-of-feeling, so strongest and weakest read at a glance */
.lc-cat { position: relative; display: flex; align-items: center; gap: 6px;
  font-size: 11.5px; padding: 2px 6px; border-radius: 5px; overflow: hidden; }
.lc-bar { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 5px; }
.lc-bar.good { background: var(--pos-light); } .lc-bar.bad { background: var(--neg-light); }
.lc-name { position: relative; flex: 1; }
.lc-n { position: relative; color: var(--text3); font-size: 10.5px;
  font-variant-numeric: tabular-nums; }

.lc-people { display: flex; flex-wrap: wrap; gap: 5px; }
.lc-p { font-size: 11px; padding: 2px 7px; border-radius: 99px; text-decoration: none; }
.lc-p.good { background: var(--pos-light); color: var(--pos); }
.lc-p.bad { background: var(--neg-light); color: var(--neg); }

.lc-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.lc-actions .btn { text-align: center; text-decoration: none; }

/* ── compare matrix ─────────────────────────────────────────────────────────
   Categories down, offices across. Colour first so the pattern reads before
   any number does; the sticky first column keeps the row label in view while
   scrolling right through eighteen offices.

   Cells are separated tiles rather than a ruled grid — at this density the
   gaps do the separating and lines would only add noise. Figures are mono and
   tabular so a column of means lines up on the decimal, which is what makes a
   column scannable at all.

   Row and column headers are drag handles. They carry `touch-action: none`
   because without it the browser claims the gesture for scrolling and the
   drag never starts on a trackpad or a touchscreen. */
.mx-wrap { overflow-x: auto; margin-top: 14px; padding-bottom: 4px; }
/* width:auto or the base `table{width:100%}` stretches this to the card and,
   because every cell is a fixed width, dumps all the slack into the label
   column — which shoves the whole grid to the right edge. */
.mx { width: auto; border-collapse: separate; border-spacing: 3px; font-size: 11.5px; }
.mx th, .mx td { padding: 0; border-bottom: none; }
.mx-corner { position: sticky; left: 0; z-index: 3; background: var(--white); }

.mx-loc {
  height: 104px; vertical-align: bottom; padding-bottom: 7px; width: 46px;
  cursor: grab; touch-action: none;
}
/* office names rotated: eighteen horizontal labels would need a 2000px table */
.mx-loc span {
  display: block; writing-mode: vertical-rl; transform: rotate(180deg);
  font-family: var(--heading); font-size: 10.5px; font-weight: 700;
  color: var(--text2); white-space: nowrap; margin: 0 auto;
}
.mx-loc:hover span { color: var(--accent); }

.mx-cat {
  position: sticky; left: 0; z-index: 2; background: var(--white);
  text-align: right; padding: 0 12px 0 2px; font-family: var(--heading);
  font-size: 11.5px; font-weight: 700; color: var(--text); white-space: nowrap;
  cursor: grab; touch-action: none;
}
.mx-cat:hover { color: var(--accent); }
.mx-n {
  color: var(--text3); font-weight: 400; margin-left: 7px; font-size: 10px;
  font-family: var(--mono); font-variant-numeric: tabular-nums;
}
.mx-sort { color: var(--accent); margin-left: 3px; }

.mx-cell {
  width: 46px; height: 32px; text-align: center; cursor: pointer;
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 11.5px; font-weight: 500; color: var(--text);
  border-radius: 4px; position: relative; background: var(--bg);
}
.mx-cell[data-cat]:hover { outline: 2px solid var(--accent); outline-offset: 1px; z-index: 1; }
/* too few points to trust: hatched rather than merely pale, so thin evidence
   never passes for a confident reading */
.mx-cell.thin { background: var(--bg); color: var(--text3); font-weight: 400; }
.mx-cell.thin::after {
  content: ""; position: absolute; inset: 0; border-radius: 4px;
  background: repeating-linear-gradient(45deg, transparent 0 3px,
    rgba(23, 32, 58, .07) 3px 6px);
}
.mx-cell.thin span { font-size: 10px; position: relative; z-index: 1; }
.mx-cell.empty { background: transparent; cursor: default; }
.mx-cell.empty:hover { outline: none; }

.mx-legend {
  display: flex; flex-wrap: wrap; align-items: center; gap: 18px;
  margin-top: 14px; font-size: 11.5px; color: var(--text2);
}
.mx-ramp { display: inline-flex; align-items: center; gap: 7px; }
.mx-ramp i {
  font-style: normal; font-family: var(--mono); font-size: 10.5px;
  color: var(--text3);
}
.mx-strip {
  display: block; width: 140px; height: 10px; border-radius: 3px;
  background: linear-gradient(90deg, rgba(180,35,24,.72), rgba(180,35,24,.10),
    rgba(30,127,60,.10), rgba(30,127,60,.72));
}
.mx-key {
  display: inline-block; width: 15px; height: 15px; border-radius: 4px;
  vertical-align: -3px; margin-right: 6px; border: 1px solid var(--border);
}
.mx-key.thin {
  background: repeating-linear-gradient(45deg, var(--bg) 0 3px,
    rgba(23, 32, 58, .09) 3px 6px);
}
.mx-key.empty { background: transparent; }

/* ── dragging a row or column ── */
.mx-no-select, .mx-no-select * { user-select: none !important; cursor: grabbing !important; }
tr.mx-dim, .mx-dim { opacity: .25; transition: opacity .15s; }
.mx-ghost {
  position: fixed; z-index: 500; pointer-events: none;
  background: rgba(255, 255, 255, .92); border-radius: 8px; padding: 3px;
  box-shadow: var(--shadow-md); transform: scale(1.03);
}
.mx-ghost-row { display: flex; gap: 3px; align-items: center; }
.mx-ghost-col { display: flex; flex-direction: column; gap: 3px; }
.mx-ghost-cell {
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  border-radius: 4px; font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 11.5px; font-weight: 500; color: var(--text);
}
.mx-ghost-head {
  font-family: var(--heading); font-size: 10.5px; font-weight: 700;
  color: var(--text2); white-space: nowrap; background: none;
}
/* a column header keeps its rotation while carried — the ghost span sits
   outside .mx-loc, so the vertical writing mode has to be restated here */
.mx-ghost-vert { align-items: flex-end; padding-bottom: 7px; }
.mx-ghost-vert span {
  display: block; writing-mode: vertical-rl; transform: rotate(180deg);
  white-space: nowrap; margin: 0 auto;
}

/* ── ask: two routes, a plan you can edit, and an archive ───────────────────*/
.ask-top { display: flex; align-items: baseline; gap: 14px; }
.ask-top h1 { flex: 1; }

/* the proposed search, shown before it costs anything */
.ask-plan { margin-top: 12px; padding: 12px 14px; background: var(--bg);
  border: 1px solid var(--border); border-radius: 10px; display: grid; gap: 9px; }
.ap-h { font-size: 11px; font-weight: 800; text-transform: uppercase;
  letter-spacing: .06em; color: var(--text2); }
.ap-h .dim { display: block; font-weight: 400; text-transform: none;
  letter-spacing: 0; font-size: 11.5px; margin-top: 3px; }
.ap-f { display: grid; gap: 3px; }
.ap-f > span { font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text3); }
.ap-f i { font-style: normal; cursor: help; border-bottom: 1px dotted var(--text3); }
.ap-f textarea { resize: vertical; font-size: 13px; line-height: 1.45; }
.ap-run { display: flex; align-items: center; gap: 10px; }

.ah-list { display: grid; gap: 6px; max-height: 56vh; overflow-y: auto; }
.ah-row { padding: 9px 11px; border: 1px solid var(--border); border-radius: 8px;
  cursor: pointer; }
.ah-row:hover { border-color: var(--accent); background: var(--bg); }
.ah-q { font-weight: 700; font-size: 13.5px; }
.ah-meta { font-size: 11.5px; color: var(--text3); margin-top: 2px;
  display: flex; align-items: center; gap: 6px; }

/* ── ask: the search on the left, the conversation on the right ─────────────
   Two states of one grid rather than two layouts. The right track starts at
   0fr, which makes the collapse the DEFAULT and the split the exception — so
   the search owns the whole page until there is an answer to put beside it.

   Both tracks are minmax(0, Nfr): same unit either side, which is what lets
   the browser interpolate grid-template-columns at all. The left card's right
   edge slides left over the transition, and the answer arrives in the space it
   gave up. */
.ask-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0fr);
  gap: 0;
  align-items: start;
  transition: grid-template-columns .42s cubic-bezier(.4, 0, .2, 1), gap .42s;
}
.ask-layout.chat { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); gap: 18px; }

/* clipped rather than hidden: display:none would kill the transition, and the
   card inside must not spill into the left column mid-slide */
.ask-right { overflow: hidden; min-width: 0; }
.ask-right .ask-chat-card { display: none; }

/* Sticky so the thread stays put while you scroll the hit list on the left —
   the whole point of the split. Capped to the viewport with its own scroll,
   since a long conversation would otherwise push the page down and undo it. */
.ask-layout.chat .ask-right {
  overflow: visible;
  position: sticky;
  top: 16px;
  max-height: calc(100vh - 34px);
  display: flex;
}
.ask-layout.chat .ask-right .ask-chat-card {
  display: flex; flex-direction: column; min-height: 0; flex: 1;
  padding: 0; overflow: hidden;
}
.ask-layout.chat .ask-right #ask-answer { display: flex; min-height: 0; flex: 1; }

/* .ask-answer is normally a full-bleed card FOOTER, so it carries negative
   margins that cancel .card padding. Here it is the whole card, so those come
   back off and it gets all four corners instead of two. */
.ask-layout.chat .ask-answer {
  flex: 1; min-height: 0; overflow-y: auto;
  margin: 0; border-top: none; border-radius: var(--radius-lg);
}

/* Below this the two columns would be too narrow to read, so it goes back to
   stacked — which is also where the sticky behaviour stops making sense. */
@media (max-width: 1080px) {
  .ask-layout, .ask-layout.chat { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .ask-layout.chat .ask-right { position: static; max-height: none; display: block; }
  .ask-layout.chat .ask-right .ask-chat-card { display: block; }
  .ask-layout.chat .ask-right #ask-answer { display: block; }
  .ask-layout.chat .ask-answer { overflow-y: visible; }
}

/* review-level sentiment is spelled out (positive/negative); statement
   badges use the short forms. Both need the same colours. */
.badge.positive { background: var(--pos-light); color: var(--pos); }
.badge.negative { background: var(--neg-light); color: var(--neg); }

/* dashboard: recent reviews */
.recent-list { display: flex; flex-direction: column; margin-top: 6px; }
.recent-row { padding: 9px 8px; border-bottom: 1px solid var(--border); cursor: pointer; border-radius: 6px; }
.recent-row:last-child { border-bottom: 0; }
.recent-row:hover { background: var(--hover, rgba(127,127,127,.08)); }
.rr-head { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.rr-head .rev-date { margin-left: auto; }
.rr-body { margin-top: 4px; font-size: 13px; color: var(--text2); }
.rr-body .ai-tag { margin-right: 6px; }
.rr-body.clamp1 { display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; }
.auto-toggle { display: flex; gap: 10px; align-items: flex-start; margin-top: 10px; cursor: pointer; }
.auto-toggle input { margin-top: 3px; width: auto; }
.auto-toggle > span { display: flex; flex-direction: column; gap: 2px; }

/* replying to a review on Google */
.reply-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 10px; }
.reply-box { margin-top: 10px; }
.reply-box textarea { width: 100%; resize: vertical; font: inherit; }
.reply-warn { color: var(--warn); margin-top: 6px; }

/* view-only users (hub role "user"): the server refuses their writes; this
   keeps the controls that would only be refused off the screen */
body.viewer .admin-only,
body.viewer #rm-add, body.viewer #add-staff, body.viewer #staff-import,
body.viewer #p-edit, body.viewer [data-fix], body.viewer #a-add,
body.viewer #c-new, body.viewer #c-add,
body.viewer [data-act=rename], body.viewer [data-act=toggle], body.viewer [data-act=del] { display: none !important; }

/* reviews tab: summary band for the filtered slice. One white band on the
   SAME grid as .rev-cards (columns and gap), so each figure sits over a
   column of tiles; the inner padding matches a tile's, so the text lines up
   too. Dividers sit in the middle of the column gap. */
.slice-bar { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  column-gap: 14px; row-gap: 10px; margin: 4px 0 14px; padding: 11px 0;
  /* outline via shadow, not border: a border narrows the grid by 2px, which
     drops it to 4 columns at exactly the width where the tiles still fit 5 */
  background: var(--white); box-shadow: 0 0 0 1px var(--border), var(--shadow);
  border-radius: var(--radius-lg); }
.sb-item { position: relative; padding: 0 16px; min-width: 0; }
.sb-item + .sb-item::before { content: ''; position: absolute; left: -8px; top: 2px; bottom: 2px;
  width: 1px; background: var(--border); }
.sb-label { font-size: 10.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--text3); }
.sb-value { font-family: var(--heading); font-size: 20px; font-weight: 800; line-height: 1.25; margin-top: 2px; }
.sb-value .rating .star-num { font-size: 20px; }
.sb-sub { font-size: 11.5px; color: var(--text3); margin-top: 1px; }
.sb-rating { display: flex; align-items: center; gap: 14px; }
.sb-hist { display: flex; align-items: flex-end; gap: 3px; height: 40px; }
.sb-col { display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; width: 11px; }
.sb-col i { display: block; width: 100%; background: #f5b301; border-radius: 2px 2px 0 0; }
.sb-col span { font-size: 9px; color: var(--text3); line-height: 1; margin-top: 2px; }
.pos-t { color: var(--pos); } .neg-t { color: var(--neg); }
.f-range { display: inline-flex; align-items: center; gap: 4px; }
.f-range input { width: auto; }

/* ── trends ── hairline solid grid, 2px line, ringed dots, thin columns */
.tr-card { margin-bottom: 18px; }
.lead-cols .tr-card { margin-bottom: 0; }
.tr-plot { width: 100%; min-height: 60px; }
.tr-plot svg { display: block; overflow: visible; }
.tr-grid { stroke: var(--border); stroke-width: 1; }
.tr-ax { font-size: 11px; fill: var(--text3); font-variant-numeric: tabular-nums; }
.tr-line { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.tr-dot { fill: var(--accent); stroke: var(--white); stroke-width: 2; }
.tr-dot.thin { fill: var(--white); stroke: var(--accent); stroke-width: 2; }
.tr-dot.tr-on { r: 6; }
.tr-end { font-size: 12px; font-weight: 700; fill: var(--text); }
.tr-cross { stroke: var(--border2); stroke-width: 1; opacity: 0; pointer-events: none; }
.tr-bar { fill: var(--accent); }
.tr-bar.tr-on, .tr-seg.tr-on { filter: brightness(1.15); }
.tr-hit { fill: transparent; cursor: crosshair; }
.tr-note { margin: -4px 0 14px; max-width: 900px; }
.tr-legend { display: inline-flex; gap: 12px; margin-right: 10px; font-size: 12px; font-weight: 400; color: var(--text2); }
.tr-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 5px; vertical-align: -1px; }
.tr-tt { position: fixed; z-index: 50; pointer-events: none; background: var(--white); border: 1px solid var(--border2);
  border-radius: 8px; box-shadow: var(--shadow-md); padding: 8px 10px; font-size: 12px; min-width: 130px; }
.tr-tt-h { font-weight: 700; color: var(--text2); margin-bottom: 4px; }
.tr-tt-r { display: flex; align-items: center; gap: 7px; line-height: 1.6; }
.tr-tt-r i { width: 12px; height: 2px; border-radius: 1px; flex: none; }
.tr-tt-r b { color: var(--text); font-variant-numeric: tabular-nums; }
.tr-tt-r span { color: var(--text3); }
.tr-tbl-wrap { overflow-x: auto; }
.tr-tbl td.num, .tr-tbl th.num { text-align: right; font-variant-numeric: tabular-nums; }
.tr-row { margin-bottom: 18px; }

/* topics: lines + a legend that doubles as the on/off switch */
.tr-tlegend { display: flex; flex-wrap: wrap; gap: 6px; margin: 2px 0 10px; }
.tr-chip { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; font-size: 12px;
  border: 1px solid var(--border2); border-radius: 14px; background: var(--white); color: var(--text3); cursor: pointer; }
.tr-chip i { width: 14px; height: 2px; border-radius: 1px; opacity: .35; }
.tr-chip.on { color: var(--text); border-color: var(--text3); }
.tr-chip.on i { opacity: 1; height: 3px; }
.tr-tline { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; transition: opacity .12s; }
.tr-tline.quiet { opacity: .15; }
.tr-tdot { stroke: var(--white); stroke-width: 2; }
.tr-chip { font: inherit; font-size: 12px; }
.tr-tlab { font-size: 11.5px; fill: var(--text2); }
/* the line under the pointer: thicker on the chart, bold in the readout */
.tr-tline.hot { stroke-width: 3; }
.tr-tt-r.hl b, .tr-tt-r.hl span { font-weight: 800; color: var(--text); }
.tr-tt-r.hl i { height: 3px; }

/* review modal: the popup is a column capped at the viewport; the review side
   is its own column — the text scrolls, the reply box stays docked at the
   bottom where it's always in view instead of below the fold */
.modal.wide { display: flex; flex-direction: column; }
.modal.wide > .rm-cols { flex: 1 1 auto; min-height: 0; align-items: stretch;
  grid-template-rows: minmax(0, 1fr); }
.modal.wide .rm-left, .modal.wide .rm-cols > div:last-child { display: flex; flex-direction: column; min-height: 0; }
.modal.wide .rm-left .rm-body { flex: 1 1 auto; min-height: 110px; max-height: none; }
.modal.wide #rm-tags { flex: 1 1 auto; min-height: 0; max-height: none; }
.rm-reply { flex: none; }
.rm-notes { flex: none; }
.rm-notes .rm-col-head { margin: 14px 0 6px; }
.rm-notes textarea { width: 100%; resize: vertical; font: inherit; min-height: 60px; }
/* on a short screen the review shrinks to its floor and the reply still
   doesn't fit — then the whole left column scrolls, so Save stays reachable
   instead of sliding under the Close bar */
.modal.wide .rm-left { overflow-y: auto; overflow-x: hidden; padding: 0 4px 4px 2px; }
.rm-reply .rm-col-head { margin: 14px 0 6px; }
.rp-current { max-height: 110px; overflow-y: auto; margin-top: 10px; }
.reply-box textarea { min-height: 70px; }
.reply-foot { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.reply-foot .reply-warn { flex: 1; margin: 0; line-height: 1.35; }
.modal.wide #rm-tags { align-content: start; }

/* tag → its source sentence in the review */
.src-click { cursor: pointer; }
.v-row.src-on, .stmt.src-on { box-shadow: 0 0 0 2px var(--accent); }
.rm-sent.hl { border-radius: 3px; transition: background .2s; }
.rm-sent.hl.neg { background: #fbd9d5; box-shadow: 0 0 0 2px #fbd9d5; }
.rm-sent.hl.pos { background: #d3ecd9; box-shadow: 0 0 0 2px #d3ecd9; }
mark.rm-quote { color: inherit; border-radius: 3px; padding: 1px 0; }
mark.rm-quote.neg { background: #fbd9d5; box-shadow: 0 0 0 2px #fbd9d5; }
mark.rm-quote.pos { background: #d3ecd9; box-shadow: 0 0 0 2px #d3ecd9; }

/* dashboard: map first, recent reviews as a narrow side panel of the same height */
.dash-top { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 18px; align-items: stretch;
  margin-bottom: 18px; }
.dash-top > .card { margin-bottom: 0; }
.recent-panel { display: flex; flex-direction: column; min-height: 0; padding: 16px 14px 12px; }
.dash-top { max-height: none; }
.recent-panel .recent-list { flex: 1 1 0; min-height: 0; overflow-y: auto; margin: 0 -6px; }
.recent-panel .recent-row { padding: 8px 6px; }
.recent-panel .rr-head { gap: 6px; }
.recent-panel .rr-head .rev-stars { font-size: 12px; }
.rr-sub { display: flex; align-items: center; gap: 6px; margin-top: 1px; font-size: 12px; }
.rr-loc { color: var(--accent); font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.rr-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--neutral); }
.rr-dot.positive { background: var(--pos); } .rr-dot.negative { background: var(--neg); }
.rr-dot.mixed { background: var(--mixed); }
.rr-flag { font-size: 10.5px; color: var(--text3); white-space: nowrap; }
.rr-flag.amber { color: var(--amber); }
.recent-panel .rr-body { font-size: 12px; line-height: 1.4; margin-top: 3px; }
.rr-body.clamp2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.recent-all { margin-top: 8px; align-self: flex-end; }
@media (max-width: 1100px) { .dash-top { grid-template-columns: 1fr; }
  .recent-panel .recent-list { max-height: 420px; flex: none; } }

/* a tag that counts toward a different office than the review's own */
.office-tag { margin-left: 6px; padding: 0 6px; border-radius: 9px; font-size: 11px;
  font-weight: 700; background: #eef1fb; color: var(--accent); border: 1px solid #c9d2f0; }
.v-row .v-office.set { border-color: var(--accent); color: var(--accent); font-weight: 600; }
.v-row .v-office-open { padding: 3px 8px; font-size: 12px; color: var(--text2); }
.linkish { background: none; border: 0; padding: 0; color: var(--accent); cursor: pointer;
  font: inherit; text-align: left; margin: 2px 0 6px; }
.linkish:hover { text-decoration: underline; }

/* reviews in another language: label + switch in the popup, reply reminder */
.rm-lang { font-weight: 600; text-transform: none; letter-spacing: 0; color: var(--text3); margin-left: 6px; }
.rm-tr { margin-left: 8px; padding: 1px 8px; font-size: 11px; text-transform: none; letter-spacing: 0; }
.reply-lang { font-size: 12px; background: var(--accent-light); color: var(--accent);
  border-radius: 6px; padding: 6px 10px; margin: 0 0 8px; }
.reply-lang.warn { background: #fdeeea; color: var(--warn); margin: 0 0 10px; }

/* ── multi-client chrome ─────────────────────────────────────────────────── */
body:not(.operator) .operator-only { display: none !important; }
.tenant-switch { width: auto; max-width: 200px; font-size: 13px; padding: 4px 8px; }
