/*
 * The Un-invoiced Approved Task Report's own styling — every `.uat-*` rule the view renders
 * (ISH-1081).
 *
 * ⚠️ **THIS FILE EXISTS BECAUSE THE REPORT HAS TWO HOSTS.** `UninvoicedApprovedTasksView` is
 * mounted by `uninvoiced-approved-tasks.html` AND, scoped to one broker, by the Reports section of
 * `broker.html` (ISH-1060). These rules lived in the report page's own `<style>` block until
 * ISH-1081, so the broker record rendered the shared markup with none of its CSS: the Assignments
 * cluster collapsed into one run-on string (`BHREPRMCSMRSCM` where the standalone draws three
 * initials circles over three role captions), the Group by pills painted red instead of black, and
 * the hover tip lost the `[hidden]` rule that is the only thing keeping it off the screen.
 *
 * ⚠️ **A NEW HOST MUST LINK THIS FILE.** `js/uninvoiced-report-stylesheet.test.js` fails the build
 * for any page that mounts the view without it — that test is the whole point of the extraction,
 * not a formality. Adding a rule here and leaving one host unlinked reproduces ISH-1081 exactly.
 *
 * ── What is here and what is not ─────────────────────────────────────────────
 *
 * Here: everything the VIEW MODULE renders. Not here: the report page's own chrome — its `:root`
 * scale, `body`, `.top-nav`, `.page-container`, `.page-header`, `.spinner`, `.action-btn` — which
 * belongs to an Operations Hub page and would be wrong inside a broker record's pane.
 *
 * ⚠️ **THE TWO HOSTS DECLARE DIFFERENT `:root` SCALES, AND THAT IS DELIBERATE.** The report page
 * takes operations-hub.html's slate (`--border: #e2e8f0`, `--text: #0f172a`, `--radius: 8px`);
 * broker.html has its own warmer set (`#e0e0e0`, `#1a1a1a`, `6px`). Every rule below reads tokens
 * rather than literals precisely so each host renders the report in its own surroundings. Do NOT
 * pin a value here to make the two match — they are not supposed to.
 *
 * ⚠️ **`--orange` IS THE ONE TOKEN NEITHER css/tokens.css NOR broker.html DEFINES**, so the two
 * rules that need it (`.uat-coverage`, `.uat-asof-stale`) carry a literal fallback. An undefined
 * custom property does not fall back to the initial value — it makes the WHOLE declaration invalid
 * at computed-value time, so `border-left: 3px solid var(--orange)` on broker.html drew no border
 * at all rather than a default one.
 *
 * Depends on, and does not restate: css/report-table.css (the table), css/kpi-card.css (the
 * summary strip), css/aging-summary.css (the mix bar), css/filter-bar.css + css/filter-toolbar.css
 * (the filter row), css/period-controls.css (`.view-bar` / `.view-btn`).
 */

/* ── Summary strip ──────────────────────────────────────────────────────
   Two shared components, both required of every host: css/kpi-card.css draws the five segments
   (ISH-981) and css/aging-summary.css the mix bar inside one of them (ISH-923). Only `--kpi-cols`
   on `.uat-kpi` below belongs to this report, which is exactly the escape hatch kpi-card.css
   documents.

   ⚠️ The note that stood here said the opposite — that the page "no longer renders a `.kpi-card` at
   all" and that the kpi-card.css link "is gone with it". True of ISH-923's strip, and untrue from
   ISH-981 onward, which put the report back on the shared component and re-linked the file without
   rewriting the paragraph explaining why it had not. It survived because a comment stating an
   absence reads as settled: nobody diffs prose against a <link> tag. Left as it was it told the
   next reader to delete a stylesheet two rules here depend on. ─────────────────────────────── */

/* `.analytics-card-title-group` — the slot beside the title. Empty today: the Sales Report
   puts a period badge here, and this report's window is already stated by the `As of` chip in
   the filter bar, so a badge would say it twice. It exists so one can be added later without
   restructuring the header. */
