/* ============================================================
 * Payment Tracking Sheets (PTS)
 *
 * The grid holds 41 columns x up to 500 rows a page, so it scrolls in
 * both directions with a frozen header row and row-number column.
 * ============================================================ */

/* ---------- sheet list ---------- */
.pts-sheet-name {
  font-weight: 600;
  color: var(--text);
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  text-align: left;
}
.pts-sheet-name:hover { color: var(--primary); text-decoration: underline; }
.pts-sheet-file {
  font-size: calc(11px * var(--ui-font-scale, 1));
  color: var(--text-muted);
  margin-top: 2px;
}
.pts-num { text-align: right; font-variant-numeric: tabular-nums; }

/* ---------- grid panel header ---------- */
.pts-grid-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.pts-grid-head h3 {
  font-size: calc(14.5px * var(--ui-font-scale, 1));
  font-weight: 600;
  color: var(--text);
}
.pts-grid-head .pts-meta {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 5px;
}
.pts-chip {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  background: var(--surface-3);
  color: var(--text-muted);
  font-size: calc(11px * var(--ui-font-scale, 1));
}
.pts-chip.is-primary { background: var(--primary-soft); color: var(--primary-hover); }

/* ---------- summary tiles ---------- */
.pts-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}
.pts-stat {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 10px 13px;
}
.pts-stat .label {
  display: block;
  font-size: calc(10px * var(--ui-font-scale, 1));
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--text-muted);
  font-weight: 600;
  margin-bottom: 3px;
}
.pts-stat .value {
  font-size: calc(15px * var(--ui-font-scale, 1));
  font-weight: 600;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.pts-stat.is-primary { border-left: 3px solid var(--primary); }
.pts-stat.is-paid .value { color: var(--success); }
.pts-stat.is-denial .value { color: var(--error); }
.pts-stat.is-adj .value { color: var(--warning); }

/* ---------- toolbar ---------- */
.pts-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}
.pts-toolbar .pts-spacer { flex: 1 1 auto; }
.pts-search {
  min-width: 280px;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  font-size: calc(12px * var(--ui-font-scale, 1));
}
.pts-select {
  padding: 7px 9px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  font-size: calc(12px * var(--ui-font-scale, 1));
}
.btn.is-on { background: var(--primary-soft); color: var(--primary-hover); }

/* ---------- the grid ---------- */
.pts-grid-wrap {
  overflow: auto;
  max-height: calc(100vh - 380px);
  min-height: 280px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  overscroll-behavior: contain;
}
.pts-grid {
  border-collapse: separate;
  border-spacing: 0;
  width: max-content;
  min-width: 100%;
  font-size: calc(11px * var(--ui-font-scale, 1));
  white-space: nowrap;
}
.pts-grid thead th {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--surface-2);
  color: var(--text-muted);
  padding: 8px 11px;
  border-right: 1px solid var(--divider);
  border-bottom: 1px solid var(--border);
  font-weight: 600;
  font-size: calc(10px * var(--ui-font-scale, 1));
  text-transform: uppercase;
  letter-spacing: .04em;
  text-align: left;
  max-width: 240px;
  cursor: pointer;
  user-select: none;
}
.pts-grid thead th:hover { color: var(--text); }
.pts-grid thead th .pts-th-label {
  display: inline-block;
  max-width: 210px;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: bottom;
}
.pts-grid thead th .pts-sort { color: var(--primary); font-size: calc(9px * var(--ui-font-scale, 1)); margin-left: 3px; }

.pts-grid thead tr.pts-filter-row th {
  top: 31px;
  z-index: 19;
  padding: 4px 5px;
  background: var(--surface);
  text-transform: none;
  cursor: default;
}
.pts-filter-input {
  width: 100%;
  min-width: 92px;
  padding: 4px 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text);
  font-family: inherit;
  font-size: calc(11px * var(--ui-font-scale, 1));
}
.pts-filter-input:focus { outline: 1px solid var(--primary); border-color: var(--primary); }

