/* ============================================================================
   Staffing & PAF Report module
   Most Staffing pages use the generic chrome from main.css; this file holds
   only the bits unique to Staffing (KPI sparkline, Timeline pivot table) plus
   the chip-bar + multi-panel styles previously borrowed from cost-eac.css.
   Owning these locally keeps Staffing self-contained — no cross-module CSS
   dependency.
   ============================================================================ */


/* ── Staffing Overview dashboard ─────────────────────────────────────────── */

/* Page fills the viewport on tall screens but allows scrolling when content
   genuinely needs more room (e.g. 100% zoom + filter bar open + smaller
   monitor). The old hard `height: 100vh` + `overflow: hidden` would shrink
   the chart row below readable height and clip the Staffing Health
   .sov-health-nums under the card's overflow:hidden. */
.sov-shell .page-shell { min-height: 100vh; }
.sov-shell .page-footer { flex-shrink: 0; }

/* page-body becomes a flex column that fills all space between toolbar and footer */
.sov-body {
  display: flex !important;
  flex-direction: column;
  padding: 8px 16px 8px !important;
  gap: 8px;
}

/* ── New 6-tile KPI row ───────────────────────────────────────────────────── */
/* gap matches .sov-charts-row so the 6 tiles' 2nd and 4th seams land exactly on
   the chart rows' 1/3 and 2/3 seams (they were 0.33px off at gap:10px). */