/* ── The report card ────────────────────────────────────────────────────
   ISH-1131: this shape is css/report-table.css's `.report-card` family now — `.report-card`,
   `.report-card-head`, `.report-card-headtext`, `.report-card-title`, `.report-card-meta`, and
   its own `.table-wrap:has(> .report-table)` strip. ISH-929 built it here, and this file said
   "if a second report grows one, move it there"; by the time it moved, four pages had built it
   independently — two citing `.uat-report-card` in a comment while not loading it at all. The
   rules are deleted rather than left alongside, which is the half skipped every previous time.

   ⚠️ The card is ALSO `.board-scroll-shell` (ISH-1142). That shell must never take an `overflow`
   of any kind, `clip` included, or it becomes the rail's scrollport and the sticky bar dies with
   no error. `.report-card` declares none, and js/uninvoiced-report-stylesheet.test.js asserts
   that against css/report-table.css now that the card lives there.

   What stays below is this report's own: the slot beside the title, and the Group by margin. */

/* ── Group by ────────────────────────────────────────────────────────────
   ISH-1131: `.uat-groupby`'s three `.view-btn` rules and its `margin-bottom: 0` are gone, on
   css/report-table.css's own instruction — that file states this block against
   `.report-card-head` and says, in as many words, that when this page migrates to
   `.report-card` these are to be DELETED rather than kept as a second copy. The scoping that
   made them safe is preserved there: `.report-card-head .view-btn`, not the bare class, because
   broker.html renders `.view-btn` in a Trends switcher that is not in a card header.

   `.uat-groupby` survives on the element as a hook for this report, but declares nothing. */

.uat-title-group {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

/* ── The Assignments cluster ────────────────────────────────────────────
   ISH-993. Three chips per broker row — REP, CSM, CM — each an initials circle over its role
   caption, the treatment brokers.html uses on its cards.

   ⚠️ Rebuilt here rather than reused, and the two obvious sources are both wrong:
     - `css/staff-chip.css` is a HORIZONTAL composite (circle beside a stacked role + full
       name), built for a page hero and a kanban card. A table cell has no room to spell a
       person out, and linking that file would bring rules this page never renders.
     - brokers.html's private `.staff-chip` is the vertical shape drawn below, but it is
       inline in that page and — despite the shared class name — is a DIFFERENT component from
       css/staff-chip.css. Lifting the name into a third file would make one selector mean
       three things. Hence the page-local `.uat-assign-*` names.

   The hover tip is NOT the plain CSS one the card this is ported from uses — `.table-wrap` is
   `overflow-x: auto`, so a tip hanging off a row is clipped by the scroller. It is
   script-positioned and parented to <body> instead; see `.uat-tip` below and `initTips()` in
   the view module. The full name is also each circle's accessible name, and the search box,
   the role's own filter pill and the ASM column all still render it in full. */
.uat-assign {
  display: inline-flex;
  align-items: flex-start;
  gap: 0.4rem;
}

.uat-assign-chip {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15rem;
  min-width: 22px;
}

/* 0.5rem and the tracking match brokers.html's `.staff-role` — small enough that three captions
   fit the column, and the uppercase + letter-spacing is what keeps a three-letter word legible
   at that size.

   ⚠️ The COLOUR deliberately does not match it. That page's `--text-label` is a mid grey on a
   different scale; this page inherits operations-hub.html's slate, where the same token is
   #94a3b8 — **2.43:1 on white**, under the 4.5:1 floor that every word of this caption needs.
   `--text-secondary` (#4b5563, 7.56:1) is what the rest of this page's small text already uses.
   A page-level test fails the build on `var(--text-label)` appearing anywhere here. */
.uat-assign-role {
  font-size: 0.5rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-secondary);
  line-height: 1;
  white-space: nowrap;
}