.pts-grid tbody td {
  padding: 5px 11px;
  border-right: 1px solid var(--divider);
  border-bottom: 1px solid var(--divider);
  color: var(--text);
  max-width: 260px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pts-grid tbody tr:hover td { background: var(--surface-2); }
.pts-grid td.pts-cell-num { text-align: right; font-variant-numeric: tabular-nums; }
.pts-grid td.pts-cell-empty { color: var(--text-faint); }
.pts-grid td a { color: var(--primary); }

/* Frozen row-number column, pinned under the sticky header. */
.pts-grid th.pts-rownum,
.pts-grid td.pts-rownum {
  position: sticky;
  left: 0;
  z-index: 15;
  width: 62px;
  min-width: 62px;
  text-align: right;
  background: var(--surface-2);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  border-right: 1px solid var(--border);
  cursor: default;
}
.pts-grid thead th.pts-rownum { z-index: 30; }
.pts-grid tbody tr:hover td.pts-rownum { background: var(--surface-3); }

.pts-grid-empty {
  padding: 26px;
  text-align: center;
  color: var(--text-muted);
  font-size: calc(12px * var(--ui-font-scale, 1));
}

/* ---------- pagination ---------- */
.pts-pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px;
  margin: 12px 0;
}
.pts-pager-info {
  font-size: calc(11px * var(--ui-font-scale, 1));
  color: var(--text-muted);
  margin-right: 8px;
  font-variant-numeric: tabular-nums;
}
.pts-page-btn {
  min-width: 30px;
  padding: 5px 9px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  font-size: calc(11px * var(--ui-font-scale, 1));
  cursor: pointer;
  font-variant-numeric: tabular-nums;
}
.pts-page-btn:hover:not(:disabled) { background: var(--surface-3); }
.pts-page-btn.is-active {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
  font-weight: 600;
}
.pts-page-btn:disabled { opacity: .45; cursor: not-allowed; }
.pts-page-gap { padding: 0 4px; color: var(--text-muted); }
.pts-jump {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-left: 8px;
  font-size: calc(11px * var(--ui-font-scale, 1));
  color: var(--text-muted);
}
.pts-jump input {
  width: 70px;
  padding: 5px 7px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  font-size: calc(11px * var(--ui-font-scale, 1));
}

/* ---------- import notes ---------- */
.pts-notes {
  margin-top: 12px;
  font-size: calc(11px * var(--ui-font-scale, 1));
  color: var(--text-muted);
  line-height: 1.6;
}
.pts-notes strong { color: var(--text); }

/* ---------- upload form ---------- */
.pts-upload-form {
  max-width: 620px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 20px;
}
.pts-field { margin-bottom: 16px; }
.pts-field label {
  display: block;
  font-size: calc(10px * var(--ui-font-scale, 1));
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--text-muted);
  font-weight: 600;
  margin-bottom: 5px;
}
.pts-field input[type="text"],
.pts-field input[type="file"] {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text);
  font-family: inherit;
  font-size: calc(12px * var(--ui-font-scale, 1));
}
.pts-hint { font-size: calc(11px * var(--ui-font-scale, 1)); color: var(--text-muted); margin-top: 5px; }

.pts-schema {
  margin-top: 18px;
  max-width: 900px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px 18px;
}
.pts-schema summary { cursor: pointer; font-weight: 600; font-size: calc(12px * var(--ui-font-scale, 1)); color: var(--text); }
.pts-schema ol {
  margin: 14px 0 0 20px;
  columns: 3;
  column-gap: 26px;
  font-size: calc(11px * var(--ui-font-scale, 1));
  color: var(--text);
}
@media (max-width: 900px) { .pts-schema ol { columns: 1; } }
.pts-schema li { margin-bottom: 4px; break-inside: avoid; }
.pts-schema .pts-kind {
  font-size: calc(9.5px * var(--ui-font-scale, 1));
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--text-faint);
  margin-left: 5px;
}

/* ============================================================
 * PTS Reports — pack tabs, scope bar, headline summary, and the
 * breakdown table (which grows period columns when a report drills)
 * ============================================================ */

/* ---------- the report pack: one tab per standing report ---------- */
.pts-pack {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(178px, 1fr));
  gap: 8px;
  margin-bottom: 10px;
}
/* Section headings inside the pack grid. The grid is auto-fill, so a
   heading spanning 1 / -1 crosses the whole row; with auto-fit the empty
   tracks would collapse and the heading would stop short. */
.pts-pack-section {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 10px 0 0;
  font-size: calc(10px * var(--ui-font-scale, 1));
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--text-muted);
}
.pts-pack-section:first-child { margin-top: 0; }
.pts-pack-section::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: var(--divider);
}
.pts-pack-section-n {
  order: 3;
  font-weight: 600;
  color: var(--text-faint);
}
/* A report that reads the payment ledger rather than the claims says so,
   because its billed and open columns are blank by design. */
.pts-pack-src {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 5px;
  font-size: calc(9px * var(--ui-font-scale, 1));
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  border-radius: 999px;
  background: var(--success-soft);
  color: var(--success);
  vertical-align: middle;
}

.pts-pack-tab {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 11px;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  font: inherit;
  font-size: calc(11.5px * var(--ui-font-scale, 1));
  cursor: pointer;
  transition: border-color .12s, color .12s, background .12s;
}
.pts-pack-tab:hover { border-color: var(--primary); color: var(--text); }
.pts-pack-tab.is-active {
  border-color: var(--primary);
  background: var(--surface-2);
  color: var(--text);
  font-weight: 600;
  box-shadow: inset 3px 0 0 var(--primary);
}
.pts-pack-no {
  flex: 0 0 auto;
  min-width: 18px;
  height: 18px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-size: calc(10px * var(--ui-font-scale, 1));
  font-weight: 600;
  color: var(--text-muted);
}
.pts-pack-tab.is-active .pts-pack-no {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}
.pts-pack-name { flex: 1 1 auto; line-height: 1.25; }
/* A filled dot means this tab already holds a result for the scope on
   screen — so "Generate all 10" is visibly different from one tab. */