.sov-kpi-row {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}
.sov-kpi-tile {
  flex: 1;
  min-width: 0;
  background: #fff;
  border: 1px solid var(--kbr-border);
  border-radius: 8px;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  position: relative;
  box-shadow: 0 1px 4px rgba(0,0,0,.04);
}
.sov-kpi-dot {
  position: absolute;
  top: 10px; right: 10px;
  width: 8px; height: 8px;
  border-radius: 50%;
}
.sov-kpi-label  { font-size: 10px; font-weight: 700; letter-spacing: 0.06em; color: #6b7a99; text-transform: uppercase; margin-bottom: 2px; }
.sov-kpi-value  { font-size: 30px; font-weight: 800; color: var(--kbr-navy); line-height: 1.1; letter-spacing: -0.5px; margin-bottom: 2px; }
.sov-kpi-badge  { min-height: 18px; margin-bottom: 2px; }
.sov-kpi-caption{ font-size: 11px; color: #9aa5be; }
.sov-chart-meta { font-size: 11px; color: #9aa5be; white-space: nowrap; }

/* Status badges */
.sov-badge-ok   { display: inline-block; background: #dcfce7; color: #166534; font-size: 10px; font-weight: 700; padding: 1px 6px; border-radius: 10px; }
.sov-badge-warn { display: inline-block; color: #94a3b8; font-size: 11px; font-weight: 600; }
.sov-badge-gap  { display: inline-block; color: #6366f1; font-size: 11px; font-weight: 600; }

/* ── Staffing Health gauge ───────────────────────────────────────────────── */
.sov-gauge-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
  margin: 4px 0;
}
.sov-gauge-chart {
  width: 140px;
  height: 72px; /* half of a 140px circle */
  position: relative;
}
.sov-gauge-label {
  font-size: 26px;
  font-weight: 800;
  color: var(--kbr-navy);
  margin-top: -8px;
  line-height: 1;
}
.sov-gauge-sub { font-size: 10px; color: #9aa5be; margin-bottom: 8px; }
.sov-health-nums {
  display: flex;
  justify-content: space-around;
  width: 100%;
  padding: 8px 0;
  border-top: 1px solid var(--kbr-border);
  margin-top: 4px;
}
.sov-hn { text-align: center; }
.sov-hn-lbl { font-size: 10px; margin-bottom: 2px; }
.sov-hn-val { font-size: 22px; font-weight: 800; color: var(--kbr-navy); line-height: 1; }

/* KPI tile strip — shrinks but doesn't grow */
.sov-strip-wrap {
  display: flex;
  gap: 12px;
  flex-shrink: 0;
  flex-wrap: wrap;
}
.sov-group { display: flex; flex-direction: column; }
.sov-group-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: #6b7a99;
  text-transform: uppercase;
  margin-bottom: 5px;
}
.sov-tiles { display: flex; gap: 8px; }

/* Individual KPI tile */
.sov-tile {
  background: #fff;
  border: 1px solid var(--kbr-border);
  border-radius: 8px;
  padding: 10px 14px 0;
  display: flex;
  flex-direction: column;
  min-width: 110px;
  flex: 1;
  box-shadow: 0 1px 4px rgba(0,0,0,.04);
  overflow: hidden;
}
.sov-tile-hdr {
  display: flex;
  align-items: baseline;
  margin-bottom: 3px;
}
.sov-tile-name  { font-size: 14px; font-weight: 700; color: var(--kbr-navy); }
.sov-todate-lbl { font-size: 10px; color: #9aa5be; }

/* Values row: big total on the left, smaller to-date pushed to the right
   so it lines up vertically with the "to date" label in .sov-tile-foot.
   `margin-top: auto` pushes this row (and the foot + colored bar that
   follow it) to the bottom of the tile, so the "Planned/Filled/..." name
   sits at the top with whitespace beneath, and the numbers + labels +
   bar sit flush against the bottom of the card. */
.sov-tile-vals  {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-top: auto;
  margin-bottom: 6px;
}
.sov-total {
  font-size: 28px; font-weight: 800; color: var(--kbr-navy);
  line-height: 1; letter-spacing: -0.5px;
}
.sov-todate { font-size: 20px; font-weight: 700; color: #6b7a99; line-height: 1; }

.sov-td-indigo { color: #6366f1; }

/* Foot row: "total" on the left under the big number, "to date" on the
   right under the small number. Same baseline so the two labels line up. */
.sov-tile-foot {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-top: 2px;
  margin-bottom: 6px;
}
.sov-tile-sub  { font-size: 10px; color: #9aa5be; }
.sov-tile-bar  { height: 3px; margin: auto -14px 0; border-radius: 0 0 8px 8px; }

/* FTE tile with sparkline */
.sov-fte-tile { min-width: 130px; }
.sov-fte-tile .sov-tile-name { margin-bottom: 2px; }
.sov-fte-tile .sov-total     { margin-bottom: 4px; }
.sov-fte-tile .kpi-spark     { flex: 1; min-height: 28px; margin-bottom: 6px; }

/* Chart area fills all remaining height */
.sov-charts-area {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Each chart row takes equal share of the charts area. min-height keeps
   the cards readable at 100% zoom — without it the row would happily
   shrink to nothing as the filter bar / KPI tiles take more vertical
   space, leaving a squeezed timeline chart and the Staffing Health
   card's .sov-health-nums clipped under .sov-card{overflow:hidden}.

   Grid, not flex, and both rows share the same 3 tracks: `flex: 2` splits the
   space left AFTER the gaps, so a flex:2 card is (W-g)*2/3 wide while the two
   flex:1 cards below it plus their gap span (W-2g)*2/3+g. Those differ by g/3,
   which is the 2/3-column seam that QA marked as misaligned. Equal grid tracks
   put the seam in the same place on every row by construction. */
.sov-charts-row {
  flex: 1;
  min-height: 320px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}
.sov-card-wide { grid-column: span 2; }

/* Cards inside chart rows stretch to fill the row */
.sov-card {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  margin: 0 !important;
}
.sov-card h4 { flex-shrink: 0; margin-bottom: 8px; }

/* Chart box fills remaining card height */
.sov-chart-box {
  flex: 1;
  min-height: 0;
  position: relative;
}
.sov-chart-box canvas {
  position: absolute;
  inset: 0;
  width: 100% !important;
  height: 100% !important;
}

/* Opt-in horizontal scroll for a long weekly series (FTE Forecast). Only the box
   carrying .sov-chart-scroll is affected — the other charts on this page keep
   filling their panel exactly as before.
   .sov-chart-inner is the positioned ancestor the canvas absolutely fills, and it
   MUST keep a definite height: Chart.js runs maintainAspectRatio:false here, and a
   content-derived height makes the canvas grow on every resize observation. */
.sov-chart-scroll {
  overflow-x: auto;
  overflow-y: hidden;
}
.sov-chart-scroll > .sov-chart-inner {
  position: relative;
  height: 100%;
  min-width: 100%;   /* short series still fill the panel; JS widens past it */
}

/* Health bar card layout */
.sov-health-bars { display: flex; flex-direction: column; gap: 14px; margin-top: 4px; }
.sov-hbar-hdr {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: var(--kbr-navy);
  font-weight: 600;
  margin-bottom: 5px;
}
.sov-hbar-pct { font-weight: 800; }
.sov-hbar-track { height: 8px; background: #e8ecf3; border-radius: 4px; overflow: hidden; }
.sov-hbar-fill  { height: 100%; border-radius: 4px; transition: width 0.5s ease; }
.sov-health-note {
  font-size: 11px;
  color: #6b7a99;
  margin-top: auto;
  padding-top: 12px;
  margin-bottom: 0;
  border-top: 1px solid var(--kbr-border);
}

/* ── PAF Details extra filter bar controls ───────────────────────────────── */
.det-name-wrap { display: flex; }
.det-name-input {
  height: 34px;
  min-width: 150px;
  padding: 0 10px;
  border: 1px solid var(--kbr-border);
  border-radius: 4px;
  background: #fff;
  font-size: 13px;
  color: var(--kbr-navy);
  outline: none;
}
.det-name-input:focus { border-color: var(--kbr-teal-dark); box-shadow: 0 0 0 2px rgba(8,145,178,.12); }
.det-name-input::placeholder { color: #9aa5be; }

/* ── Chip bar (Mode / Period / Measure / Group by / Graph by / PAF quick
   filters). Originally lived in cost-eac.css; copied here so Staffing pages
   don't need to link that file. Cost-EAC keeps its own copy for its pages. */
.ce-chip-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 6px 0 4px;
}
.ce-chip-label {
  font-size: 11px;
  font-weight: 600;
  color: #6b7280;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  margin-right: 2px;
}
.ce-chip {
  padding: 3px 12px;
  background: #fff;
  border: 1.5px solid var(--kbr-border);
  border-radius: 12px;
  color: #475569;
  font-size: 11.5px;
  font-weight: 500;
  cursor: pointer;
  user-select: none;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.ce-chip:hover { background: #f0f4fb; border-color: var(--kbr-navy); color: var(--kbr-navy); }
.ce-chip.active {
  background: var(--kbr-navy);
  border-color: var(--kbr-navy);
  color: #fff;
}
.ce-chip.disabled {
  opacity: 0.4;
  pointer-events: none;
  cursor: not-allowed;
}
.ce-chip-divider {
  width: 1px;
  height: 18px;
  background: var(--kbr-border);
  margin: 0 4px;
  align-self: center;
}
.ce-chip-spacer { flex: 1; }

/* ── Timeline multi-panel (Graph-by) cards — header strip + canvas wrap. */
.ce-tl-panel {
  background: #fff;
  border: 1px solid var(--kbr-border);
  border-radius: 8px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: 280px;
}
.ce-tl-panel-hdr {
  padding: 5px 12px;
  background: var(--kbr-teal-dark);
  color: #fff;
  font-size: 11.5px;
  font-weight: 700;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.tl-view-toggle {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.45);
  color: #fff;
  border-radius: 4px;
  padding: 1px 6px;
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
}
.tl-view-toggle:hover { background: rgba(255, 255, 255, 0.18); }

/* Per-panel Chart/Table toggle — sits inside .ce-tl-panel-hdr on the
   teal-dark background, mirrors the main #tlSingleCard toggle pattern. */
.tl-mini-view-toggle {
  display: inline-flex;
  border: 1px solid rgba(255, 255, 255, 0.45);
  border-radius: 4px;
  overflow: hidden;
  background: transparent;
}
.tl-mini-toggle-btn {
  background: transparent;
  border: none;
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  line-height: 1.4;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.tl-mini-toggle-btn:hover { background: rgba(255, 255, 255, 0.18); }
.tl-mini-toggle-btn.active {
  background: #fff;
  color: var(--kbr-teal-dark);
}
.tl-mini-toggle-btn + .tl-mini-toggle-btn { border-left: 1px solid rgba(255, 255, 255, 0.35); }
.tl-mini-toggle-btn.active + .tl-mini-toggle-btn,
.tl-mini-toggle-btn + .tl-mini-toggle-btn.active { border-left-color: transparent; }
.tl-mini-toggle-btn i { font-size: 11px; }

.ce-tl-table-wrap {
  padding: 8px 10px;
  overflow: auto;
  flex: 1;
  min-height: 240px;
}

.ce-tl-canvas-wrap {
  flex: 1;
  position: relative;
  padding: 6px 10px 8px;
  min-height: 240px;
  display: flex;
  flex-direction: column;
}

/* Filter-bar labels render as authored ("Project ID", "Execution Center",
   "CBS") rather than uppercased. The strings already carry the right casing,
   and forcing caps also flattened the acronyms into the same shape as the
   words. Lives here rather than in main.css's .fb-label so only the Staffing
   pages change — main.css is shared with every other module. */
.fb-label { text-transform: none; }

/* Reporting Date hard right instead of centred. main.css pushes the first item
   left and adds a zero-width ::after with margin-left:auto as a stand-in third
   item, which splits the trailing slack and centres Reporting Date. Dropping
   that stand-in and giving the last item the auto margin sends it to the edge —
   the same trick .ce-footer uses on Cost. Scoped to Staffing so the other
   modules keep the centred layout. */
.page-footer.staffing-footer::after { content: none; }
.page-footer.staffing-footer .footer-item:last-child { margin-left: auto; }

/* Graph-by panel plot area: [frozen y scale][horizontal scroller][frozen y2].
   Only the middle column scrolls, so the scale numbers and the legend below
   stay put however far the bars are scrolled. */
.tl-panel-plot {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: stretch;
  padding: 8px 0;
}
.tl-panel-scroll {
  flex: 1;
  min-width: 0;
  overflow-x: auto;
  overflow-y: hidden;
}
/* Must keep a definite height: Chart.js runs maintainAspectRatio:false and a
   content-derived height makes the canvas grow on every resize observation. */
.tl-panel-inner {
  position: relative;
  height: 100%;
  min-width: 100%;   /* short ranges still fill the panel; JS widens past it */
}
.tl-panel-inner > canvas {
  position: absolute;
  inset: 0;
}

/* Tick labels are absolutely positioned from the rendered scale's pixel
   values, so this column only needs to be tall enough to hold them. */
.tl-panel-yaxis {
  position: relative;
  flex: none;
  width: 34px;
  font-size: 11px;
  color: #6b7a99;
}
.tl-panel-yaxis:empty { display: none; }
.tl-pa-tick {
  position: absolute;
  right: 4px;
  transform: translateY(-50%);
  white-space: nowrap;
}
.tl-pa-right .tl-pa-tick { right: auto; left: 4px; }

.tl-panel-legend {
  flex: none;
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 2px 12px;
  padding: 6px 2px 0;
}
.tl-panel-legend:empty { display: none; }

/* Per-panel "Loading…" overlay shown while progressive rendering waits
   for each panel's timeline response. Sits absolute over the canvas
   wrap; removed by the loadMultiPanel handler when the panel's data
   lands. */
.tl-panel-loading {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.85);
  color: #94a3b8;
  font-size: 12px;
  font-style: italic;
  pointer-events: none;
}

/* ── Timeline mini-table (Graph-by view-toggle → table view) ──────────────
   Non-sticky layout — the whole table scrolls uniformly. Labels (Series,
   Plan, Actual, Forecast) get a colored swatch in front so the row
   visually maps back to the chart series. */
.ce-tl-table-wrap {
  flex: 1;
  overflow: auto;
  padding: 10px 12px;
  min-height: 340px;
}
.tl-mini-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 13px;
}
.tl-mini-table th,
.tl-mini-table td {
  border-right: 1px solid var(--kbr-border);
  border-bottom: 1px solid var(--kbr-border);
  padding: 8px 12px;
  text-align: right;
  white-space: nowrap;
}
.tl-mini-table thead th {
  background-color: #f1f5f9;
  font-weight: 600;
  border-top: 1px solid var(--kbr-border);
}
.tl-mini-table tbody th.tl-mini-label,
.tl-mini-table tbody td.tl-mini-label,
.tl-mini-table thead th.tl-mini-label {
  text-align: left;
  font-weight: 600;
  background-color: #f1f5f9;
  border-left: 1px solid var(--kbr-border);
}
/* Colored swatch in front of Plan / Actual / Forecast labels — matches
   the chart series colors so the table reads as a legend. Filled by an
   inline style="background:..." in renderPanelTable so it picks up
   whatever palette the page is using. */
.tl-mini-dot {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 2px;
  margin-right: 8px;
  vertical-align: middle;
  flex-shrink: 0;
}

/* Sparkline below the value in Staffing KPI tiles. Flows in normal order
   (label → value → spark), so text never sits on top of the chart. */
.kpi-strip.has-spark .kpi {
  display: flex;
  flex-direction: column;
  padding-bottom: 4px;
}
.kpi-spark {
  display: block;
  width: 100%;
  height: 30px;
  margin-top: 4px;
  pointer-events: none;
}

/* ── Staffing Timeline combined chart+table layout ──────────────────────── */
.tl-combined {
  display: flex;
  overflow-x: hidden; /* clip horizontal outside scroll-body; allow vertical for inline table */
}

/* Sticky left column: empty spacer (chart height) + row labels */
.tl-sticky-labels {
  flex-shrink: 0;
  width: 110px;
  display: flex;
  flex-direction: column;
  background: #fff;
}
.tl-chart-gap { height: 340px; }
.tl-row-dot { display: inline-block; width: 10px; height: 10px; border-radius: 2px; flex-shrink: 0; margin-right: 6px; }
.tl-label-row {
  height: 30px;
  display: flex;
  align-items: center;
  padding: 0 10px;
  font-size: 11px;
  font-weight: 700;
  color: var(--kbr-navy);
  border-top: 1px solid var(--kbr-border);
  background: #fff;
  white-space: nowrap;
}

/* Shared scrollable area: chart canvas sits on top, table below */
.tl-scroll-body {
  flex: 1;
  overflow-x: auto;
  overflow-y: visible; /* allow inline table rows to grow vertically */
}
.tl-chart-wrap {
  height: 340px;
  /* width set dynamically by JS to periods × COL_WIDTH */
}

/* ── TIMELINE PIVOT TABLE ───────────────────────────────────────────────── */
.tl-pivot-wrap {
  overflow: auto;
  max-height: 65vh;
  border: 1px solid var(--kbr-border);
  border-radius: 4px;
  background: #fff;
}
/* Chart view: the inline table under the graph. Must stay overflow:visible so it
   shares .tl-scroll-body's horizontal scrollbar with the chart — that shared
   scroller is what keeps the period columns lined up under the bars, and giving
   this element its own overflow spawns a second, unsynced scrollbar.
   The unbounded row growth that used to push a scrollbar onto the whole PAGE is
   handled in JS instead: renderSinglePivot() ignores transpose in chart view, so
   the inline table is only ever the 3 measure rows. */
.tl-pivot-inline {
  overflow: visible;
  max-height: none;
  border: none;
  border-radius: 0;
  border-top: 1px solid var(--kbr-border);
}
/* Table view: standalone full scroll area (inherits base .tl-pivot-wrap) */
.tl-pivot-standalone {}
.tl-pivot-table {
  border-collapse: collapse;
  font-size: 12px;
  white-space: nowrap;
  min-width: 100%;
}
.tl-pivot-table thead { position: sticky; top: 0; z-index: 4; }
.pv-th {
  padding: 6px 10px;
  font-weight: 700;
  font-size: 11px;
  border-right: 1px solid rgba(255,255,255,0.2);
  border-bottom: 2px solid rgba(255,255,255,0.3);
}
.pv-dim-hdr {
  background: var(--kbr-navy);
  color: #fff;
  text-align: left;
  min-width: 110px;
  position: sticky;
  left: 0;
  z-index: 5;
}
.pv-measure-hdr {
  background: var(--kbr-navy);
  color: #fff;
  text-align: left;
  width: 80px;
  min-width: 80px;
}
.pv-period-hdr {
  background: var(--kbr-teal-dark);
  color: #fff;
  text-align: right;
  min-width: 62px; /* matches TL_COL_W; JS sets explicit width on each th */
}
.pv-total-hdr {
  background: var(--kbr-navy);
  color: #fff;
  text-align: right;
  min-width: 80px;
  position: sticky;
  right: 0;
  z-index: 5;
}
.pv-td {
  padding: 4px 10px;
  border-bottom: 1px solid #e8ecf3;
  border-right: 1px solid #e8ecf3;
}
.pv-dim-cell {
  font-weight: 600;
  color: var(--kbr-navy);
  background: #f4f6fa;
  text-align: left;
  vertical-align: top;
  position: sticky;
  left: 0;
  z-index: 2;
  border-right: 2px solid #c8d0e0;
}
.pv-measure-cell {
  color: #374151;
  background: #fafbfc;
  text-align: left;
  font-style: italic;
  font-size: 11px;
}

/* ── Frozen leading columns, two-dimension Group By (.pv-lead-2) ───────────
   Offsets must match DIM_COL_W (110) and MEASURE_COL_W (80) in timeline.js —
   the same constants the chart's left margin is derived from. Without a
   distinct offset per column every sticky cell pins to left:0 and they stack
   on top of one another as soon as the table scrolls sideways. Each needs an
   opaque background or the period cells show through underneath. */
.pv-lead-2 .pv-dim2-hdr,
.pv-lead-2 .pv-dim2-cell   { left: 110px; }
.pv-lead-2 .pv-measure-hdr { position: sticky; left: 220px; z-index: 5; }
.pv-lead-2 .pv-measure-cell{ position: sticky; left: 220px; z-index: 2; }

/* Grouped pivot under the chart: its own bounded scroll box, so a long nested
   table scrolls within the card instead of stretching the page. Overrides
   .tl-pivot-inline's overflow:visible — that shared-scroller trick keeps the
   period columns aligned under the bars, which only ever applied to the
   3-row ungrouped table. */
.tl-pivot-inline.tl-pivot-frozen {
  overflow: auto;
  max-height: 46vh;
}
.pv-num-cell {
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: #1e2a3a;
}
.pv-total-cell {
  text-align: right;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--kbr-navy);
  background: #eef1f8;
  border-left: 1px solid #c8d0e0;
  position: sticky;
  right: 0;
  z-index: 2;
}
.pv-even .pv-num-cell, .pv-even .pv-measure-cell { background: #fff; }
.pv-odd  .pv-num-cell, .pv-odd  .pv-measure-cell { background: #f8fafc; }
.pv-detail-row:hover .pv-num-cell,
.pv-detail-row:hover .pv-measure-cell { background: #eef3fb !important; }
.pv-subtotal-row td {
  background: #dde4f0 !important;
  font-weight: 700;
  color: var(--kbr-navy);
  border-top: 1px solid #b0bcce;
  border-bottom: 2px solid #b0bcce;
}
.pv-subtotal-label {
  text-align: left;
  font-weight: 700;
  color: var(--kbr-navy);
  padding-left: 14px !important;
  position: sticky;
  left: 0;
  z-index: 2;
  background: #dde4f0 !important;
}
.pv-grand-hdr td {
  background: var(--kbr-navy) !important;
  color: #fff !important;
  font-weight: 700;
  border-top: 2px solid #0e1f33;
}

/* Collapse/expand button inside dim cell */
.pv-collapse-btn {
  background: none;
  border: none;
  padding: 0 4px 0 0;
  cursor: pointer;
  font-size: 10px;
  color: var(--kbr-teal-dark);
  vertical-align: middle;
  line-height: 1;
}
.pv-collapse-btn:hover { color: var(--kbr-navy); }

/* Stacked graph-by section header */
.pv-stack-section { margin-bottom: 16px; }
.pv-stack-hdr {
  padding: 6px 10px;
  background: var(--kbr-navy);
  color: #fff;
  font-size: 12px;
  border-radius: 4px 4px 0 0;
}

/* ── TABLE TOOLBAR ─────────────────────────────────────────────────────── */
.tl-table-toolbar {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.tl-tb-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  font-size: 11px;
  font-weight: 500;
  border: 1px solid var(--kbr-border);
  border-radius: 4px;
  background: #fff;
  color: #374151;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.tl-tb-btn:hover { background: #f0f3f9; border-color: var(--kbr-teal-dark); }
.tl-tb-btn.active {
  background: var(--kbr-navy);
  color: #fff;
  border-color: var(--kbr-navy);
}
.tl-tb-sep {
  width: 1px;
  height: 20px;
  background: var(--kbr-border);
  margin: 0 2px;
}

/* ── GROUP ORDER BAR ───────────────────────────────────────────────────── */
.gb-order-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 0;
  flex-wrap: wrap;
  background: #f4f6fa;
  border-bottom: 1px solid var(--kbr-border);
}
/* Disabled combo option (e.g. Cumulative when Hours not selected) */
.tl-disabled { opacity: 0.45; pointer-events: none; }
.gb-order-tags { display: flex; flex-wrap: wrap; gap: 4px; }
.gb-order-tag {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 8px;
  background: #e8edf6;
  border: 1px solid #c0cce0;
  border-radius: 12px;
  font-size: 11px;
  color: var(--kbr-navy);
  font-weight: 600;
}
.gb-arrow {
  background: none;
  border: none;
  padding: 0 2px;
  cursor: pointer;
  font-size: 12px;
  color: var(--kbr-teal-dark);
  line-height: 1;
}
.gb-arrow:hover { color: var(--kbr-navy); }

/* PAF page: big-chart columns (Cost Type, WBS1) flex-fill to match
   the height of the stacked small-chart column beside them. */
.paf-big-col {
  display: flex;
  flex-direction: column;
}
.paf-big-col .card-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
}
.paf-big-col .card-panel .chart-box {
  flex: 1;
  height: 0;
}

/* Timeline Group-by legend — lives outside .tl-scroll-body so it stays visible
   no matter how far the chart is scrolled sideways. */
.tl-group-legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px 14px;
  padding: 14px 4px;
  border-top: 1px solid var(--kbr-border);
  margin-top: 6px;
}
.tl-gl-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--kbr-text-muted);
  white-space: nowrap;
}
.tl-gl-dot {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  flex: none;
}

/* Stacked right-column charts on PAF page — smaller than generic .short so
   both cards + gap fit within the same row height as the big-col charts. */
.chart-box.paf-short { height: 130px; }

/* The right-hand column stacks two cards where the other two columns hold one,
   and it never got .paf-big-col's flex treatment — so its cards sized to their
   content and the row ended on three different baselines. Fill the column the
   same way, and let the two charts share the leftover height, so all three
   columns finish on one line. Overrides the fixed .paf-short height above via
   specificity; that height still applies on narrow screens, where Bootstrap
   stacks the columns and there is no row height to fill. */
.paf-bottom-row > .col-md-3 {
  display: flex;
  flex-direction: column;
}
.paf-bottom-row > .col-md-3 > .card-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
}
.paf-bottom-row > .col-md-3 > .card-panel .chart-box {
  flex: 1;
  height: 0;
  min-height: 110px;
}

/* ── Page-body loading state ──────────────────────────────────────────
   When a request is in flight, the page-body gets `data-loading="true"`.
   The chart/tile rows dim slightly and a thin shimmer bar runs across
   the top of the page. Pure-CSS animation, no JS overhead.

   Purpose: backend filter requests on the PAF page take 1-2s. Without
   visible feedback the page looks frozen — users wonder if their click
   registered. The dim + shimmer makes "something is happening"
   immediately obvious. */
.page-body[data-loading="true"] {
  position: relative;
}
.page-body[data-loading="true"] > .row {
  opacity: 0.55;
  pointer-events: none;
  transition: opacity 0.12s ease;
}
.page-body[data-loading="true"]::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(
    90deg,
    transparent 0%,
    var(--kbr-teal, #1eb9c5) 35%,
    var(--kbr-teal, #1eb9c5) 65%,
    transparent 100%
  );
  background-size: 40% 100%;
  background-repeat: no-repeat;
  animation: page-body-shimmer 1.2s linear infinite;
  z-index: 100;
  pointer-events: none;
}
@keyframes page-body-shimmer {
  0%   { background-position: -50% 0; }
  100% { background-position: 150% 0; }
}

/* ─── PAF quick-filter chip bars ─────────────────────────────────────────
   Sits between the FilterPanel host and the page-body. Three horizontal
   chip groups (Priority / Work Status / Process Aging) wrap onto multiple
   rows on narrow screens. Empty selection (no chip active) = "All". */
.paf-quick-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 24px;
  padding: 8px 12px;
  background: #f8fafc;
  border-bottom: 1px solid var(--kbr-border);
}
.paf-quick-filters .ce-chip-bar {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-bottom: 0;
}
.paf-quick-filters .ce-chip-label {
  min-width: 96px;
  font-size: 11px;
  font-weight: 600;
  color: #6b7280;
  text-transform: uppercase;
  letter-spacing: 0.4px;
}

/* ─── Staffing Timeline "Graph by" multi-panel grid ───────────────────────
   Mirrors the cost-eac timeline panel layout. One mini-chart per dimension
   value when the user picks Graph by ≠ None. */
#tlMultiArea {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(420px, 1fr));
  gap: 12px;
}

/* ─── Staffing Timeline chip-bar alignment ─────────────────────────────────
   Each chip-bar row has a different-length label ("Mode:" vs "Graph by:"),
   so without a fixed label width the first chip on each row starts at a
   different x-position. Forcing min-width on the label makes every row's
   first chip line up vertically. */


/*─── Bootstrap col + Chart.js canvas overflow fix ────────────────────────
   When a card-panel sits inside a `d-flex` Bootstrap column (col-xl-3 etc.)
   and contains a Chart.js <canvas>, the column refuses to shrink below the
   canvas's intrinsic 300px default width — flex defaults to `min-width:auto`
   which equals the content's intrinsic size. Result: the 4 PAF chart cards
   overflow their row and overlap each other / the page boundary.

   Forcing `min-width: 0` on the flex children (col + card-panel) lets them
   shrink down to whatever the grid gives them. `overflow: hidden` on the
   chart-box clips any residual canvas overflow inside the card. */
.row > [class*="col-"].d-flex {
  min-width: 0;
}
.card-panel.flex-fill,
.card-panel.h-100 {
  min-width: 0;
}
.chart-box {
  overflow: hidden;
}

/* ----------------------------------------------------------------------------
   Staffing Overview info bar — surfaces Project ID / Name / Client /
   Report Date in a compact ribbon below the Filters toggle. Transparent
   background; labels gray, values navy so it reads on the page surface.
   ---------------------------------------------------------------------------- */
/* Project/Client/Date meta — now lives inside .page-toolbar on the right */
.toolbar-meta {
  display: flex;
  align-items: center;
  gap: 20px;
  padding-right: 16px;
  flex-shrink: 0;
}
.toolbar-meta .sib-item {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  white-space: nowrap;
}
.toolbar-meta .sib-label {
  text-transform: uppercase;
  font-size: 10px;
  letter-spacing: 0.5px;
  color: #6b7280;
  font-weight: 600;
}
.toolbar-meta .sib-value {
  color: var(--kbr-navy);
  font-weight: 700;
  font-size: 13px;
}
.toolbar-details-btn {
  background: var(--kbr-navy);
  color: #fff;
  border: none;
  font-size: 12px;
  padding: 4px 12px;
  border-radius: 4px;
  white-space: nowrap;
}
.toolbar-details-btn:hover {
  background: var(--kbr-navy-2, #1a3550);
  color: #fff;
}

/* ----------------------------------------------------------------------------
   Horizontally scrollable chart container. Wrap canvas in `.chart-inner`
   inside a `.chart-box.chart-box-scroll-x`; the inner wrapper's min-width
   is set by chart.js renderers based on bar count, and the outer .chart-box
   takes the overflow.
   ---------------------------------------------------------------------------- */
.chart-box.chart-box-scroll-x {
  overflow-x: auto;
  overflow-y: hidden;
}
.chart-box.chart-box-scroll-x .chart-inner {
  height: 100%;
  position: relative;
}

/* HTML legend rendered as a sibling of `.chart-box` so the scrollbar sits
   above it. Mirrors the look of Chart.js's built-in bottom legend. */
.chart-external-legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px 14px;
  padding: 8px 8px 4px;
  font-size: 11px;
  color: #475569;
}
.chart-external-legend .cel-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.chart-external-legend .cel-swatch {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 2px;
}

/* PAF Details — compact Tabulator overrides styled to match the LEASETEQ
   reference: soft-gray header bar, white rows (no zebra), thin row dividers,
   and small sort arrows on both sides of each header. Scoped to #tblDetails
   so it doesn't leak into other Tabulator instances in the app. */
#tblDetails.tabulator {
  font-size: 12px;
  color: #1f2937;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 6px;
}

/* Header bar */
#tblDetails .tabulator-header {
  background: #f3f4f6;
  border-bottom: 1px solid #e5e7eb;
}
#tblDetails .tabulator-header .tabulator-col {
  background: transparent;
  border-right: 1px solid #e5e7eb;
  padding: 6px 10px;
}
#tblDetails .tabulator-header .tabulator-col:last-child { border-right: none; }
#tblDetails .tabulator-header .tabulator-col-content { padding: 0; }
#tblDetails .tabulator-header .tabulator-col-title {
  font-size: 12px;
  font-weight: 600;
  color: #374151;
}

/* Sort arrow: single subtle chevron, brightens when active. */
#tblDetails .tabulator-col-sorter { right: 6px; }
#tblDetails .tabulator-col-sorter .tabulator-arrow {
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-bottom: 5px solid #cbd5e1;
}
#tblDetails .tabulator-col[aria-sort="ascending"] .tabulator-arrow {
  border-bottom-color: #111827;
}
#tblDetails .tabulator-col[aria-sort="descending"] .tabulator-arrow {
  border-bottom: none;
  border-top: 5px solid #111827;
}

/* Body rows */
#tblDetails .tabulator-tableholder { background: #fff; }
#tblDetails .tabulator-row {
  background: #fff;
  border-bottom: 1px solid #f1f5f9;
  min-height: 36px;
}
#tblDetails .tabulator-row.tabulator-row-even { background: #fff; }
#tblDetails .tabulator-row:hover { background: #f9fafb; }
#tblDetails .tabulator-row .tabulator-cell {
  padding: 8px 10px;
  border-right: none;
  color: #1f2937;
  font-variant-numeric: tabular-nums;
}

/* Group banner — when Group By is active, each cluster gets a soft slate
   header showing the dimension value + child count. */
#tblDetails .tabulator-row.tabulator-group {
  background: #eef2f8;
  border-top: 1px solid #cbd5e1;
  border-bottom: 1px solid #cbd5e1;
  color: var(--kbr-navy);
  font-weight: 700;
  padding: 6px 10px;
}
#tblDetails .tabulator-row.tabulator-group:hover { background: #e3eaf3; }
#tblDetails .tabulator-row.tabulator-group .tabulator-arrow {
  border-color: var(--kbr-navy) !important;
  margin-right: 6px;
}

/* Group By field — when injected into the filter-bar-fields row, match
   the visual weight of the regular filter combos. */
.det-gb-field .cols-btn {
  width: 100%;
  background: #fff;
  border: 1px solid #d6dde7;
  border-radius: 6px;
  padding: 6px 28px 6px 10px;
  font-size: 13px;
  color: var(--kbr-navy);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 34px;
}
.det-gb-field .cols-btn:hover { border-color: #bfc7d1; }
.det-gb-field .cols-caret { color: #6b7280; }
.det-gb-field .cols-dropdown { right: auto; left: 0; min-width: 220px; }