/* The hover tip for one circle (ISH-993). Parented to <body> and placed by script — see
   initTips() in js/uninvoiced-approved-tasks-view.js for why neither is optional here.

   ⚠️ `[hidden]` is declared explicitly because this rule sets `display`, which otherwise beats
   the attribute's own UA `display: none` and leaves the tip permanently on screen. That is a
   trap this repo has hit repeatedly.

   ⚠️ `pointer-events: none` is load-bearing, not polish: table rows toggle their own expansion
   on click, and a tip sitting under the cursor would swallow that click. */
.uat-tip {
  position: fixed;
  z-index: 200;
  display: block;
  max-width: 240px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  background: #1f1f1f;
  color: #ffffff;
  border-radius: var(--radius);
  padding: 0.4rem 0.6rem;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28);
  text-align: left;
  pointer-events: none;
}

.uat-tip[hidden] {
  display: none;
}

/* #9aa0a6 on #1f1f1f is 7.0:1 — this is a dark surface, so the page's light-background token
   rules do not apply and --text-label's 2.43:1 problem is not in play either way. */
.uat-tip-role {
  display: block;
  font-size: 0.55rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #9aa0a6;
  margin-bottom: 0.1rem;
}

.uat-tip-name {
  display: block;
  font-size: 0.85rem;
  font-weight: 700;
  line-height: 1.2;
}

/* An uncovered role reads as a state rather than a person, the same distinction the dashed
   circle draws. #ffb3b3 on #1f1f1f is 9.1:1. */
.uat-tip.is-unset .uat-tip-name {
  color: #ffb3b3;
  font-weight: 600;
  font-style: italic;
}

/* ── Rep initials ───────────────────────────────────────────────────────
   The circle itself, shared by all three chips above. */
.uat-initials-group {
  display: inline-flex;
  gap: 0.2rem;
}

.uat-initials {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--nav-bg);
  color: #ffffff;
  font-size: 0.5625rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}

/* An uncovered account is a finding, so the gap is drawn rather than left blank — a dashed
   ring reads as "nobody", where an empty cell reads as "not loaded". */
.uat-initials.is-none {
  background: none;
  border: 1px dashed var(--border);
}

.col-people {
  white-space: nowrap;
}

/* ⚠️ A dash, not a zero and not an empty tile (ISH-987). This report already renders one for
   an empty bucket, precisely so a blank never reads as a rendering failure — and a figure that
   does not exist yet must never be drawn as $0.00, which reads as a real measurement. Quiet
   enough to say "nothing here", dark enough to pass a contrast check: --text-secondary is
   7.56:1, where this page's --text-label is 2.43:1. */
.uat-kpi-none {
  color: var(--text-secondary);
  font-weight: 500;
}

/* ── The Week over week polarity (ISH-1315) ─────────────────────────────
   ⚠️ **THIS PAGE'S OWN, and `.kpi-trend` is deliberately not used.** The shared component paints
   `.kpi-trend.is-down` with `var(--red)` because both of its source pages measure revenue, where a
   decline is bad news. This report measures an UNPAID BALANCE: a fall is the outcome the whole
   page exists to produce. Inheriting that class would have painted the good week red and the bad
   week unstyled — the single most likely way for this segment to ship inverted, and invisible to
   every test that checks a figure rather than a colour.

   ⚠️ `--green` is #10b981 on this page and measures **2.54:1** on --card-bg #ffffff. It fails AA
   for normal text (4.5:1) and fails even the large-text floor (3:1), so it must never paint this.
   #1a7f37 is 5.08:1 — the pair css/fee-rate-chip.css already measured, reused rather than
   re-derived. --red (#a62626) is 7.18:1 and is used as the token.

   ⚠️ Colour is never the only carrier: the value text itself starts with ▲ or ▼ and the node
   carries an aria-label saying "up"/"down" in words. */
.uat-kpi-better {
  color: #1a7f37;
}

.uat-kpi-worse {
  color: var(--red);
}

/* ── The KPI strip (ISH-981) ────────────────────────────────────────────
   Five segments, from css/kpi-card.css — the same joined strip analytics.html, broker.html and
   sales-pipeline-report.html render. Only the column count is this page's, which is exactly the
   escape hatch that file documents. */