.pts-pack-dot {
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: transparent;
  border: 1px solid var(--border);
}
.pts-pack-tab.is-ready .pts-pack-dot {
  background: var(--success);
  border-color: var(--success);
}
.pts-pack-blurb {
  font-size: calc(11.5px * var(--ui-font-scale, 1));
  color: var(--text-muted);
  margin: 0 0 14px;
  min-height: 17px;
}

/* ---------- scope bar ---------- */
.pts-scope-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 14px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  margin-bottom: 10px;
}
.pts-scope-summary {
  flex: 1 1 auto;
  font-size: calc(11.5px * var(--ui-font-scale, 1));
  font-weight: 600;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---------- report colour ----------
   Three categorical hues, picked with the data-viz validator rather than by
   eye: they clear the colour-blind separation and normal-vision floors on
   every pair, on both the light and the dark surface. The fourth headline
   figure stays neutral on purpose — a fourth hue cannot clear those floors,
   and Claim Billed Value is the baseline the other three are read against.

   Every accent sits beside its own bold label and its printed number, so
   colour is never the only channel. The same hexes drive the Excel and PDF
   exports (see backend/pts_export.py), so screen and print agree. */
#view-pts-reports,
#view-pts-dashboard {
  --rep-billed: var(--text);
  --rep-paid: #1baf7a;
  --rep-open: #eb6834;
  --rep-expected: #2a78d6;
  --rep-negative: #c0392b;
  --rep-band: var(--primary);
  --rep-band-text: #fff;         /* 6.5:1 on the light band */
  --rep-heat: 42, 120, 214;      /* sequential blue, light -> dark */
  --rep-heat-max: .24;
}
[data-theme="dark"] #view-pts-reports,
[data-theme="dark"] #view-pts-dashboard {
  /* The dark theme's teal is a light step, so the band takes dark ink rather
     than white — white on it measures 3.3:1, short of what 11px needs. */
  --rep-band-text: #10201f;      /* 5.1:1 on the dark band */
  --rep-paid: #199e70;
  --rep-open: #d95926;
  --rep-expected: #3987e5;
  --rep-negative: #e66767;
  --rep-heat: 57, 135, 229;
  --rep-heat-max: .34;
}

/* ---------- what you are looking at ---------- */
.pts-report-status {
  font-size: calc(11.5px * var(--ui-font-scale, 1));
  color: var(--text-muted);
  margin: 0 0 12px;
  padding: 8px 12px;
  border-left: 3px solid var(--success);
  background: var(--surface-2);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.pts-report-status strong { color: var(--text); }
.pts-report-status.is-empty { border-left-color: var(--warning); }

.pts-filter-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px 18px;
  margin-bottom: 16px;
}
.pts-filter-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px 16px;
}
.pts-filter-card .pts-field { margin-bottom: 0; }
.pts-filter-card select,
.pts-filter-card input[type="date"],
.pts-filter-card input[type="number"],
.pts-filter-card input[type="text"] {
  width: 100%;
  padding: 7px 9px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text);
  font-family: inherit;
  font-size: calc(11.5px * var(--ui-font-scale, 1));
}
.pts-filter-card select[multiple] { padding: 4px; min-height: 74px; }
.pts-filter-card select[multiple] option { padding: 2px 5px; }

.pts-filter-dims {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px 16px;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--divider);
}
.pts-dim-count {
  font-size: calc(9.5px * var(--ui-font-scale, 1));
  font-weight: 500;
  color: var(--primary);
  margin-left: 5px;
  text-transform: none;
  letter-spacing: 0;
}
/* The count is worth a second look once another dimension has cut the list
   down — it is the difference between "137 payers" and "the 30 payers this
   facility actually bills". The dot carries no meaning on its own; the
   number beside it is the message. */