.uat-kpi {
  --kpi-cols: 5;

  margin-bottom: 1.25rem;
}

/* ISH-1012 deleted this page's `.main-tabs` / `.main-tab-btn` / `.tab-panel[hidden]` rules
   along with the one-tab strip they styled. Two things in them were hard-won and are recorded
   here rather than lost with the markup:

     - the inactive tab colour had to be `--text-secondary` (7.17:1), NOT the `--text-label`
       analytics.html uses, which is #94a3b8 on this page's slate scale and fails at 2.43:1;
     - `.tab-panel[hidden] { display: none }` was stated explicitly, because a `[hidden]`
       element loses to any author rule setting `display` — this app has hit that four times.

   Both apply again the moment a strip comes back. The deleted block is one commit away. */

.uat-scope-chip {
  display: inline-flex;
  align-items: center;
  background: rgba(166, 38, 38, 0.07);
  color: var(--red);
  border: 1px solid rgba(166, 38, 38, 0.15);
  border-radius: 999px;
  padding: 0.15rem 0.6rem;
  font-size: 0.75rem;
  font-weight: 600;
}

/* Moved to css/filter-bar.css (ISH-895): the filter row this page hand-copied
   from analytics.html as `.uat-filters` / `.uat-field` / `.uat-search` /
   `.uat-clear` is now the shared component, and the markup in
   the view renames onto its classes. Linked in <head>.

   ISH-906 then replaced the three native <select>s with real `.multi-filter`
   pills (ISH-928 made them BrokerApp.createMultiFilter()), so `.filter-field` is gone
   from this page and from the shared file — see its header. What this page
   renders now is `.filter-bar` > `.filter-bar-search` + three `.filter-group`
   pills + `.filter-clear-btn`, which needs css/filter-toolbar.css too.

   The old comment here said why the copy existed — "`.filter-bar` is still
   per-page inline across the app". That is no longer true, which is the whole
   of this change. */

/* ── "As of" chip and its popover ────────────────────────────────────────
   The date is the part worth showing; the full sentence is one click away.
   ⚠️ A click popover, not a `title` tooltip — the house rule (ISH-468's click-confirmation
   pattern): a tooltip is unreachable on touch, invisible to keyboard users, and cannot be
   read at leisure. No `title` attribute anywhere on this control. */
.uat-asof {
  position: relative;
  /* ISH-929: pushed over by `.filter-bar-spacer` + `.filter-bar-divider` in the markup now,
     the way the Sales Report separates its Window badge — a hairline marks the break between
     the facets and the fact, where a bare `margin-left: auto` left an unexplained gap. */
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.uat-asof-chip {
  display: inline-flex;
  align-items: center;
  /* 0.4rem, matching the gap `.filter-kind` sits on in the Sales Report's period control. */
  gap: 0.4rem;
  height: 30px;
  padding: 0 0.7rem;
  /* ⚠️ 1px, not 1.5px (ISH-929). This chip is INSIDE `.filter-bar`, beside the `.mf-trigger`
     pills and the `.filter-bar-search` input that ISH-921 pinned at 1px for exactly this
     reason — "a 1px pill beside a 1.5px input, visible side by side". This control was already
     in the bar and was missed by that pass. Change it with them, not on its own. */
  border: 1px solid var(--border);
  border-radius: 50px;
  background: #ffffff;
  font: inherit;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--text-secondary);
  cursor: pointer;
  white-space: nowrap;
  transition:
    border-color 0.15s,
    color 0.15s;
}

.uat-asof-chip:hover,
.uat-asof-chip[aria-expanded="true"] {
  border-color: #999999;
  color: var(--text);
}

.uat-asof-popover {
  position: absolute;
  top: calc(100% + 0.4rem);
  right: 0;
  z-index: 20;
  width: max-content;
  max-width: 320px;
  padding: 0.65rem 0.8rem;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
  font-size: 0.8125rem;
  font-weight: 400;
  line-height: 1.45;
  color: var(--text-secondary);
  text-align: left;
  white-space: normal;
}