.pts-dim-count.is-narrowed {
  color: var(--rep-open, #EB6834);
  font-weight: 700;
}
.pts-dim-count.is-narrowed::after {
  content: " ●";
  font-size: calc(7px * var(--ui-font-scale, 1));
  vertical-align: middle;
}

/* A pack tab whose report came back with nothing in it. Marked, not hidden:
   an empty report is a fact about the scope, and worth seeing. */
.pts-pack-tab.is-empty .pts-pack-name { opacity: .55; }
.pts-pack-tab.is-empty .pts-pack-dot { background: var(--rep-open, #EB6834); }

/* ---------- dimension pickers ---------- */
/* Checkboxes, not a multi-select: a multi-select needs a modifier key to add
   a second value and throws the rest away on a plain click, which made
   choosing one facility look like it had locked out the others. */
.pts-dim {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  padding: 10px;
}
.pts-dim.is-active { border-color: var(--primary); }
.pts-dim-head {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin: 0 0 7px;
}
.pts-dim-title {
  font-size: calc(10.5px * var(--ui-font-scale, 1));
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.pts-dim-picked {
  margin-left: auto;
  font-size: calc(10px * var(--ui-font-scale, 1));
  font-weight: 700;
  color: var(--primary);
}
.pts-dim-search {
  width: 100%;
  font-size: calc(11px * var(--ui-font-scale, 1));
  padding: 5px 7px;
  margin-bottom: 6px;
}
.pts-dim-list {
  max-height: 190px;
  overflow-y: auto;
  border: 1px solid var(--divider);
  border-radius: var(--radius-sm, 4px);
}
.pts-dim-opt,
.pts-dim-all {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 4px 7px;
  font-size: calc(11.5px * var(--ui-font-scale, 1));
  cursor: pointer;
}
/* "Select all" rides at the top of the list rather than under it, so it is
   still reachable after scrolling a hundred payers. Half-ticked when only
   some are chosen, which is the state you are in most of the time. */
.pts-dim-all {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--surface);
  border-bottom: 1px solid var(--divider);
  font-weight: 600;
  color: var(--text-muted);
}
.pts-dim-all:hover { color: var(--text); }
.pts-dim-all input { margin: 0; flex: none; }
.pts-dim-all input:disabled + .pts-dim-name { opacity: .5; }
.pts-dim-opt:nth-child(even) { background: var(--surface-alt, rgba(0, 0, 0, .02)); }
.pts-dim-opt:hover { background: var(--hover, rgba(0, 0, 0, .05)); }
.pts-dim-opt input { margin: 0; flex: none; }
.pts-dim-name {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* The count is records inside the period on the scope bar. A value with none
   is still real data and still selectable — it just has nothing this month,
   which is the single most common reason a report comes back blank. */
.pts-dim-n {
  flex: none;
  font-size: calc(10.5px * var(--ui-font-scale, 1));
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}
.pts-dim-opt.is-empty .pts-dim-name { opacity: .55; }
.pts-dim-opt.is-empty .pts-dim-n { color: var(--rep-open, #EB6834); }
.pts-dim-actions {
  display: flex;
  gap: 10px;
  align-items: baseline;
  margin: 7px 0 0;
  font-size: calc(10.5px * var(--ui-font-scale, 1));
}
.pts-dim-legend { margin-left: auto; color: var(--text-muted); font-size: calc(10px * var(--ui-font-scale, 1)); }

/* ---------- tabs ---------- */
.pts-tabs {
  display: flex;
  align-items: center;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 18px;
}
.pts-tab {
  padding: 9px 16px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--text-muted);
  font-family: inherit;
  font-size: calc(12px * var(--ui-font-scale, 1));
  font-weight: 500;
  cursor: pointer;
}
.pts-tab:hover { color: var(--text); }
.pts-tab.is-active { color: var(--primary); border-bottom-color: var(--primary); font-weight: 600; }

/* ---------- headline block ---------- */
.pts-report-head { text-align: center; margin-bottom: 20px; }
.pts-report-title {
  font-size: calc(18px * var(--ui-font-scale, 1));
  font-weight: 700;
  letter-spacing: .34em;
  text-transform: uppercase;
  color: var(--text);
}
.pts-report-title.is-small { font-size: calc(13.5px * var(--ui-font-scale, 1)); letter-spacing: .26em; }
.pts-report-sub {
  font-size: calc(13px * var(--ui-font-scale, 1));
  color: var(--text);
  margin-top: 8px;
  font-weight: 500;
}
.pts-report-meta { font-size: calc(11.5px * var(--ui-font-scale, 1)); color: var(--text-muted); margin-top: 4px; }

/* ---------- KPI cards ---------- */
.pts-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  gap: 14px;
}
.pts-kpi {
  background: var(--surface);
  border: 1px solid var(--border);
  border-top: 3px solid var(--primary);
  border-radius: var(--radius-md);
  padding: 16px 18px;
  text-align: center;
  box-shadow: var(--shadow-sm);
}
.pts-kpi .kpi-label {
  display: block;
  font-size: calc(10px * var(--ui-font-scale, 1));
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 8px;
}
.pts-kpi .kpi-value {
  display: block;
  font-size: calc(23px * var(--ui-font-scale, 1));
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}
.pts-kpi .kpi-note { display: block; font-size: calc(11px * var(--ui-font-scale, 1)); color: var(--text-muted); margin-top: 6px; }
.pts-kpi { border-top-color: var(--rep-billed); }
.pts-kpi.is-collected { border-top-color: var(--rep-paid); }
.pts-kpi.is-collected .kpi-value { color: var(--rep-paid); }
.pts-kpi.is-open { border-top-color: var(--rep-open); }
.pts-kpi.is-open .kpi-value { color: var(--rep-open); }
.pts-kpi.is-expected { border-top-color: var(--rep-expected); }
.pts-kpi.is-expected .kpi-value { color: var(--rep-expected); }

/* The ratio strip sits under the money it is computed from. Smaller figures
   on purpose: these qualify the four above rather than compete with them. */
.pts-kpis.is-ratios { margin-top: 12px; }
.pts-kpis.is-ratios .pts-kpi { padding: 12px 14px; }
.pts-kpis.is-ratios .kpi-value { font-size: calc(18px * var(--ui-font-scale, 1)); }
.pts-kpi.is-rate { border-top-color: var(--rep-paid); }
.pts-kpi.is-rate .kpi-value { color: var(--rep-paid); }
.pts-kpi.is-denial { border-top-color: var(--rep-negative); }
.pts-kpi.is-denial .kpi-value { color: var(--rep-negative); }
.pts-kpi.is-dso { border-top-color: var(--rep-open); }
.pts-kpi.is-dso .kpi-value { color: var(--rep-open); }
/* A ratio with no denominator prints as an em dash, muted, so it never
   reads as a measured zero. */
.pts-kpi .kpi-value.is-none { color: var(--text-muted); font-weight: 600; }

/* ---------- per-bucket expected rate ---------- */
.pts-tier-row { margin-top: 14px; }
.pts-tier-label {
  font-size: calc(11px * var(--ui-font-scale, 1));
  font-weight: 600;
  color: var(--text-muted);
  margin: 0 0 8px;
  display: flex;
  gap: 10px;
  align-items: baseline;
}
.pts-tier-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
}
.pts-tier-fields label {
  display: block;
  font-size: calc(11px * var(--ui-font-scale, 1));
  color: var(--text-muted);
  margin-bottom: 4px;
}
.pts-tier-fields input { width: 100%; }

/* The roll-up row standing in for the tail of a long breakdown. Italic and
   muted so it never reads as a real group with that name. */
.pts-report-table tr.pts-other-row td { font-style: italic; color: var(--text-muted); }
/* The comparison block, ruled off the way the period block is. */
.pts-report-table .pts-c-compare { border-left: 2px solid var(--border); }
.pts-report-table td.is-up { color: var(--rep-paid); }
.pts-report-table td.is-down { color: var(--rep-negative); }

/* ---------- breakdown table ---------- */
.pts-report-table {
  font-size: calc(11.5px * var(--ui-font-scale, 1));
  font-variant-numeric: tabular-nums;   /* columns of money must line up */
  border-collapse: separate;
  border-spacing: 0;
}
/* The header band is the same teal the workbook and the PDF use, so a report
   read on screen and the same report printed are recognisably one thing. */
.pts-report-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--rep-band);
  color: var(--rep-band-text);
  font-size: calc(10.5px * var(--ui-font-scale, 1));
  font-weight: 600;
  letter-spacing: .01em;
  padding: 9px 10px;
  border: 0;
  white-space: normal;
}
/* A wide pivot scrolls sideways; the row it belongs to has to stay put. */
.pts-report-table tbody td.pts-c-label {
  position: sticky;
  left: 0;
  z-index: 1;
  background-color: var(--surface);
  font-weight: 500;
}
/* background-COLOR, not the shorthand: the heat wash below is a
   background-image, and the shorthand would reset it on every other row. */
.pts-report-table tbody tr:nth-child(even) td { background-color: var(--surface-2); }
/* Where the period block ends and the row totals begin. */
.pts-report-table .pts-c-split { border-left: 2px solid var(--rep-band); }
.pts-report-table td.is-negative { color: var(--rep-negative); }
/* Sequential wash on the period cells — the value is printed in every one of
   them, so the colour is a second reading of the number, never the only one. */
.pts-report-table td.pts-heat {
  background-image: linear-gradient(
    rgba(var(--rep-heat), calc(var(--heat, 0) * var(--rep-heat-max))),
    rgba(var(--rep-heat), calc(var(--heat, 0) * var(--rep-heat-max))));
}
.pts-report-table th.pts-col-num, .pts-report-table td.pts-col-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.pts-report-table tbody tr:hover td { background-color: var(--surface-3); }
.pts-report-table tr.pts-total-row td {
  font-weight: 700;
  background-color: var(--surface-3);
  border-top: 2px solid var(--rep-band);
  border-bottom: 0;
}
.pts-report-table tr.pts-total-row td.pts-c-label { background-color: var(--surface-3); }
.pts-report-note {
  margin-top: 14px;
  font-size: calc(11px * var(--ui-font-scale, 1));
  color: var(--text-muted);
  line-height: 1.7;
}
.pts-report-note strong { color: var(--text); }

.pts-report-empty {
  background: var(--surface);
  border: 1px dashed var(--border);
  border-radius: var(--radius-md);
  padding: 34px 20px;
  text-align: center;
  color: var(--text-muted);
  font-size: calc(12px * var(--ui-font-scale, 1));
}


/* ---------- export picker ---------- */
.pts-export-panel {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  padding: 12px 14px;
  margin: 12px 0 4px;
}
.pts-export-head {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: calc(11.5px * var(--ui-font-scale, 1));
  margin-bottom: 10px;
}
.pts-export-count { font-size: calc(11px * var(--ui-font-scale, 1)); color: var(--text-muted); }
.pts-export-count.is-empty { color: var(--rep-open); }
.pts-link {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-size: calc(11px * var(--ui-font-scale, 1));
  color: var(--primary);
  cursor: pointer;
  text-decoration: underline;
}
.pts-link:hover { color: var(--primary-hover); }
.pts-export-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 4px 10px;
  max-height: 220px;
  overflow-y: auto;
  padding-bottom: 4px;
}
.pts-export-item {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 4px 6px;
  border-radius: var(--radius-sm);
  font-size: calc(11.5px * var(--ui-font-scale, 1));
  color: var(--text);
  cursor: pointer;
}
.pts-export-item:hover { background: var(--surface-3); }
/* Shown in place of the ratio strip on a payments report, which has no
   billed figure for a rate to be a share of. */
.pts-rep-cashnote {
  grid-column: 1 / -1;
  margin: 0;
  padding: 12px 14px;
  font-size: calc(11.5px * var(--ui-font-scale, 1));
  line-height: 1.5;
  color: var(--text-muted);
  background: var(--surface-2);
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
}

.pts-export-section {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 12px 0 4px;
  font-size: calc(10px * var(--ui-font-scale, 1));
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--text-muted);
}
.pts-export-section:first-child { margin-top: 0; }
.pts-export-section > span { flex: 0 0 auto; }
.pts-export-all {
  margin-left: auto;
  padding: 1px 7px;
  font: inherit;
  font-size: calc(9.5px * var(--ui-font-scale, 1));
  color: var(--primary);
  background: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
}
.pts-export-all:hover { border-color: var(--primary); }
.pts-export-item input { accent-color: var(--primary); flex: 0 0 auto; }
.pts-export-no {
  flex: 0 0 auto;
  min-width: 17px;
  height: 17px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--surface-3);
  font-size: calc(9.5px * var(--ui-font-scale, 1));
  font-weight: 600;
  color: var(--text-muted);
}
.pts-export-name { flex: 1 1 auto; line-height: 1.25; }

/* The split row sits between the report picker and the download buttons,
   because that is the order the decision is made in: which reports, then
   whether each facility gets its own set, then take the files. */