/* ISH-973: the snapshot-freshness disclosure inside the as-of popover. The popover holds two
   or three short paragraphs now rather than one text node, so they need their own spacing. */
.uat-asof-line {
  margin: 0 0 0.4rem;
}

.uat-asof-line:last-child {
  margin-bottom: 0;
}

/* --orange, not --red: a stale snapshot still renders a usable report built from real data.
   Red would read as "this page is broken", which would be the wrong call to action. */
.uat-asof-stale {
  margin: 0;
  padding-top: 0.4rem;
  border-top: 1px solid var(--border-light);
  color: var(--orange, #fd7e14);
}

.uat-asof-chip--stale {
  border-color: var(--orange, #fd7e14);
  color: var(--orange, #fd7e14);
}

/* Kept legible on its own rather than relying on the border colour alone: colour is not a
   signal every viewer can read. */
.uat-asof-stale-dot {
  margin-left: 0.3rem;
  font-weight: 600;
}

/* ── The table ──────────────────────────────────────────────────────────
   Moved to css/report-table.css (ISH-896) and restyled to analytics.html's
   Unattributed Brokers look: no header fill, 600 weight in --text-label,
   ▼/▲ on the active column in --text rather than --red, and a borderless
   wrapper instead of a bordered card. Linked in <head>.

   Only the two page-specific rules below stay here — they name this
   report's own columns, so they do not belong in the shared file. */
.col-broker,
.col-client {
  max-width: 240px;
}

/* ⚠️ NO box of its own (ISH-929). This table renders inside an expanded row of the
   `.report-table`, which is itself inside the report card — so a border and a radius here drew
   a card inside a card inside a card. The indent and the row it sits in are what separate it.
   The `overflow: hidden` went with the radius that needed it. */
.uat-task-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8125rem;
}

/* ⚠️ `position: static` is NOT redundant: `.report-table th` (css/report-table.css) is a
   DESCENDANT selector, and this table lives inside a `.report-table`, so its headers inherit
   that rule's sticky positioning along with its type. Only the sticky and the size are
   overridden — the fill deliberately is not, so the nested header takes the same #ffffff as
   every other header on the page. It used to force #f1f5f9, a full step darker than any of
   them, which is the treatment ISH-896 moved the main table off and left behind here. */
.uat-task-table th {
  position: static;
  font-size: 0.625rem;
  padding: 0.4rem 0.6rem;
}

.uat-task-table td {
  padding: 0.4rem 0.6rem;
  border-bottom: 1px solid var(--border-light);
  font-variant-numeric: tabular-nums;
}

.uat-task-table tr:last-child td {
  border-bottom: none;
}

/* A task whose value the warehouse could not parse. Counted in `skipped.unparseableValue`
   and contributing 0 to the totals, so it is said in words rather than shown as $0.00, which
   would read as a real zero. */
.uat-value-unknown {
  font-size: 0.75rem;
  font-style: italic;
  color: var(--text-secondary);
  white-space: nowrap;
}

.uat-task-table a {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--red);
  white-space: nowrap;
}

/* ── Island states and the coverage disclosure ───────────────────────── */
.uat-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: 4rem 1rem;
  color: var(--text-secondary);
  text-align: center;
}

.uat-error {
  color: var(--red);
}

.uat-coverage {
  margin-top: 1rem;
  font-size: 0.8125rem;
  color: var(--text-secondary);
  background: var(--info-bg);
  border: 1px solid var(--border);
  border-left: 3px solid var(--orange, #fd7e14);
  border-radius: var(--radius);
  padding: 0.7rem 0.9rem;
}

@media (max-width: 900px) {
  /* The chip stops claiming the right edge once the bar wraps, or it lands on its own line. */
  .uat-asof {
    margin-left: 0;
  }
}