.pts-export-split {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 12px;
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--divider);
}
.pts-export-split-toggle {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: calc(11.5px * var(--ui-font-scale, 1));
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
}
.pts-export-split-toggle input { accent-color: var(--primary); }
.pts-select-sm {
  width: auto;
  min-width: 150px;
  padding: 4px 8px;
  font-size: calc(11px * var(--ui-font-scale, 1));
}
.pts-select-sm:disabled { opacity: .5; cursor: not-allowed; }
.pts-export-split .pts-hint { flex: 1 1 100%; margin: 0; }

.pts-export-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--divider);
}
.pts-export-actions .pts-hint { flex: 1 1 220px; margin: 0; }

/* ---------- printable footer ---------- */
.pts-report-footer {
  margin-top: 18px;
  padding-top: 10px;
  border-top: 1px solid var(--divider);
  font-size: calc(10.5px * var(--ui-font-scale, 1));
  color: var(--text-faint);
  letter-spacing: .02em;
}

/* ---------- printing the page itself ----------
   The PDF export is the good way to print a report; this is the fallback for
   someone who just hits Ctrl+P. Everything that is chrome comes off, the
   heading block and the table stay, and the wash prints as tone. */
@media print {
  .sidebar, .topbar-actions, .pts-pack, .pts-pack-blurb,
  .pts-scope-bar, .pts-filter-card, .pts-tabs, .banner,
  .pts-export-panel { display: none !important; }
  .pts-tab-panel[hidden] { display: block !important; }
  #view-pts-reports { --rep-heat-max: .18; }
  .pts-report-table thead th {
    position: static;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .pts-report-table td.pts-heat, .pts-kpi {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .pts-report-table tbody td.pts-c-label { position: static; }
  .table-scroll { overflow: visible !important; }
  .pts-report-footer { position: fixed; bottom: 0; left: 0; right: 0; }
}

/* ---------- charting ---------- */
/* Colour comes down with the data, already resolved for this surface, so the
   only palette here is the chart's chrome: ink for text, hairlines for the
   grid, and the surface itself for the gaps between marks. */
.pts-viz-deck {
  display: grid;
  grid-template-columns: 1fr;
  align-items: start;      /* each card hugs its chart, never its neighbour */
  gap: 18px;
}
@media (min-width: 1180px) {
  .pts-viz-deck { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* A heatmap and a stacked column both want the full width; a bar chart of
     ten facilities does not. */
  .pts-viz-deck .pts-viz-card:has(.pts-viz-cell) { grid-column: 1 / -1; }
}
.pts-viz-card {
  margin: 0;
  padding: 16px 18px 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  min-width: 0;
}
/* The form picker. Only the readings that are honest for this chart's data
   appear, so the row is short and every button is a real option. */
.pts-viz-pick {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  margin-bottom: 10px;
}
.pts-viz-form {
  appearance: none;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: calc(10.5px * var(--ui-font-scale, 1));
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 999px;
  cursor: pointer;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.pts-viz-form:hover { color: var(--text); border-color: var(--text-muted); }
.pts-viz-form.is-on {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}
.pts-viz-kept {
  margin-left: auto;
  font-size: calc(10px * var(--ui-font-scale, 1));
  color: var(--text-muted);
  font-style: italic;
}

.pts-viz-head { margin-bottom: 2px; }
.pts-viz-title {
  margin: 0;
  font-size: calc(12.5px * var(--ui-font-scale, 1));
  font-weight: 700;
  color: var(--text);
  letter-spacing: .01em;
}
.pts-viz-sub { margin: 3px 0 0; font-size: calc(11px * var(--ui-font-scale, 1)); color: var(--text-muted); }
.pts-viz-note {
  margin: 8px 0 0;
  font-size: calc(10.5px * var(--ui-font-scale, 1));
  color: var(--text-muted);
  line-height: 1.45;
}
.pts-viz-fail {
  margin: 0;
  padding: 22px 0;
  text-align: center;
  font-size: calc(11.5px * var(--ui-font-scale, 1));
  color: var(--text-muted);
}

/* The legend is always present at two or more series. The swatch carries the
   identity; the text stays in ink. */
.pts-viz-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin: 9px 0 2px;
  font-size: calc(11px * var(--ui-font-scale, 1));
  color: var(--text-muted);
}
.pts-viz-key { display: inline-flex; align-items: center; gap: 6px; }
.pts-viz-key i {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  flex: none;
}

/* Width comes from the card, height from the chart's own viewBox. Stated
   here rather than left to the width/height attributes, because a blanket
   `svg { width: 16px }` icon rule in an author stylesheet outranks a
   presentation attribute and would draw every chart at icon size. */
.pts-viz-svg { display: block; overflow: visible; width: 100%; height: auto; }
/* Recessive: one hairline, no domain rule, no tick marks of its own. */
.pts-viz-grid { stroke: var(--divider); stroke-width: 1; shape-rendering: crispEdges; }
.pts-viz-tick { font-size: calc(9.5px * var(--ui-font-scale, 1)); fill: var(--text-muted); }
.pts-viz-cat { font-size: calc(10.5px * var(--ui-font-scale, 1)); fill: var(--text); }
.pts-viz-value { font-size: calc(10px * var(--ui-font-scale, 1)); fill: var(--text-muted); font-weight: 600; }
.pts-viz-axis-label { font-size: calc(10px * var(--ui-font-scale, 1)); fill: var(--text-muted); }

/* The reference line is context, so it is dashed and unsaturated — it must
   not read as a series. */
.pts-viz-ref { stroke: var(--text-muted); stroke-width: 1; stroke-dasharray: 4 3; opacity: .75; }
.pts-viz-ref-label { font-size: calc(9.5px * var(--ui-font-scale, 1)); fill: var(--text-muted); font-weight: 600; }

.pts-viz-stem { stroke: var(--divider); stroke-width: 2; stroke-linecap: round; }
.pts-viz-stem.is-move { stroke: var(--text-muted); stroke-width: 2.5; opacity: .5; }

.pts-viz-mark { cursor: default; transition: opacity .12s ease; }
.pts-viz-mark:hover { opacity: .82; }
/* A surface-coloured ring keeps overlapping marks apart without a second hue. */
.pts-viz-mark.is-ringed { stroke: var(--surface); stroke-width: 2; }
/* The lit and shadowed faces of an extruded mark. They belong to the mark in
   front of them, which is what the reader points at, so they take no pointer
   of their own — otherwise the tooltip flickers as the cursor crosses an edge
   that is part of the same bar. */
.pts-viz-facet { pointer-events: none; }

.pts-viz-line { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.pts-viz-area { fill-opacity: .12; }

.pts-viz-cell { cursor: default; }
.pts-viz-cell:hover { stroke: var(--text); stroke-width: 1.5; }
.pts-viz-cellv { font-size: calc(9.5px * var(--ui-font-scale, 1)); fill: var(--text); font-variant-numeric: tabular-nums; }
/* Past the middle of the ramp the wash is dark enough that ink on it fails
   contrast, so the number flips to the surface colour. */
.pts-viz-cellv.is-inverse { fill: #fff; }

.pts-viz-tip {
  position: fixed;
  z-index: 9000;
  pointer-events: none;
  max-width: 280px;
  padding: 8px 10px;
  border-radius: var(--radius-sm, 5px);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-md, 0 6px 18px rgba(0, 0, 0, .18));
  font-size: calc(11px * var(--ui-font-scale, 1));
  line-height: 1.45;
  color: var(--text);
}
.pts-viz-tip-sub { color: var(--text-muted); font-size: calc(10.5px * var(--ui-font-scale, 1)); }

@media print {
  .pts-viz-deck { grid-template-columns: 1fr; }
  .pts-viz-card { break-inside: avoid; box-shadow: none; }
  .pts-viz-tip { display: none !important; }
}

/* ---------- plain-language captions on the KPI cards ----------
   One sentence a reader with no billing background can act on, under the
   figure. The technical note stays below it, smaller, and the formula is on
   hover behind the small "i". */
.pts-kpi .kpi-plain {
  display: block;
  margin-top: 8px;
  font-size: calc(12px * var(--ui-font-scale, 1));
  line-height: 1.4;
  color: var(--text);
  text-wrap: pretty;
}
.pts-kpi .kpi-plain + .kpi-note { margin-top: 4px; font-size: calc(10.5px * var(--ui-font-scale, 1)); }
.pts-kpi[title] { cursor: help; }
.pts-kpi .kpi-info {
  display: inline-grid;
  place-items: center;
  width: 13px;
  height: 13px;
  margin-left: 3px;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-size: calc(8.5px * var(--ui-font-scale, 1));
  font-weight: 700;
  font-style: italic;
  letter-spacing: 0;
  text-transform: none;
  vertical-align: 1px;
  opacity: .75;
}

/* ---------- what the tab dots mean ---------- */
.pts-pack-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  margin: -4px 0 8px;
  font-size: calc(11px * var(--ui-font-scale, 1));
  color: var(--text-muted);
}
.pts-pack-legend span { display: inline-flex; align-items: center; gap: 6px; }
.pts-pack-legend .pts-pack-dot { display: inline-block; }
.pts-pack-dot.is-legend-ready { background: var(--success); border-color: var(--success); }
.pts-pack-dot.is-legend-empty { background: var(--rep-open, #eb6834); border-color: var(--rep-open, #eb6834); }

/* ---------- advanced options, folded away ---------- */
.pts-advanced {
  margin-top: 16px;
  border-top: 1px solid var(--border);
  padding-top: 12px;
}
.pts-advanced > summary {
  cursor: pointer;
  font-size: calc(12.5px * var(--ui-font-scale, 1));
  font-weight: 700;
  color: var(--text);
  list-style-position: outside;
}
.pts-advanced > summary .pts-hint { display: block; font-weight: 400; margin-top: 2px; }
.pts-advanced[open] > summary { margin-bottom: 12px; }
.pts-names-row { margin-top: 14px; display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; }

/* ---------- reversal note under a breakdown ---------- */
.pts-reversal-note { color: var(--rep-negative, #c0392b); font-weight: 600; }

/* ---------- name clean-up window ---------- */
.pts-names-back {
  position: fixed;
  inset: 0;
  z-index: 900;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(11, 18, 32, .52);
}
.pts-names-frame {
  width: min(860px, 100%);
  max-height: 100%;
  overflow: auto;
  padding: 18px 20px 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: 0 18px 48px rgba(11, 18, 32, .3);
}
.pts-names-head { display: flex; align-items: flex-start; gap: 16px; margin-bottom: 8px; }
.pts-names-head > div { flex: 1 1 auto; }
.pts-names-head h3 { margin: 0 0 4px; font-size: calc(15px * var(--ui-font-scale, 1)); }
.pts-names-head p { margin: 0; font-size: calc(12px * var(--ui-font-scale, 1)); color: var(--text-muted); }
.pts-names-field { margin-top: 16px; }
.pts-names-field h4 { margin: 0 0 6px; font-size: calc(13px * var(--ui-font-scale, 1)); }
.pts-names-table code,
.pts-names-rules code {
  display: inline-block;
  margin: 1px 4px 1px 0;
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--surface-2, rgba(127, 127, 127, .12));
  font-size: calc(11.5px * var(--ui-font-scale, 1));
}
.pts-names-rules { margin: 0; padding-left: 18px; font-size: calc(12.5px * var(--ui-font-scale, 1)); }
.pts-names-rules li { margin: 3px 0; }
.pts-names-form { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.pts-names-form input { flex: 1 1 200px; min-width: 0; }
