/*
 * Federal Contract Radar — read-only public surface.
 *
 * Soft Slate workspace canvas (--app-* tokens) under the shared dark-navy site
 * header, per DESIGN.md. Mobile is the canonical composition; desktop expands it.
 * No gradients, glass, neon, or terminal aesthetic.
 */

.radar-body {
  margin: 0;
  background: var(--app-bg);
  color: var(--app-text);
  font-family: var(--font-ui);
  min-height: 100vh;
}

/* Radar presentation layer: quieter than the general workspace palette so the
   hierarchy comes from information, not card chrome.
 *
 * Scoped to `.radar-body` — every Radar document carries it — rather than to one
 * page class. The index, the IQT report and the company report are one surface a
 * reader moves through in two clicks, so they must resolve to the SAME canvas
 * and the same ink. Scoping this to the company page alone is what let the index
 * drift onto a hardcoded near-black that matched neither this palette nor the
 * site header it sat under. */
.radar-body {
  --radar-canvas: #eef1f5;
  --radar-surface: #fbfaf8;
  --radar-border: rgba(72, 88, 109, 0.13);
  --radar-divider: rgba(72, 88, 109, 0.10);
  --radar-ink: #122033;
  --radar-secondary: #34465e;
  --radar-muted: #52637a;
  --radar-meta: #5f6e82;
  --radar-blue: #315f9c;
  --radar-blue-soft: #e6ebf3;
  /* #287a5b measured 4.48:1 for the "Active" chip on the page canvas — a miss by
     0.02. This clears 5.12 there and 5.70 on a card, and is the same green. */
  --radar-green: #257054;
  --radar-green-soft: #e7f0eb;
  --radar-red: #b44949;
  /* Index/IQT status ink. The company report has no "exited"/"blocked" state, so
     this pair only resolves on those two surfaces. */
  --radar-amber: #8a5a10;
  --radar-shadow: 0 1px 2px rgba(18, 32, 51, 0.025), 0 8px 24px rgba(18, 32, 51, 0.045);

  /*
   * Accent for TEXT, separate from the accent for borders and tints.
   *
   * `--app-accent` is deliberately the same #2563EB in both themes. Behind a
   * border or a background tint that is fine — those need 3:1. As small text on
   * this canvas it measures 2.8-3.4:1, under AA, and it was doing exactly that
   * on the current tab and the sorted column header. `--radar-blue` is the same
   * role and is theme-aware, so text uses it and everything else keeps
   * `--app-accent`.
   *
   * Declared here with the rest of the palette rather than on `.ds-workspace`.
   * The sub-navigation is shared chrome now: it renders on the Federal Contracts
   * index and on every company report, and neither of those builds a workspace.
   * Scoped to the workspace, `var(--ds-accent-text)` resolved to nothing on
   * exactly the two page types the rail was just added to, and their current tab
   * fell back to plain ink while In-Q-Tel's stayed blue. `.radar-body` is the one
   * scope all three share — the same reason the rest of this palette lives here.
   */
  --ds-accent-text: var(--radar-blue);

  /*
   * Scoped override, not a site-wide change.
   *
   * The shared `--app-text-tertiary` (#6B7280) is 3.74-4.15:1 against this
   * palette's surfaces — under AA for normal text everywhere except the
   * lightest one, and seventeen rules in this stylesheet use it as a text
   * colour. Fixing the token rather than the seventeen. #59616F clears 4.5 on
   * the worst of them (surface-3, 4.83:1) and stays a visible step lighter than
   * `--app-text-muted`, so the tertiary level still exists. This declaration is
   * light-mode-only in intent: it lands on the body element, which outranks the
   * site's inherited `:root` value, so the dark block below must hand the token
   * back or this light grey would follow us onto the dark canvas.
   */
  --app-text-tertiary: #59616F;
}

@media (prefers-color-scheme: dark) {
  .radar-body {
    --radar-canvas: #171d25;
    --radar-surface: #202730;
    --radar-border: rgba(187, 200, 216, 0.13);
    --radar-divider: rgba(187, 200, 216, 0.09);
    --radar-ink: #e6edf5;
    --radar-secondary: #c3ceda;
    --radar-muted: #b0bcc9;
    --radar-meta: #a3afbd;
    --radar-blue: #7fa4d8;
    --radar-blue-soft: #27374d;
    --radar-green: #6fba98;
    --radar-green-soft: #20382f;
    --radar-red: var(--app-danger);
    --radar-amber: #e0b26b;
    --radar-shadow: 0 1px 2px rgba(0, 0, 0, 0.18), 0 10px 28px rgba(0, 0, 0, 0.20);
    /*
     * Hand `--app-text-tertiary` back to the site token. The light-mode override
     * above is set on the body element, which outranks the `:root` declaration
     * this media query's site-wide counterpart makes — so without this line the
     * light grey (#59616F) would ride into dark mode at 2.71:1 on the canvas.
     * `inherit` takes :root's dark value rather than restating the hex here, so
     * the two files cannot drift apart.
     */
    --app-text-tertiary: inherit;
  }
}

/*
 * `body.app-workspace main` owns the workspace canvas: full-bleed width, the
 * radial main-glow, and the vertical rhythm. Do not override it here — constrain
 * the reading column with this inner wrapper instead. (main is a flex column, so
 * auto margins on stretched children would not center them anyway.)
 */
.radar-page {
  box-sizing: border-box;
  margin: 0 auto;
  max-width: 560px;
  padding: 0 16px;
  width: 100%;
}

.radar-company-page {
  /* The company report's measure, in one place. The page and the demo banner
   * above it both read it, so widening the report can never leave the banner
   * narrower than the cards it sits over.
   *
   * Keyed to viewport HEIGHT, which looks odd until you follow the coupling: the
   * plot's height is derived from its width (`aspect-ratio: 1000 / H` below, H
   * being the density heuristic from getChartPlotHeight), so every pixel of extra
   * measure buys ~0.52px of extra chart height. Width and "fits on one screen"
   * are therefore the same dial, and a single fixed measure cannot serve both: at
   * a 1440x700 viewport anything past 1180px scrolls, while at 1600x1000 even
   * 1520px fits with room over.
   *
   * So the base is the value that fits a short laptop window, and taller windows
   * spend the height they actually have. Measured per tier, not interpolated —
   * see the CHANGELOG entry for the numbers.
   */
  --radar-report-measure: 1180px;
}

@media (min-height: 780px) {
  .radar-company-page { --radar-report-measure: 1300px; }
}

@media (min-height: 880px) {
  .radar-company-page { --radar-report-measure: 1400px; }
}

@media (min-height: 980px) {
  .radar-company-page { --radar-report-measure: 1500px; }
}

.radar-company-page .radar-page,
.radar-card {
  background: var(--app-surface-1);
  border: 1px solid var(--app-border);
  border-radius: 16px;
  box-shadow: var(--app-card-shadow);
  padding: 28px 20px 20px;
}

/* Company identity — centered, per the first-viewport contract.
 *
 * `.radar-company` is NOT only the company name. It is also the index hero
 * ("Federal Contracts") and the event page's ("Contract action") — two static
 * UI labels, where the uppercase treatment is a type choice and nothing is
 * being misspelled. The base therefore keeps it, and only the company page
 * opts out; see `.radar-company-page .radar-company` below for why.
 *
 * Dropping the transform here instead restyled both of those pages silently,
 * and left the index at 0.06em — tracking tuned for capitals, applied to mixed
 * case, which is the exact defect the company-page rule was fixing.
 */
.radar-company {
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  margin: 0;
  text-align: center;
  text-transform: uppercase;
}

/* The one signal the first viewport is built around. */
.radar-amount {
  color: var(--radar-green);
  font-size: clamp(2.5rem, 12vw, 3.25rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin: 20px 0 0;
  text-align: center;
}

.radar-amount-link {
  color: inherit;
  text-decoration: none;
}

.radar-amount-link:hover {
  text-decoration: underline;
  text-underline-offset: 0.12em;
}

.radar-amount-link:focus-visible {
  border-radius: 4px;
  outline: 2px solid var(--radar-blue);
  outline-offset: 4px;
}

.radar-amount-deobligation {
  color: var(--radar-red);
}

.radar-amount-zero {
  color: var(--radar-muted);
}

.radar-amount-caption {
  color: var(--radar-muted);
  font-size: 0.875rem;
  margin: 6px 0 0;
  text-align: center;
}

.radar-kicker {
  color: var(--radar-muted);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  margin: 0 0 8px;
  text-align: center;
  text-transform: uppercase;
}

/* --radar-blue, not --app-accent: the solid accent (#2563EB) is tuned for a
   white button label, and as ink it only reaches 2.91:1 on the dark radar
   surface — under AA, and under even the 3:1 large-text floor. --radar-blue is
   the link ink the rest of this file already uses, and clears AA in both
   schemes (6.20:1 light / 5.88:1 dark). Hover goes to --radar-ink rather than
   --app-accent-hover, which is darker still and would sink further in dark. */
.radar-inline-link {
  color: var(--radar-blue);
  font-weight: 600;
  text-decoration: none;
}

.radar-inline-link:hover {
  color: var(--radar-ink);
  text-decoration: underline;
}

.radar-inline-link:focus-visible {
  border-radius: 2px;
  outline: 2px solid var(--radar-blue);
  outline-offset: 2px;
}

.radar-event-facts {
  display: grid;
  gap: 12px;
  margin: 0;
}

.radar-event-fact {
  display: grid;
  gap: 2px;
}

.radar-event-fact dt {
  color: var(--app-text-tertiary);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.radar-event-fact dd {
  color: var(--app-text);
  font-size: 0.875rem;
  line-height: 1.45;
  margin: 0;
  overflow-wrap: anywhere;
}

.radar-event-detail {
  color: var(--app-text-muted);
  font-size: 0.8125rem;
  line-height: 1.5;
  margin: 16px 0 0;
}

.radar-mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
    "Courier New", monospace;
  font-size: 0.75rem;
  font-weight: 500;
}

.radar-event-meta {
  font-size: 0.875rem;
  margin: 14px 0 0;
  text-align: center;
}

.radar-event-meta-secondary {
  color: var(--app-text-muted);
  margin-top: 4px;
}

.radar-quiet {
  color: var(--app-text-muted);
  font-size: 1rem;
  line-height: 1.5;
  margin: 24px 0;
  text-align: center;
}

.radar-divider {
  border: 0;
  border-top: 1px solid var(--app-border);
  margin: 24px 0;
}

.radar-compare {
  align-items: baseline;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: space-between;
}

.radar-compare-label {
  color: var(--app-text-muted);
  font-size: 0.8125rem;
}

.radar-compare-value {
  font-size: 1.125rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.radar-compare-change {
  color: var(--app-success);
  font-size: 0.8125rem;
  font-weight: 600;
}

.radar-compare-change-muted {
  color: var(--app-text-tertiary);
  font-weight: 400;
}

.radar-deobligation {
  color: var(--app-text-muted);
  font-size: 0.8125rem;
  margin: 8px 0 0;
}

.radar-label {
  color: var(--app-text-tertiary);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.radar-trend {
  margin: 24px 0 0;
}

.radar-trend-svg {
  display: block;
  height: 64px;
  margin-top: 8px;
  width: 100%;
}

.radar-trend-bar {
  fill: var(--app-accent);
}

.radar-trend-empty {
  color: var(--app-text-tertiary);
  font-size: 0.8125rem;
  margin: 24px 0 0;
}

/* Company drill-through: Soft Slate report on the system workspace canvas. */
body.app-workspace.radar-company-page {
  /* Body as well as main. `main` alone leaves the body on --app-bg (#EAEEF4),
     four points off the report canvas — which shows on macOS overscroll and on
     any viewport taller than the report. */
  background: var(--radar-canvas);
  color: var(--radar-ink);
}

body.app-workspace.radar-company-page main {
  background: var(--radar-canvas);
  background-image: none;
  color: var(--radar-ink);
  padding: 0 0 20px;
}

.radar-company-page .radar-page {
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  max-width: none;
  padding: 0 0 20px;
}

/* Keep the shared dataset switcher on the same full-bleed rail as IQT. */
.radar-company-page .radar-page > .ds-subnav {
  margin: 0;
  padding: 0 20px;
}

.radar-company-report {
  background: var(--app-surface-1);
  border: 1px solid var(--app-border);
  border-radius: 16px;
  box-shadow: var(--app-card-shadow);
  box-sizing: border-box;
  display: grid;
  /* ~12–20px tighter than prior title-to-content gap on desktop. */
  gap: clamp(4px, 1vh, 8px);
  margin: 20px auto 0;
  max-width: var(--radar-report-measure);
  /* Top padding was 0, so the company name sat against the card's own border.
   *
   * It is viewport-keyed rather than fixed for the reason the measure above is:
   * the plot's height derives from its width, so every vertical pixel spent
   * here is one the chart does not get, and the page is built to fit a short
   * laptop window without scrolling. At 700px tall this yields ~15px — enough
   * to read as deliberate space rather than a clipped edge — and at 1000px it
   * opens to the full 24px, matching the horizontal padding so the card's
   * inset reads as even on the viewports that can afford it.
   */
  padding: clamp(12px, 2.2vh, 24px) 24px 20px;
}

.radar-company-report-header {
  align-items: center;
  display: flex;
  justify-content: center;
  /* Was 2px, which left the name 13px off the content below against 22px of
   * card padding above it — the title read as belonging to the block under it
   * rather than sitting in its own space. Viewport-keyed for the same reason
   * the card's top padding is: on a short window this stays near the old value
   * and the chart keeps its height.
   */
  margin-bottom: clamp(2px, 0.9vh, 10px);
  position: relative;
  text-align: center;
  width: 100%;
}

.radar-company-back {
  align-items: center;
  border-radius: 8px;
  color: var(--radar-meta);
  display: inline-flex;
  font-size: 0.8125rem;
  font-weight: 600;
  left: -10px;
  min-height: 44px;
  padding: 0 10px;
  position: absolute;
  text-decoration: none;
  top: 50%;
  transform: translateY(-50%);
}

.radar-company-back:hover {
  color: var(--radar-ink);
  text-decoration: underline;
  text-underline-offset: 0.18em;
}

.radar-company-back:focus-visible {
  outline: 2px solid var(--radar-blue);
  outline-offset: 2px;
}

.radar-company-page .radar-section-label {
  color: var(--radar-meta);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  margin: 0 0 4px;
  text-transform: uppercase;
  text-align: center;
}

/* The company page — and ONLY the company page — sets the name in the case the
 * registry stores.
 *
 * Here the text is a real company's name, and the registry already holds it the
 * way each company writes it, so uppercasing normalised nothing and overrode
 * brands carrying internal capitals: `SpaceX` rendered as SPACEX, `Shield AI`
 * as SHIELD AI. Rendering a name in a case its owner does not use is a small
 * factual error on the one line identifying who the page is about. That
 * reasoning does not extend to the index or event headings, which are labels
 * this project writes — hence the opt-out lives here, not in the base rule.
 *
 * Tracking goes with it. 0.065em was tuned for capitals, which are uniform
 * boxes needing daylight between them; at 2.25–3.6rem in mixed case the same
 * value pulls the word apart, and a display size wants slightly negative.
 */
.radar-company-page .radar-company {
  color: var(--radar-ink);
  font-size: clamp(2.25rem, 4.3vw, 3.6rem);
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.05;
  text-align: center;
  text-transform: none;
}

.radar-company-page .radar-freshness {
  color: var(--radar-meta);
  margin: 0;
  /* Wraps rather than overflowing — still true, but the mechanism moved. It is
   * no longer one long '·'-joined string that has to be broken *somewhere*; it
   * is now one element per fact, each `nowrap`, so the break can only land in a
   * gap between facts. That is what stopped "Department of War coverage through
   * May 1, 2026" from splitting after "Department of".
   *
   * `right` came from the era when this was a single string: it is the left
   * item of a space-between footer, so right-aligning it pulled every wrapped
   * line away from the column it belongs to and produced a ragged wedge. This
   * rule out-specifies the footer's own `text-align`, so the alignment has to
   * be corrected here, not there.
   */
  text-align: left;
  text-wrap: pretty;
  white-space: normal;
}

/* Company Report Layout: Summary Rail (Left) + Contract Activity Chart (Right) */
.radar-company-layout {
  align-items: start;
  display: grid;
  gap: 20px;
  /* 390px, up from 300px. At 300 the rail's content box was 258px and three of
   * its meta lines needed 263-290px, so every stat wrapped its own caption onto
   * a second line. 390 gives 348px of content, which clears the longest line the
   * rail actually composes ("No comparable prior period · Oct 20, 2025 – Apr 17,
   * 2026", measured at 337px) with the window switched to any of the three, and
   * leaves ~11px rather than the 1px that 380 left — a margin that thin is a
   * rendering difference away from wrapping again.
   *
   * One line still exceeds this and cannot reasonably be fixed with width: a full
   * legal agency name ("National Aeronautics and Space Administration · Funding
   * modification Jul 14") measures 450px and would want a 492px rail — 43% of the
   * layout, taking ~190px from the chart. That one is a copy problem, not a width
   * problem; `AGENCY_SHORT_NAMES` in publication/caption.ts already holds the
   * reviewed short forms if we decide the page should use them too.
   *
   * Still a minmax, so the rail gives the width back before the chart is
   * squeezed on a smaller desktop.
   */
  grid-template-columns: minmax(300px, 390px) minmax(0, 1fr);
  width: 100%;
}

.radar-summary-rail {
  /* Same elevated surface as the chart card — internal dividers carry hierarchy. */
  background: var(--radar-surface);
  border: 1px solid var(--radar-border);
  border-radius: 12px;
  box-shadow: var(--radar-shadow);
  display: flex;
  flex-direction: column;
  padding: 8px 0;
  width: 100%;
}

.radar-rail-item {
  display: flex;
  justify-content: center;
  min-height: 120px;
  padding: 18px 20px;
}

.radar-rail-divider {
  border-top: 1px solid var(--radar-divider);
  height: 0;
  margin: 0 16px;
}

.radar-rail-icon {
  align-items: center;
  border-radius: 4px;
  display: flex;
  flex-shrink: 0;
  height: 32px;
  justify-content: center;
  width: 32px;
}

.radar-rail-icon svg {
  height: 16px;
  opacity: 0.78;
  stroke-width: 1.7;
  width: 16px;
}

.radar-rail-icon-latest,
.radar-rail-icon-obligations {
  background: var(--radar-green-soft);
  border: 1px solid color-mix(in srgb, var(--radar-green) 18%, transparent);
  color: var(--radar-green);
}

.radar-rail-icon-total {
  background: var(--radar-blue-soft);
  border: 1px solid color-mix(in srgb, var(--radar-blue) 18%, transparent);
  color: var(--radar-blue);
}

.radar-rail-content {
  align-self: center;
  align-items: center;
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-width: 0;
  text-align: center;
  width: 100%;
}

.radar-rail-content > * {
  margin: 0;
}

.radar-rail-value-row {
  align-items: center;
  display: grid;
  gap: 15px;
  grid-template-columns: 32px minmax(0, 1fr) 32px;
  max-width: 100%;
  width: 13.875rem;
}

.radar-rail-value-row::after {
  content: "";
  height: 32px;
  width: 32px;
}

.radar-rail-eyebrow {
  color: var(--radar-meta);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.075em;
  text-transform: uppercase;
}

.radar-rail-value {
  color: var(--radar-ink);
  font-size: clamp(1.9rem, 2.35vw, 2.3rem);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.05;
  text-align: center;
}

.radar-rail-value-latest,
.radar-rail-link {
  color: var(--radar-green);
  text-decoration: none;
}

.radar-rail-value-quiet {
  font-size: 1.25rem;
  letter-spacing: -0.015em;
}

.radar-rail-link:hover {
  color: var(--radar-green);
  filter: brightness(1.08);
  text-decoration: underline;
}

.radar-rail-meta {
  color: var(--radar-muted);
  font-size: 0.78rem;
  line-height: 1.4;
}

.radar-rail-event {
  color: var(--radar-blue);
  font-size: 0.78rem;
  font-weight: 600;
  margin-top: 2px;
  text-decoration: none;
}

.radar-rail-event:hover {
  color: var(--app-accent-hover);
  text-decoration: underline;
}

/* One child: the freshness facts. It was two — a corrections sentence sat
 * beside them — and the flex properties that arranged those two sides
 * (`justify-content: space-between`, `column-gap`, `align-items: baseline`,
 * `flex-wrap`) went inert when it moved into "About this chart". They are gone
 * rather than left as decoration that reads like it does something; the
 * wrapping now happens one level down, in `.radar-flow-freshness`.
 *
 * `text-align: left` stays and is load-bearing: an inherited `right` was
 * pulling wrapped lines away from the column they belong to, which is what
 * made this block read as a ragged wedge.
 */
.radar-flow-footer {
  border-top: 1px solid var(--radar-divider);
  flex-shrink: 0;
  font-size: 12px;
  /* Keep the date axis visually attached to its source context. */
  margin-top: 12px;
  padding-top: 8px;
  text-align: left;
}

.radar-flow-freshness {
  color: var(--radar-meta);
  /* The facts are laid out, not run together: a wrap lands in a gap between
   * them and never inside one. The gap does the separating work the `·` used
   * to, and unlike a `·` it cannot be orphaned onto the start of a new line.
   */
  column-gap: 18px;
  display: flex;
  flex-wrap: wrap;
  min-width: 0;
  row-gap: 2px;
}

.radar-flow-fact {
  white-space: nowrap;
}

/* Below ~344px the longest fact ("Department of War coverage through May 1,
 * 2026", 284px at 12px) is wider than the card's content box, and `nowrap`
 * would push it across the border rather than wrap it — nothing in the
 * ancestor chain clips. A mid-fact break is the lesser fault than text
 * crossing the card edge, so under 360px the guarantee is deliberately
 * released. 375px, the narrowest common phone, sits above this and keeps
 * whole facts. */
@media (max-width: 359px) {
  .radar-flow-fact { white-space: normal; }
}

.radar-flow {
  /* Explicit regions: header → legend → plot panel(s) → footer.
     Column flex with zero-grow children so leftover height never expands the plot. */
  background: var(--radar-surface);
  border: 1px solid var(--radar-border);
  border-radius: 12px;
  box-shadow: var(--radar-shadow);
  display: flex;
  flex-direction: column;
  height: fit-content;
  min-height: 0;
  padding: 14px 20px 12px;
}

.radar-flow {
  /* One height for every control in the ribbon's right-hand cluster.
   * 34px because that clears the pill group's own natural height (33.6px from
   * its label line box plus padding) — a smaller token would leave the pills
   * taller than the Expand control, since min-height cannot shrink them. */
  --radar-ribbon-control-h: 34px;
}

.radar-flow-header {
  /* Region A */
  /* Centre, not flex-start. The control cluster is 33.6px tall and the heading's
   * line box is 25.6px, so top-aligning them put the heading's text centre 4px
   * above the pill labels' — the row read as two things that missed each other.
   * Measured, not eyeballed: heading box 25.6 vs controls box 33.6 at 1280px. */
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 16px;
  justify-content: space-between;
  margin-bottom: 8px;
  /* Same 2px inset the legend and readout rows carry, so all three rows in the
   * ribbon start on one vertical line. The heading was flush at 0 while the two
   * rows beneath it were inset, which is why the legend swatch never lined up
   * under "Contract Activity". */
  padding: 0 2px;
  /* Containing block for the explainer panel, so the panel anchors to the card's
   * content edge rather than to the trigger. Anchoring to the trigger meant the
   * panel started wherever the heading text happened to end and ran off the right
   * edge on a narrow screen (measured at 497px: right edge 1px past the
   * viewport). Anchored here it is inside the card at every width. */
  position: relative;
}

/* Heading and its explainer travel together. The disclosure used to sit at the
 * far right of the legend row, directly beneath "Expand chart" — two icon+text
 * controls of near-identical weight stacked in one corner, reading as a pair of
 * sibling actions when one changes the viewport and the other is documentation.
 * Beside the heading it sits next to the thing it explains and leaves the right
 * side to controls alone. */
.radar-flow-heading {
  /* Inline: the heading, then the explainer beside it.
   *
   * This was stacked, on the reasoning that side by side the explainer competed
   * with the heading for the same line. That reasoning assumed they carry
   * similar weight — but the explainer is 11px `--radar-meta` against a 25.6px
   * heading, so it reads as an affordance attached to the title rather than a
   * second thing claiming the line, and stacking spent a whole row on it.
   *
   * `baseline`, not `center`: the two sit on the same line of text, and centring
   * a 11px box against a 25.6px one leaves the small text floating.
   *
   * Wraps, so a narrow header drops the explainer under the title rather than
   * squeezing the heading.
   */
  align-items: baseline;
  column-gap: 10px;
  display: flex;
  flex-wrap: wrap;
  row-gap: 2px;
}

.radar-flow-title,
.radar-flow h2 {
  color: var(--radar-secondary);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  margin: 0;
}

/*
 * Zero-script window switch on the shared layout ancestor so the chart SVG and
 * the range-bound summary rail metrics switch together from one radio set.
 *
 * The heading is no longer switched: all three read "Contract Activity", so the
 * only thing three copies bought was two hidden duplicate headings in the
 * document outline.
 */
.radar-company-layout .radar-flow-panel--ytd,
.radar-company-layout .radar-flow-panel--365,
.radar-company-layout .radar-rail-range--ytd,
.radar-company-layout .radar-rail-range--365 {
  display: none;
}

.radar-company-layout:has(.radar-tf-ytd:checked) .radar-flow-panel--180,
.radar-company-layout:has(.radar-tf-365:checked) .radar-flow-panel--180,
.radar-company-layout:has(.radar-tf-ytd:checked) .radar-rail-range--180,
.radar-company-layout:has(.radar-tf-365:checked) .radar-rail-range--180 {
  display: none;
}

.radar-company-layout:has(.radar-tf-ytd:checked) .radar-flow-panel--ytd,
.radar-company-layout:has(.radar-tf-ytd:checked) .radar-rail-range--ytd {
  display: block;
}

.radar-company-layout:has(.radar-tf-365:checked) .radar-flow-panel--365,
.radar-company-layout:has(.radar-tf-365:checked) .radar-rail-range--365 {
  display: block;
}

.radar-flow-subtitle {
  color: var(--radar-muted);
  font-size: 0.75rem;
  margin: 0;
}

.radar-flow-controls {
  align-items: center;
  display: flex;
  gap: 12px;
}

/* The chart is the primary reading surface. This native disclosure keeps the
 * static page script-free while giving the reader a full-width inspection mode. */
.radar-chart-focus-control {
  position: relative;
}

.radar-chart-focus-control summary {
  align-items: center;
  background: transparent;
  border: 1px solid var(--radar-divider);
  border-radius: 4px;
  color: var(--radar-secondary);
  cursor: pointer;
  display: inline-flex;
  font-size: 11px;
  font-weight: 600;
  gap: 6px;
  list-style: none;
  min-height: var(--radar-ribbon-control-h);
  padding: 0 10px;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
  white-space: nowrap;
}

.radar-chart-focus-control summary::-webkit-details-marker { display: none; }

.radar-chart-focus-control summary svg {
  height: 14px;
  width: 14px;
}

.radar-chart-focus-control summary:hover {
  background: var(--radar-blue-soft);
  border-color: color-mix(in srgb, var(--radar-blue) 36%, var(--radar-divider));
  color: var(--radar-blue);
}

.radar-chart-focus-control summary:focus-visible {
  outline: 2px solid var(--radar-blue);
  outline-offset: 2px;
}

.radar-chart-focus-label-expanded { display: none; }

.radar-chart-focus-control[open] .radar-chart-focus-label { display: none; }
.radar-chart-focus-control[open] .radar-chart-focus-label-expanded { display: inline; }

/* Focus mode intentionally keeps the range selector and all source evidence in
 * place, but gives the plotted series the full report width. */
.radar-company-layout:has(.radar-chart-focus-control[open]) {
  grid-template-columns: minmax(0, 1fr);
}

.radar-company-layout:has(.radar-chart-focus-control[open]) .radar-summary-rail {
  display: none;
}

.radar-flow-pills {
  /* Same height as the Expand control beside it. The two were 33.6px and 30px —
   * centred on each other, so nothing looked broken, but the cluster was two
   * different-sized objects. One token drives both. */
  align-items: center;
  background: color-mix(in srgb, var(--radar-canvas) 78%, var(--radar-surface));
  border: 1px solid var(--radar-divider);
  border-radius: 4px;
  display: inline-flex;
  min-height: var(--radar-ribbon-control-h);
  padding: 2px;
}

.radar-flow-pill {
  background: transparent;
  border: 0;
  border-radius: 4px;
  color: var(--radar-muted);
  cursor: pointer;
  font-size: 11px;
  font-weight: 500;
  padding: 5px 16px;
  transition: background 0.15s ease, color 0.15s ease;
  /* A range label is one token. Without this "180 Days" and "1 Year" break
   * across two lines on a phone and the pill row grows to double height —
   * "90 Days" happened to be narrow enough to hide this. */
  white-space: nowrap;
}

.radar-flow-pill:hover {
  color: var(--radar-secondary);
}

.radar-flow-pill.active,
.radar-tf-radio:checked + .radar-flow-pill {
  background: var(--radar-surface);
  box-shadow: 0 1px 2px rgba(18, 32, 51, 0.08);
  color: var(--radar-blue);
  font-weight: 600;
}

.radar-tf-radio:focus-visible + .radar-flow-pill {
  outline: 2px solid var(--radar-blue);
  outline-offset: 2px;
}

/* The plots and the key they belong to. Positioned so the key can sit ON the
 * chart instead of occupying a band above it — the ribbon was three stacked rows
 * of chrome before the reader reached any data, and on a short window that band
 * was competing with the plot for the same scarce vertical space. */
.radar-flow-plots {
  position: relative;
}

.radar-flow-legend {
  /* Top-left of the plot: the corner the series leaves empty (it rises to the
   * right) and clear of the not-yet-reported band label, which is drawn at the
   * band's own left edge well inside the plot. */
  align-items: center;
  column-gap: 14px;
  display: flex;
  /* One line, always. A wrapping legend would grow into the plot and break the
   * fixed clearance the not-yet-reported label is positioned against. */
  flex-wrap: nowrap;
  font-size: 11px;
  left: 6px;
  pointer-events: none;
  position: absolute;
  top: 4px;
  white-space: nowrap;
  /* Above the SVG, below the tooltips the chart raises on hover. */
  z-index: 2;
}

/* On a phone the card is ~343px wide: an overlaid key would cover the plot it
 * explains, and the vertical space it saves is worth less than the legibility it
 * costs. It goes back to being a row of its own. */
@media (max-width: 767px) {
  .radar-flow-legend {
    flex-wrap: wrap;
    margin-bottom: 6px;
    position: static;
    row-gap: 4px;
    white-space: normal;
  }
}

/* How to read the chart — asked once, so it discloses rather than occupying the
 * card permanently. Same `<details>` idiom as "Expand chart", so it needs no
 * JavaScript. Lives beside the heading, not in the legend row. */
.radar-date-basis {
  flex-shrink: 0;
  font-size: 11px;
  font-weight: 400;
  /* Deliberately NOT positioned — the panel anchors to .radar-flow-header. */
}

.radar-date-basis summary {
  align-items: center;
  color: var(--radar-meta);
  cursor: pointer;
  display: inline-flex;
  gap: 4px;
  list-style: none;
  transition: color 0.15s ease;
  white-space: nowrap;
}

.radar-date-basis summary::-webkit-details-marker { display: none; }

.radar-date-basis summary svg {
  height: 13px;
  width: 13px;
}

.radar-date-basis summary:hover {
  color: var(--radar-blue);
}

.radar-date-basis summary:focus-visible {
  border-radius: 4px;
  outline: 2px solid var(--radar-blue);
  outline-offset: 3px;
}

/* Floats over the plot instead of reflowing it: opening a disclosure that
 * pushed the chart down would move the bars out from under the cursor. */
.radar-date-basis-body {
  background: var(--radar-surface);
  border: 1px solid var(--radar-border);
  border-radius: 8px;
  box-shadow: var(--radar-shadow);
  color: var(--radar-secondary);
  font-size: 12px;
  line-height: 1.45;
  margin: 6px 0 0;
  /* Left edge of the card's content, not of the trigger — see the containing
   * block note on .radar-flow-header. The clamp still keeps a narrow viewport
   * honest. */
  left: 0;
  max-width: min(22rem, calc(100vw - 3rem));
  padding: 10px 12px;
  position: absolute;
  top: 100%;
  width: max-content;
  z-index: 5;
}

.radar-date-basis-body p + p,
.radar-date-basis-terms + p {
  margin-top: 8px;
}

/* Three terms, one sentence each. The definitions live here rather than behind a
 * link because a reader who wants to know what a date means is looking at the
 * chart — the separate methodology page they had to go find is gone. */
.radar-date-basis-terms {
  display: grid;
  gap: 7px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.radar-date-basis-terms strong {
  color: var(--radar-ink);
  font-weight: 600;
}

/* One compact marker replaces the old full-height focus stroke, which looked
 * like a stray blue data bar over the plot. */
.radar-chart-point-group {
  outline: none;
}

.radar-active-marker {
  fill: var(--radar-surface);
  opacity: 0;
  pointer-events: none;
  stroke: var(--radar-blue);
  stroke-width: 2;
  transition: opacity 0.12s ease-out;
}

.radar-active-bar-marker {
  fill: var(--radar-surface);
  opacity: 0;
  pointer-events: none;
  stroke: var(--radar-green);
  stroke-width: 2;
  transition: opacity 0.12s ease-out;
}

.radar-chart-point-group[data-has-bar="0"] .radar-active-bar-marker {
  display: none;
}

.radar-chart-point-group[data-bar-kind="deobligation"] .radar-active-bar-marker {
  stroke: var(--radar-red);
}

.radar-chart-point-group:focus-visible .radar-active-marker,
.radar-chart-point-group:focus-within .radar-active-marker,
.radar-chart-point-group.is-active .radar-active-marker,
.radar-chart-point-group:focus-visible .radar-active-bar-marker,
.radar-chart-point-group:focus-within .radar-active-bar-marker,
.radar-chart-point-group.is-active .radar-active-bar-marker {
  opacity: 1;
}

.radar-hover-trigger {
  cursor: pointer;
}

.radar-tooltip-wrapper,
.radar-tooltip-card,
.radar-tooltip-card * {
  font-family: var(--font-ui) !important;
}

.radar-tooltip-wrapper {
  opacity: 0;
  overflow: visible;
  pointer-events: none;
  transition: opacity 0.15s ease-out, transform 0.15s ease-out;
  transform: translateY(4px);
}

.radar-chart-point-group:focus-within .radar-tooltip-wrapper,
.radar-tooltip-wrapper:hover {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}

/* Enhanced charts have one state owner. Native :hover/:focus no longer opens a
 * second card; the controller assigns is-active/is-pinned to exactly one group. */
html.radar-chart-enhanced .radar-chart-point-group:hover .radar-tooltip-wrapper,
html.radar-chart-enhanced .radar-chart-point-group:focus-within .radar-tooltip-wrapper,
html.radar-chart-enhanced .radar-tooltip-wrapper:hover {
  opacity: 0;
  pointer-events: none;
  transform: translateY(4px);
}

html.radar-chart-enhanced .radar-chart-point-group.is-pinned .radar-tooltip-wrapper,
html.radar-chart-enhanced .radar-chart-point-group.is-pinned .radar-tooltip-wrapper:hover {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .radar-active-marker,
  .radar-active-bar-marker,
  .radar-tooltip-wrapper {
    transition: none;
  }
}

.radar-chart-readout {
  border-bottom: 1px solid var(--radar-divider);
  box-sizing: border-box;
  display: grid;
  grid-template-rows: repeat(2, minmax(0, 1fr));
  height: 48px;
  overflow: hidden;
  padding: 5px 2px 7px;
}

.radar-chart-readout-primary {
  color: var(--radar-secondary);
  font-size: 12px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.radar-chart-readout-secondary {
  color: var(--radar-meta);
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.radar-tooltip-card {
  background: var(--radar-surface);
  border: 1px solid var(--radar-border);
  border-radius: 8px;
  box-shadow: 0 10px 30px rgba(18, 32, 51, 0.14);
  box-sizing: border-box;
  color: var(--radar-ink);
  /* 12pt is the minimum reading size for chart evidence. */
  font-size: 12pt;
  line-height: 1.35;
  padding: 16px 18px;
  touch-action: pan-y;
  width: calc(100% - 12px);
  /* The renderer reserves the card's height from an estimate of how many lines
   * the contract description wraps to. An estimate can be short, and a card
   * that outgrows its foreignObject is cut off by the svg viewport with no way
   * to reach what is missing. Capping every card at the height reserved for it
   * turns that failure into a scrollbar. */
  max-height: 100%;
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Cards the renderer already knows are capped — every multi-action card, and
 * any card taller than the plot — keep the gutter so text does not reflow when
 * the scrollbar appears, and take a tab stop so the overflow is reachable
 * without a pointer. */
.radar-tooltip-card-scrollable {
  scrollbar-gutter: stable;
}

.radar-chart-point-group.is-pinned .radar-tooltip-card {
  border-color: color-mix(in srgb, var(--radar-blue) 42%, var(--radar-border));
  box-shadow: 0 12px 34px rgba(18, 32, 51, 0.18);
}

.radar-tooltip-wrapper-right .radar-tooltip-card {
  margin-left: 12px;
}

.radar-tooltip-wrapper-left .radar-tooltip-card {
  margin-right: 12px;
}

.radar-tooltip-agency {
  color: var(--radar-secondary);
  font-size: 12pt;
  font-weight: 600;
  margin-bottom: 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.radar-tooltip-type {
  color: var(--radar-meta);
  font-size: 10pt;
  font-weight: 500;
  letter-spacing: 0.03em;
  margin-top: 2px;
  text-transform: uppercase;
}

.radar-tooltip-amount {
  font-size: 12pt;
  font-weight: 700;
  margin-bottom: 8px;
}

.radar-tooltip-pos {
  color: var(--radar-green);
}

.radar-tooltip-neg {
  color: var(--radar-red);
}

.radar-tooltip-row {
  display: flex;
  flex-direction: column;
  margin-bottom: 5px;
}

.radar-tooltip-sublabel {
  color: var(--radar-meta);
  font-size: 10pt;
  font-weight: 500;
}

.radar-tooltip-value {
  color: var(--radar-ink);
  font-size: 12pt;
  font-weight: 500;
  overflow-wrap: anywhere;
  word-break: break-all;
}

.radar-tooltip-description {
  display: block;
  overflow-wrap: anywhere;
  word-break: normal;
  white-space: normal;
}

.radar-tooltip-events {
  border-top: 1px solid var(--radar-divider);
  margin-top: 6px;
  padding-top: 6px;
}

.radar-tooltip-event-record + .radar-tooltip-event-record {
  border-top: 1px solid var(--radar-divider);
  margin-top: 7px;
  padding-top: 7px;
}

.radar-tooltip-event-title {
  color: var(--radar-secondary);
  font-size: 11pt;
  font-weight: 700;
  margin-bottom: 4px;
}

.radar-tooltip-event-row {
  color: var(--radar-meta);
  font-size: 10pt;
  line-height: 1.35;
  margin-bottom: 4px;
}

.radar-tooltip-event-row strong {
  color: var(--radar-ink);
  display: block;
  font-weight: 500;
  overflow-wrap: anywhere;
}

.radar-tooltip-event-more {
  color: var(--radar-meta);
  font-size: 10pt;
  font-weight: 500;
}

.radar-tooltip-row-spaced {
  margin-top: 6px;
}

.radar-tooltip-running-total {
  color: var(--radar-blue);
  font-size: 12pt;
  margin-bottom: 4px;
}

.radar-flow-legend-left,
.radar-flow-legend-right {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}

.radar-legend-item {
  align-items: center;
  color: var(--radar-meta);
  display: inline-flex;
  font-weight: 500;
  gap: 6px;
}

.radar-chart-instructions {
  color: var(--radar-meta);
  font-size: 11px;
  line-height: 1.4;
  margin: 0 2px 6px;
}

/* Region C — plot: fixed aspect from density height, never absorbs leftover card height. */
.radar-company-page .radar-trend,
.radar-company-page .radar-flow-plot {
  display: block;
  flex: 0 0 auto;
  line-height: 0;
  margin: 0;
  min-height: 0;
}

.radar-company-page .radar-flow-panel {
  flex: 0 0 auto;
  line-height: 0;
  margin: 0;
}

.radar-company-page .radar-trend-svg {
  cursor: crosshair;
  display: block;
  font-family: var(--font-ui);
  /* Height tracks width via viewBox aspect — fixed px heights letterboxed with
     preserveAspectRatio=meet and left a blank band under the x-axis. */
  height: auto;
  margin: 0;
  max-height: none;
  vertical-align: top;
  width: 100%;
}

.radar-tooltip-card,
.radar-tooltip-card * {
  cursor: auto;
}

/*
 * Density-driven plot aspect (viewBox is 1000 × H). Match the box to the
 * viewBox so meet does not introduce vertical letterboxing.
 */
.radar-company-page .radar-trend-svg.radar-plot-h-300 { aspect-ratio: 1000 / 300; }
.radar-company-page .radar-trend-svg.radar-plot-h-310 { aspect-ratio: 1000 / 310; }
.radar-company-page .radar-trend-svg.radar-plot-h-320 { aspect-ratio: 1000 / 320; }
.radar-company-page .radar-trend-svg.radar-plot-h-330 { aspect-ratio: 1000 / 330; }
.radar-company-page .radar-trend-svg.radar-plot-h-340 { aspect-ratio: 1000 / 340; }
.radar-company-page .radar-trend-svg.radar-plot-h-350 { aspect-ratio: 1000 / 350; }
.radar-company-page .radar-trend-svg.radar-plot-h-360 { aspect-ratio: 1000 / 360; }
.radar-company-page .radar-trend-svg.radar-plot-h-370 { aspect-ratio: 1000 / 370; }
.radar-company-page .radar-trend-svg.radar-plot-h-380 { aspect-ratio: 1000 / 380; }
.radar-company-page .radar-trend-svg.radar-plot-h-390 { aspect-ratio: 1000 / 390; }
.radar-company-page .radar-trend-svg.radar-plot-h-400 { aspect-ratio: 1000 / 400; }
.radar-company-page .radar-trend-svg.radar-plot-h-410 { aspect-ratio: 1000 / 410; }
.radar-company-page .radar-trend-svg.radar-plot-h-420 { aspect-ratio: 1000 / 420; }
.radar-company-page .radar-trend-svg.radar-plot-h-430 { aspect-ratio: 1000 / 430; }
.radar-company-page .radar-trend-svg.radar-plot-h-440 { aspect-ratio: 1000 / 440; }
.radar-company-page .radar-trend-svg.radar-plot-h-450 { aspect-ratio: 1000 / 450; }
.radar-company-page .radar-trend-svg.radar-plot-h-460 { aspect-ratio: 1000 / 460; }
.radar-company-page .radar-trend-svg.radar-plot-h-470 { aspect-ratio: 1000 / 470; }
.radar-company-page .radar-trend-svg.radar-plot-h-480 { aspect-ratio: 1000 / 480; }
.radar-company-page .radar-trend-svg.radar-plot-h-490 { aspect-ratio: 1000 / 490; }
.radar-company-page .radar-trend-svg.radar-plot-h-500 { aspect-ratio: 1000 / 500; }
.radar-company-page .radar-trend-svg.radar-plot-h-510 { aspect-ratio: 1000 / 510; }
.radar-company-page .radar-trend-svg.radar-plot-h-520 { aspect-ratio: 1000 / 520; }

.radar-trend-svg text {
  font-family: var(--font-ui);
}

/* Neutral zero baseline — never blue; the running-total stroke stays accent. */
.radar-trend-baseline {
  stroke: var(--radar-border);
  stroke-width: 1;
}

/*
 * Days the Pentagon has not reported through yet.
 *
 * Reads as "we cannot see here", not as a data series: no hue that competes
 * with the green/red/blue the chart already spends, and it sits behind the
 * plot. Deliberately quiet — the stretch covers a large share of the default
 * chart, so anything stronger would dominate the whole figure.
 */
.radar-trend-unreported {
  fill: var(--radar-meta);
  opacity: 0.06;
}

.radar-trend-unreported-label {
  fill: var(--radar-meta);
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.02em;
}

@media (prefers-contrast: more) {
  .radar-trend-unreported {
    opacity: 0.14;
  }
}

.radar-axis-tick {
  fill: var(--radar-meta);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 500;
}

.radar-axis-date {
  fill: var(--radar-meta);
}

/* Semantic series colors: Soft Slate success / danger / accent tokens. */
.radar-trend-bar-award {
  fill: var(--radar-green);
}

.radar-trend-bar-deobligation {
  fill: var(--radar-red);
}

.radar-trend-line {
  fill: none;
  stroke: var(--radar-blue);
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2.75;
}

.radar-line-dot {
  fill: var(--radar-blue);
  stroke: var(--radar-surface);
  stroke-width: 1.25;
}

.radar-trend-area-stop-start {
  stop-color: var(--radar-blue);
  stop-opacity: 0.16;
}

.radar-trend-area-stop-end {
  stop-color: var(--radar-blue);
  stop-opacity: 0.012;
}

.radar-value-pill-bg {
  fill: var(--radar-blue);
}

.radar-value-pill-text {
  fill: #ffffff;
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 700;
}

.radar-label-dot-pos {
  fill: var(--radar-green);
  stroke: var(--radar-surface);
}

.radar-label-dot-neg {
  fill: var(--radar-red);
  stroke: var(--radar-surface);
}

.radar-annotation-amount {
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 700;
}

.radar-annotation-pos {
  fill: var(--radar-green);
}

.radar-annotation-neg {
  fill: var(--radar-red);
}

.radar-annotation-agency {
  fill: var(--radar-secondary);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 500;
}

@media (max-width: 640px) {
  .radar-annotation-agency {
    display: none;
  }
  .radar-flow-legend-left,
  .radar-flow-legend-right {
    gap: 8px;
  }
}

.radar-chart-key {
  color: var(--app-text-muted);
  display: flex;
  flex-wrap: wrap;
  font-size: 0.72rem;
  gap: 16px;
  margin-top: 2px;
}

.radar-chart-key span {
  align-items: center;
  display: inline-flex;
  gap: 6px;
}

.radar-key-swatch {
  display: inline-block;
  height: 8px;
  width: 8px;
}

.radar-key-swatch-award { background: var(--radar-green); border-radius: 1px; }
.radar-key-swatch-deobligation { background: var(--radar-red); border-radius: 1px; }
.radar-key-swatch-total { background: var(--radar-blue); border-radius: 50%; }
/* Pentagon announcement markers — diamond rail, never an obligation bar. */
.radar-key-swatch-announcement {
  background: #1d4ed8;
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
  border-radius: 0;
}
.radar-announcement-diamond {
  fill: #1d4ed8;
  stroke: #0b1220;
  stroke-width: 1;
  opacity: 0.92;
}
.radar-announcement-marker:hover .radar-announcement-diamond {
  fill: #2563eb;
}

@media (max-width: 960px) and (min-width: 768px) {
  .radar-company-layout {
    gap: 16px;
    grid-template-columns: minmax(220px, 250px) minmax(0, 1fr);
  }
  .radar-rail-item {
    padding: 14px 14px;
  }
  .radar-rail-value {
    font-size: 1.6rem;
  }
}

@media (max-width: 767px) {
  /* The matching .radar-index-page narrow-screen rules live with the index-page
   * block below. Both selectors carry the same specificity as their unprefixed
   * base rules, so only source order decides: the company-page bases sit above
   * this block and are overridden here, while the index-page bases sit below it
   * and would win. Keeping each override after its own base is what makes the
   * narrow-screen padding actually apply. */
  .radar-company-page .radar-page > .ds-subnav {
    margin: 0;
    padding: 0 16px;
  }
  .radar-company-report { gap: 10px; margin-top: 16px; padding: 0 16px 20px; }
  .radar-company-report-header { align-items: center; flex-direction: column; gap: 8px; padding-top: 44px; text-align: center; }
  .radar-company-back { left: -10px; top: 0; transform: none; }
  .radar-company-layout { grid-template-columns: minmax(0, 1fr); }
  .radar-summary-rail {
    /* Compact enough that the icon/value relationship reads as one object. */
    justify-self: center;
    max-width: 22rem;
  }
  .radar-flow { padding: 14px 14px 12px; }
  .radar-flow-header { align-items: flex-start; }
  .radar-flow-controls { gap: 8px; }
  .radar-chart-focus-control summary { padding: 0 8px; }
  .radar-flow-footer { flex-direction: column; align-items: start; gap: 6px; }
  /* The freshness line wraps at every width now, so the mobile-only
   * `white-space: normal` this used to carry is redundant. */
  .radar-axis-date-weekly-minor { display: none; }
}

@media (min-width: 721px) and (max-height: 820px) {
  body.app-workspace.radar-company-page main { padding-block: 0 12px; }
  .radar-company-report { gap: 6px; }
  .radar-company-report-header { min-height: 48px; }
  .radar-company-page .radar-company { font-size: 2.25rem; }
  .radar-company-page .radar-section-label { margin-bottom: 2px; }
  .radar-highlights { min-height: 96px; }
  .radar-highlight { gap: 5px; padding: 12px 20px; }
  .radar-highlight strong { font-size: 2.15rem; }
  .radar-flow { padding: 12px 16px 10px; }
}

/* Data context, not brand attribution — sits above the footer action row. */
.radar-freshness {
  color: var(--radar-meta);
  font-size: 0.75rem;
  line-height: 1.5;
  margin: 20px 0 0;
}

.radar-corrections {
  color: var(--radar-muted);
  font-size: 0.75rem;
  line-height: 1.5;
  margin: 8px 0 0;
}

/* Footer: attribution left, history right — preserved at mobile widths. */
.radar-footer {
  align-items: center;
  border-top: 1px solid var(--radar-border);
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: space-between;
  margin-top: 20px;
  padding-top: 14px;
}

.radar-attribution {
  color: var(--radar-muted);
  font-size: 0.75rem;
  font-weight: 500;
}

/* Rendered as a text link, but padded out to a >=44px tap target. The negative
   margin keeps that padding from pushing the footer row apart. Same AA ink as
   .radar-inline-link — --app-accent fails as text on Soft Slate dark. */
.radar-history {
  border-radius: 6px;
  color: var(--radar-blue);
  font-size: 0.8125rem;
  font-weight: 600;
  margin: -12px -8px;
  padding: 12px 8px;
  text-decoration: none;
}

.radar-history:hover {
  color: var(--radar-ink);
  text-decoration: underline;
}

.radar-history:focus-visible {
  outline: 2px solid var(--radar-blue);
  outline-offset: 2px;
}

/* The index is a scan surface, not a single-company report. A company keeps
   its own source-backed page; this grid makes the curated coverage legible at
   a glance without inventing an aggregate score or ranking. */
body.app-workspace.radar-index-page {
  background: var(--radar-canvas);
  color: var(--radar-ink);
}

body.app-workspace.radar-index-page main {
  background: var(--radar-canvas);
  background-image: none;
  color: var(--radar-ink);
  padding: 0 0 3.5rem;
}

.radar-index-page .radar-page {
  max-width: none;
  padding: 0 0 32px;
}

/* Keep dataset context on the same full-bleed rail as IQT; the content below it
   owns the reading measure and the breathing room before the hero. */
.radar-index-page .radar-page > .ds-subnav {
  margin: 0;
  padding: 0 20px;
}

.radar-index-content {
  box-sizing: border-box;
  margin: 0 auto;
  max-width: 1180px;
  padding: 40px 24px 32px;
  width: 100%;
}

/* Narrow screens, kept immediately after the two rules they override. Both
 * selectors match the specificity of their base rules, so an override placed in
 * the company-page media block higher up would lose on source order and the
 * index would silently keep its 24px desktop gutter on a 375px screen. */
@media (max-width: 767px) {
  .radar-index-page .radar-page > .ds-subnav {
    margin: 0;
    padding: 0 16px;
  }

  .radar-index-content { padding: 28px 16px 24px; }
}

/* 880px, not 760: the intro sentence needs 797px to sit on one line, and at the
   old cap it broke onto a second for the sake of 37px. */
.radar-index-hero {
  margin: 0 auto 28px;
  max-width: 880px;
  text-align: center;
}

.radar-index-page .radar-company {
  color: var(--radar-ink);
  font-size: clamp(1.65rem, 3vw, 2.35rem);
  letter-spacing: 0.06em;
}

.radar-index-intro {
  color: var(--radar-secondary);
  font-size: 1rem;
  line-height: 1.6;
  margin: 12px 0 0;
}

/* Three columns at the full measure, two when the viewport cannot hold three,
   one on a phone — decided by the track size rather than by breakpoints, so the
   count follows the space instead of a guess about it. Nine cards divide into
   three rows exactly. */
.radar-index-list {
  display: grid;
  gap: 18px;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  list-style: none;
  margin: 0;
  padding: 0;
}

/* The IQT card takes the shared card metric — same size, same accent — because
   it is one of the set now, not a hero above it. The standalone overrides (its
   own min-height, its own green display metric) are gone with the hero. */

/*
 * ── Data Sets workspace ──────────────────────────────────────────────────────
 *
 * A fixed-height workspace, not a scrolling document: the page fills the
 * viewport once and every region owns its own overflow, so the filters and the
 * column headers never leave the screen. The structure, the metrics and the
 * collapse-on-close behaviour mirror the Editor's investigation workspace
 * (style.css, `.investigation-*`) so the two read as one system; the names are
 * `ds-` because Data Sets is the surface, and Federal Contract Radar is meant
 * to adopt this frame next.
 *
 * Tokens are the shared `--app-*` set. Nothing here introduces a palette.
 */

body.app-workspace.ds-page main {
  background: var(--app-bg);
  background-image: none;
  padding: 0;
}

.ds-page .radar-page {
  max-width: none;
  padding: 0;
}

.ds-workspace {
  /* Site ribbon (sticky) + its rule. The workspace claims exactly what is left,
     which is what keeps the document itself from scrolling. */
  --ds-chrome: calc(var(--shell-row-min-height, 56px) + 1px);
  --ds-gap: 12px;
  /* --ds-accent-text is declared on .radar-body, not here — see the note there.
     The sub-navigation now renders outside this workspace. */

  box-sizing: border-box;
  color: var(--app-text);
  display: flex;
  flex-direction: column;
  gap: var(--ds-gap);
  /* A floor, so a short window scrolls the page rather than crushing the panes. */
  height: max(560px, calc(100svh - var(--ds-chrome)));
  padding: 0 20px 16px;
}

.ds-subnav {
  border-bottom: 1px solid var(--app-border);
  display: flex;
  gap: 4px;
  margin: 0 -20px;
  overflow-x: auto;
  padding: 0 20px;
}

.ds-tab {
  border-bottom: 2px solid transparent;
  color: var(--app-text-muted);
  font-size: 0.8125rem;
  font-weight: 650;
  line-height: 1;
  padding: 15px 12px 13px;
  text-decoration: none;
  white-space: nowrap;
}

.ds-tab:hover {
  color: var(--app-text);
}

/* "page" on a dataset's own landing page, "true" on a document inside that
   dataset — a company report. Both are the active tab and look identical; only
   what they announce differs. */
.ds-tab[aria-current="page"],
.ds-tab[aria-current="true"] {
  border-bottom-color: var(--app-accent);
  color: var(--ds-accent-text);
}

.ds-tab:focus-visible {
  border-radius: 6px;
  outline: 3px solid var(--app-focus-ring);
  outline-offset: -2px;
}

.ds-titlebar {
  display: grid;
  gap: 4px;
}

.ds-title {
  font-size: 1.5rem;
  font-weight: 650;
  letter-spacing: -0.01em;
  line-height: 1.2;
  margin: 0;
}

.ds-meta {
  align-items: baseline;
  color: var(--app-text-muted);
  display: flex;
  flex-wrap: wrap;
  font-size: 0.8125rem;
  gap: 4px 18px;
}

.ds-meta strong {
  color: var(--app-text);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.ds-meta-note {
  color: var(--app-text-tertiary);
}

/* The contextual column. `data-inspector="closed"` drops the third track
   entirely rather than emptying it, so closing the inspector hands the width
   back to the table instead of leaving a gap where a panel used to be. */
.ds-body {
  display: grid;
  flex: 1;
  gap: var(--ds-gap);
  grid-template-columns: 232px minmax(0, 1fr) minmax(280px, 22vw);
  min-height: 0;
}

.ds-workspace[data-inspector="closed"] .ds-body {
  grid-template-columns: 232px minmax(0, 1fr);
}

/* A surface with no rail — the index — never renders the track at all, rather
   than rendering an empty one. Same rule as the inspector: a region that is not
   there gives its width back. */
.ds-workspace[data-rail="none"] .ds-body {
  grid-template-columns: minmax(0, 1fr);
}

.ds-workspace[data-rail="none"][data-inspector="open"] .ds-body {
  grid-template-columns: minmax(0, 1fr) minmax(280px, 22vw);
}

.ds-rail,
.ds-main,
.ds-inspector {
  min-height: 0;
  min-width: 0;
}

.ds-rail,
.ds-inspector {
  background: var(--app-surface-1);
  border: 1px solid var(--app-border);
  border-radius: 12px;
  overflow-y: auto;
  padding: 14px;
}

.ds-main {
  display: flex;
  flex-direction: column;
  gap: var(--ds-gap);
  overflow: hidden;
}

.ds-panel {
  background: var(--app-surface-1);
  border: 1px solid var(--app-border);
  border-radius: 12px;
  min-height: 0;
}

.ds-panel-facets {
  flex: 0 0 auto;
  padding: 12px 14px 10px;
}

/* The table takes whatever the tiles leave. Tiles wrap as the column narrows, so
   this pane absorbs the change instead of the page growing a scrollbar. */
.ds-panel-table {
  display: flex;
  flex: 1;
  flex-direction: column;
  /* A floor for the work surface: below this the table stops being a table. If
     the viewport cannot afford it, the workspace's own min-height gives up and
     the page scrolls instead of the pane collapsing. */
  min-height: 260px;
  overflow: hidden;
}

.ds-panel-head {
  align-items: center;
  display: flex;
  gap: 12px;
  justify-content: space-between;
  min-height: 34px;
}

.ds-panel-table .ds-panel-head {
  border-bottom: 1px solid var(--app-border);
  padding: 10px 14px;
}

.ds-panel-title {
  color: var(--app-text);
  font-size: 0.9375rem;
  font-weight: 650;
  margin: 0;
}

.ds-panel-title span {
  color: var(--app-text-muted);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
}

.ds-panel-qualifier {
  font-size: 0.8125rem;
}

.ds-note {
  color: var(--app-text-tertiary);
  font-size: 0.75rem;
  line-height: 1.4;
  margin: 8px 0 0;
}

.ds-empty {
  color: var(--app-text-muted);
  font-size: 0.8125rem;
  margin: 0;
}

/* ── Summary tiles ─────────────────────────────────────────────────────────
   Buttons, not cards: each tile both reports its slice and applies it as a
   filter, so the summary and the control are one thing. auto-fit means they
   reflow as the inspector opens and closes without a breakpoint. */
/* One band, always. Wrapping to a second row cost the table ~150px of height,
   and at 1280 with the inspector open that left two visible rows — the summary
   ate the thing it summarises. A single row keeps the facets panel a fixed
   height whatever the column width, and scrolls sideways when eight will not
   fit. The table, which is the work surface, keeps the rest. */
.ds-tiles {
  display: grid;
  gap: 8px;
  grid-auto-columns: minmax(124px, 1fr);
  grid-auto-flow: column;
  margin-top: 10px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  padding-bottom: 2px;
}

.ds-tile {
  background: var(--app-surface-2);
  border: 1px solid transparent;
  border-radius: 10px;
  cursor: pointer;
  display: grid;
  font: inherit;
  gap: 4px;
  padding: 9px 10px 10px;
  text-align: left;
  transition:
    background-color 140ms cubic-bezier(0.25, 1, 0.5, 1),
    border-color 140ms cubic-bezier(0.25, 1, 0.5, 1);
}

.ds-tile:hover {
  background: var(--app-surface-3);
}

.ds-tile.is-selected {
  background: var(--app-accent-soft);
  border-color: var(--app-accent);
}

.ds-tile:focus-visible {
  outline: 3px solid var(--app-focus-ring);
  outline-offset: 2px;
}

.ds-tile-label {
  color: var(--app-text-muted);
  font-size: 0.75rem;
  font-weight: 650;
  line-height: 1.25;
  /* Two lines' worth, always. "Microelectronics & Quantum" wraps and its
     neighbours do not; without a floor its number and bar sat a line lower than
     every other tile's. */
  min-height: 2.5em;
}

.ds-tile.is-selected .ds-tile-label {
  color: var(--ds-accent-text);
}

.ds-tile-total {
  color: var(--app-text);
  font-size: 1.25rem;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  line-height: 1.1;
}

/* Geometry is an SVG attribute because the page CSP forbids inline styles; the
   two rects carry the active/exited split the mock drew as a dot matrix. */
.ds-tile-bar {
  display: block;
  height: 4px;
  width: 100%;
}

.ds-tile-bar-track {
  fill: var(--radar-amber);
}

.ds-tile-bar-active {
  fill: var(--radar-green);
}

.ds-tile-split {
  color: var(--app-text-tertiary);
  font-size: 0.6875rem;
  font-variant-numeric: tabular-nums;
}

/* ── Rail ──────────────────────────────────────────────────────────────────*/
.ds-rail-head {
  margin-bottom: 10px;
}

.ds-rail-title {
  font-size: 0.9375rem;
  font-weight: 650;
  margin: 0;
}

.ds-field {
  margin-bottom: 10px;
}

.ds-search {
  background: var(--app-surface-2);
  border: 1px solid var(--app-border-strong);
  border-radius: 8px;
  box-sizing: border-box;
  color: var(--app-text);
  font: inherit;
  font-size: 0.8125rem;
  min-height: 36px;
  padding: 0 10px;
  width: 100%;
}

.ds-search::placeholder {
  /* --app-text-tertiary, not a lighter grey: placeholder text needs the same
     4.5:1 as body copy, and the usual "muted" default does not clear it. */
  color: var(--app-text-tertiary);
}

.ds-search:focus-visible {
  border-color: var(--app-accent);
  outline: 3px solid var(--app-focus-ring);
  outline-offset: 1px;
}

.ds-segmented {
  background: var(--app-surface-2);
  border: 1px solid var(--app-border);
  border-radius: 8px;
  display: inline-flex;
  gap: 2px;
  padding: 2px;
}

.ds-segment {
  background: transparent;
  border: 0;
  border-radius: 6px;
  color: var(--app-text-muted);
  cursor: pointer;
  flex: 1;
  font: inherit;
  font-size: 0.75rem;
  font-weight: 650;
  min-height: 28px;
  padding: 0 9px;
  white-space: nowrap;
}

.ds-segment span {
  color: var(--app-text-tertiary);
  font-variant-numeric: tabular-nums;
}

.ds-segment:hover {
  color: var(--app-text);
}

.ds-segment[aria-pressed="true"] {
  background: var(--app-surface-1);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.08);
  color: var(--app-text);
}

.ds-segment[aria-pressed="true"] span {
  color: var(--app-text-muted);
}

.ds-segment:focus-visible {
  outline: 3px solid var(--app-focus-ring);
  outline-offset: 1px;
}

.ds-group {
  border: 0;
  margin: 0 0 14px;
  padding: 0;
}

.ds-group-legend {
  color: var(--app-text);
  font-size: 0.75rem;
  font-weight: 650;
  padding: 0;
}

.ds-group-legend span {
  color: var(--app-text-tertiary);
  font-weight: 500;
}

.ds-option {
  align-items: center;
  border-radius: 6px;
  cursor: pointer;
  display: grid;
  font-size: 0.8125rem;
  gap: 8px;
  grid-template-columns: auto minmax(0, 1fr) auto;
  min-height: 30px;
  padding: 0 4px;
}

.ds-option:hover {
  background: var(--app-surface-2);
}

.ds-option input {
  accent-color: var(--app-accent);
  margin: 0;
}

.ds-option input:focus-visible {
  outline: 3px solid var(--app-focus-ring);
  outline-offset: 2px;
}

.ds-option-label {
  color: var(--app-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ds-option-count {
  color: var(--app-text-tertiary);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
}

/* Pinned to the foot of the rail. With seven focus values and six regions the
   rail scrolls, and "clear all" is exactly the control a reader wants when they
   have scrolled far enough to lose track of what they applied. */
.ds-rail-foot {
  background: var(--app-surface-1);
  border-top: 1px solid var(--app-border);
  bottom: -14px;
  margin-top: auto;
  padding: 12px 0;
  position: sticky;
}

.ds-rail {
  display: flex;
  flex-direction: column;
}

.ds-button {
  background: var(--app-surface-1);
  border: 1px solid var(--app-border-strong);
  border-radius: 8px;
  color: var(--app-text);
  cursor: pointer;
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 650;
  min-height: 36px;
  padding: 0 12px;
  width: 100%;
}

.ds-button:hover {
  border-color: var(--app-accent);
  color: var(--ds-accent-text);
}

.ds-button:focus-visible {
  outline: 3px solid var(--app-focus-ring);
  outline-offset: 2px;
}

/* ── Table ─────────────────────────────────────────────────────────────────*/
.ds-table-scroll {
  flex: 1;
  min-height: 120px;
  overflow: auto;
}

.ds-table {
  border-collapse: separate;
  border-spacing: 0;
  font-size: 0.8125rem;
  width: 100%;
}

.ds-table th,
.ds-table td {
  border-bottom: 1px solid var(--app-border);
  padding: 9px 12px;
  text-align: left;
  vertical-align: middle;
}

.ds-table th:first-child,
.ds-table td:first-child {
  padding-left: 14px;
}

.ds-table th:last-child,
.ds-table td:last-child {
  padding-right: 14px;
}

.ds-table thead th {
  background: var(--app-bg-subtle);
  color: var(--app-text-muted);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  position: sticky;
  text-transform: uppercase;
  top: 0;
  z-index: 2;
}

.ds-table tbody tr {
  transition: background-color 140ms cubic-bezier(0.25, 1, 0.5, 1);
}

.ds-table tbody tr:hover {
  background: var(--app-surface-2);
}

.ds-table tbody tr.is-selected {
  background: var(--app-accent-soft);
}

.ds-cell-company {
  width: 26%;
}

.ds-cell-focus {
  width: 30%;
}

.ds-cell-region {
  width: 18%;
}

.ds-cell-status {
  width: 13%;
}

.ds-cell-order {
  font-variant-numeric: tabular-nums;
  text-align: right;
  width: 13%;
}

/* Nothing at rest said the company name opened anything. The chevron is the
   row's affordance; it is aria-hidden because the name button is the control a
   screen reader is given. */
.ds-cell-open {
  color: var(--app-text-tertiary);
  text-align: right;
  width: 28px;
}

.ds-table tbody tr:hover .ds-cell-open,
.ds-table tbody tr.is-selected .ds-cell-open {
  color: var(--ds-accent-text);
}

.ds-table td {
  color: var(--app-text-muted);
}

/* The company cell is the row's control. A button rather than a link because it
   selects a record in this workspace; it does not navigate away. */
.ds-row-select {
  background: transparent;
  border: 0;
  border-radius: 4px;
  color: var(--app-text);
  cursor: pointer;
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 650;
  padding: 0;
  text-align: left;
}

.ds-row-select:hover {
  color: var(--ds-accent-text);
}

.ds-row-select:focus-visible {
  outline: 3px solid var(--app-focus-ring);
  outline-offset: 3px;
}

.ds-chip {
  border: 1px solid var(--app-border);
  border-radius: 6px;
  color: var(--app-text-muted);
  display: inline-block;
  font-size: 0.6875rem;
  margin: 1px 4px 1px 0;
  padding: 2px 7px;
  white-space: nowrap;
}

.ds-sort {
  background: transparent;
  border: 0;
  color: inherit;
  cursor: pointer;
  font: inherit;
  letter-spacing: inherit;
  padding: 0;
  text-transform: inherit;
}

.ds-sort:hover {
  color: var(--app-text);
}

.ds-sort.is-active {
  color: var(--ds-accent-text);
}

.ds-sort.is-active::after {
  content: " ↑";
}

.ds-sort.is-active[data-ds-direction="desc"]::after {
  content: " ↓";
}

.ds-sort:focus-visible {
  border-radius: 4px;
  outline: 3px solid var(--app-focus-ring);
  outline-offset: 3px;
}

.ds-panel-foot {
  align-items: center;
  border-top: 1px solid var(--app-border);
  display: flex;
  gap: 12px;
  justify-content: space-between;
  min-height: 44px;
  padding: 6px 14px;
}

.ds-showing {
  color: var(--app-text-tertiary);
  font-size: 0.75rem;
  margin: 0;
}

.ds-pager {
  align-items: center;
  display: flex;
  gap: 6px;
}

.ds-pager-status {
  color: var(--app-text-muted);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  min-width: 90px;
  text-align: center;
}

.ds-icon-button {
  align-items: center;
  /* Never grow. As a flex child of the inspector head it stretched into a
     32px-tall band across half the panel. */
  flex: 0 0 auto;
  background: var(--app-surface-1);
  border: 1px solid var(--app-border-strong);
  border-radius: 8px;
  color: var(--app-text);
  cursor: pointer;
  display: inline-flex;
  font: inherit;
  font-size: 0.875rem;
  height: 32px;
  justify-content: center;
  min-width: 32px;
}

.ds-icon-button:hover:enabled {
  border-color: var(--app-accent);
  color: var(--ds-accent-text);
}

.ds-icon-button:disabled {
  color: var(--app-text-tertiary);
  cursor: default;
  opacity: 0.55;
}

.ds-icon-button:focus-visible {
  outline: 3px solid var(--app-focus-ring);
  outline-offset: 2px;
}

/* ── Inspector ─────────────────────────────────────────────────────────────*/
.ds-inspector-head {
  align-items: start;
  display: flex;
  gap: 10px;
  justify-content: space-between;
}

.ds-inspector-title {
  font-size: 1.0625rem;
  font-weight: 650;
  line-height: 1.25;
  margin: 0;
}

.ds-inspector-status {
  margin: 5px 0 0;
}

.ds-inspector-body {
  display: grid;
  gap: 14px;
  margin: 16px 0 0;
}

.ds-inspector-field dt {
  color: var(--app-text-muted);
  font-size: 0.75rem;
  font-weight: 650;
}

.ds-inspector-field dd {
  color: var(--app-text);
  font-size: 0.8125rem;
  line-height: 1.5;
  margin: 5px 0 0;
}

.ds-inspector-qualifier {
  color: var(--app-text-tertiary);
  font-size: 0.75rem;
}

.ds-inspector-absent {
  color: var(--app-text-tertiary);
}

.ds-inspector-links {
  display: grid;
  gap: 6px;
  justify-items: start;
}

.ds-panel-unavailable {
  padding: 20px;
}

.ds-panel-unavailable p {
  color: var(--app-text-muted);
  margin: 8px 0 0;
}

@media (prefers-reduced-motion: reduce) {
  .ds-tile,
  .ds-table tbody tr {
    transition: none;
  }
}

/* Below this the three columns cannot coexist: the rail and the inspector both
   need real width, and a fixed-height frame on a phone fights the URL bar. The
   workspace releases its height and becomes an ordinary scrolling column, with
   the inspector as a block above the table it describes. */
@media (max-width: 1023px) {
  .ds-workspace {
    height: auto;
    min-height: 0;
    padding: 0 16px 24px;
  }

  .ds-subnav {
    margin: 0 -16px;
    padding: 0 16px;
  }

  .ds-body,
  .ds-workspace[data-inspector="closed"] .ds-body {
    grid-template-columns: minmax(0, 1fr);
  }

  .ds-panel-head {
    align-items: flex-start;
    flex-direction: column;
    gap: 4px;
  }

  /* 781px of filters before the data is not a filter rail, it is a wall. Bounded
     with its own scroll so the table stays reachable; the clear button is still
     pinned inside it. */
  .ds-rail {
    max-height: 320px;
  }

  .ds-inspector {
    order: -1;
    overflow-y: visible;
  }

  .ds-table-scroll {
    max-height: 60vh;
  }

  /* Five columns cannot fit a phone. The table scrolls inside its own region
     rather than crushing the company names; the page still never scrolls
     sideways. */
  .ds-table {
    min-width: 620px;
  }
}

/* Pill form, used only where badges are rare enough to read as accents: the ten
   latest entries. */
.radar-iqt-state {
  font-size: 0.8125rem;
  font-weight: 600;
  white-space: nowrap;
}

.radar-iqt-state::before {
  background: currentColor;
  border-radius: 50%;
  content: "";
  display: inline-block;
  height: 6px;
  margin-right: 8px;
  vertical-align: 0.08em;
  width: 6px;
}

.radar-iqt-state-active {
  color: var(--radar-green);
}

.radar-iqt-state-exited {
  color: var(--radar-amber);
}

/* The card fills its grid cell. The <li> stretches to the tallest card in its
   row but the <a> inside it did not, so a row containing the taller IQT card
   left its neighbour's bottom edge floating 24px short. */
.radar-index-item {
  /* The metric sizes off the CARD, not the viewport (see .radar-index-metric).
     With a viewport unit, narrowing from two columns to three left a 54px
     "458 companies" in a 365px card. */
  container-type: inline-size;
  display: flex;
  min-width: 0;
}

.radar-index-item > .radar-index-link {
  flex: 1;
}

.radar-index-link {
  background: var(--radar-surface);
  border: 1px solid var(--radar-border);
  border-radius: 12px;
  box-shadow: var(--radar-shadow);
  color: var(--radar-ink);
  display: flex;
  flex-direction: column;
  min-height: 250px;
  padding: 24px;
  text-align: center;
  text-decoration: none;
  transition: background-color 160ms ease, border-color 160ms ease, transform 160ms ease;
}

.radar-index-link:hover {
  background: color-mix(in srgb, var(--radar-blue) 5%, var(--radar-surface));
  border-color: color-mix(in srgb, var(--radar-blue) 42%, var(--radar-border));
  transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
  .radar-index-link {
    transition: background-color 160ms ease, border-color 160ms ease;
  }

  .radar-index-link:hover {
    transform: none;
  }
}

.radar-index-link:focus-visible {
  outline: 3px solid var(--radar-blue);
  outline-offset: 3px;
}

/* An h2, not a span: nine links under a lone h1 gave a screen reader no way to
   move between entries. Visually unchanged — the heading defaults are reset. */
.radar-index-name {
  margin: 0;
  color: var(--radar-ink);
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.radar-index-metric {
  color: var(--radar-blue);
  /* cqi, not vw: the card is the constraint, not the window. The longest metric
     the set can hold is "458 companies" at ~7.4x its own font size, so 10cqi
     keeps it — and a four-digit count — inside the card's padding at every
     column count, including the 320px card where auto-fit first allows three. */
  font-size: clamp(1.75rem, 10cqi, 3.4rem);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: -0.04em;
  line-height: 1;
  margin-top: 34px;
  /* A flex item will not shrink below its content by default, so a metric too
     wide for its card would push past the padding rather than wrap. This holds
     to a four-digit count at the narrowest card the grid produces; beyond that
     it wraps, which is recoverable, instead of overflowing, which is not. */
  min-width: 0;
}

/*
 * A value and its unit, both at the metric's size.
 *
 * Two smaller-unit attempts failed for the same reason: at a ~4:1 size ratio
 * nothing aligns convincingly. A shared baseline drops the word onto the
 * numeral's floor; centring it on the numeral fixes the level but leaves a tiny
 * word floating beside a huge one, and centring the pair as a box shoves the
 * numeral off the card's axis because the eye centres on the heavy element.
 *
 * At one size the pair reads as a phrase — the way "+$5.17M" carries its own
 * prefix and suffix — so it takes the plain centred metric line and inherits the
 * metric outright: size, colour AND weight. A lighter unit beside a 700 numeral
 * is a visible stroke-width break at 54px; it read as two typefaces butted
 * together rather than as one figure.
 *
 * The only thing not inherited is the metric's -0.04em display tracking, which
 * is set for large numerals. At this size it is ~2.2px a letter, which closes up
 * lowercase counters — the correction a word needs, not a style difference.
 */
/* No margin: the gap is a real space in the markup now. It was a CSS margin,
   which meant the rendered text was literally "458companies" — a screen reader
   read one token, and the space existed only for people who could see it. */
.radar-index-metric-unit {
  letter-spacing: 0;
}

.radar-index-summary {
  color: var(--radar-meta);
  margin-top: 52px;
}

.radar-index-summary {
  color: var(--radar-muted);
  font-size: 0.875rem;
  line-height: 1.5;
  margin-top: 12px;
  /* Centred text with a ragged second line reads as a mistake. Longer agency
     names ("Department of Homeland Security · Jul 21") wrap here, so balance
     the two lines rather than leaving a one-word stub under a full one. */
  text-wrap: balance;
}

.radar-index-action {
  color: var(--radar-blue);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  margin-top: auto;
  padding-top: 24px;
  text-transform: uppercase;
}

/*
 * Quiet coverage, named under the grid.
 *
 * Deliberately a sentence and not a card: the whole point of dropping the empty
 * cards was that absence should not spend a report's visual weight. This keeps
 * the page reachable — it was the only inbound link — at the cost of one line.
 * Sized with the disclaimer rather than the cards for the same reason.
 */
.radar-index-also {
  color: var(--radar-meta);
  font-size: 0.8125rem;
  line-height: 1.6;
  margin: 24px 0 0;
  text-align: center;
}

.radar-index-also a {
  color: inherit;
  text-decoration-color: var(--app-border);
  text-underline-offset: 3px;
}

.radar-index-also a:hover,
.radar-index-also a:focus-visible {
  color: var(--radar-blue);
  text-decoration-color: currentColor;
}

.radar-index-disclaimer {
  /* --radar-meta, not --app-text-tertiary: the latter is 4.27:1 on this canvas,
     under AA for 12px. It read as "muted" only because it used to sit on the
     hardcoded dark index, where it was worse still (~3.5:1). */
  color: var(--radar-meta);
  font-size: 0.75rem;
  line-height: 1.5;
  margin: 10px 0 0;
  text-align: center;
}

.radar-index-page .radar-freshness {
  color: var(--radar-meta);
  margin: 24px auto 0;
  max-width: 760px;
  text-align: center;
}

.radar-prose {
  line-height: 1.65;
  max-width: 68ch;
}

.radar-prose h2 {
  font-size: 0.9375rem;
  font-weight: 600;
  margin: 24px 0 0;
}

.radar-prose p {
  color: var(--app-text-muted);
  font-size: 0.875rem;
  margin: 6px 0 0;
}

.radar-prose strong {
  color: var(--app-text);
}

.radar-definitions {
  display: grid;
  gap: 18px;
  list-style: none;
  margin: 18px 0 0;
  padding: 0;
}

.radar-definitions li {
  display: grid;
  gap: 3px;
}

.radar-definitions > li > strong {
  color: var(--app-text);
  font-size: 0.9375rem;
  font-weight: 600;
}

.radar-definitions span {
  color: var(--app-text-muted);
  font-size: 0.875rem;
}

.radar-todo {
  border-top: 1px solid var(--app-border);
  color: var(--app-text-tertiary);
  font-size: 0.75rem;
  margin-top: 24px;
  padding-top: 14px;
}

/* Desktop expands the mobile hierarchy; it does not replace it. */
@media (min-width: 720px) {
  .radar-page {
    padding: 0 24px;
  }

  .radar-card {
    padding: 36px 32px 24px;
  }

  .radar-amount {
    font-size: 3.5rem;
  }
}

@media (max-width: 560px) {
  .radar-index-link {
    min-height: 220px;
  }
}

/* ── Weekly digest signup ────────────────────────────────────────────────────
 *
 * Sits at the foot of every Data Sets page. Deliberately quiet: it follows a
 * page whose whole claim is that the numbers above it are checkable, and a
 * loud conversion band directly under a source-linked record reads as an
 * advertisement attached to evidence.
 */
.radar-subscribe {
  box-sizing: border-box;
  width: 100%;
  margin: 56px 0 0;
  padding: 28px 0 40px;
  border-top: 1px solid var(--radar-divider);
}

/*
 * Alignment is per page context, because .radar-page is a different box on each
 * one. On an event page it is the 560px measure and this section inherits it;
 * on a company page it is the wide report card and the section fills it like
 * the report above. The index is the exception: there .radar-page runs the full
 * viewport and its one child carries the measure, so an un-inset section drew
 * its rule the whole window wide under cards that stopped 50px from each edge.
 * The 1180px and the gutters are .radar-index-content's own, repeated so the
 * rule lands under the text rather than 24px outside it.
 */
.radar-index-page .radar-subscribe {
  max-width: 1180px;
  margin-inline: auto;
  padding-right: 24px;
  padding-left: 24px;
}

/* Matches the 767px index gutter change further up, for the same reason. */
@media (max-width: 767px) {
  .radar-index-page .radar-subscribe {
    padding-right: 16px;
    padding-left: 16px;
  }
}

.radar-subscribe__title {
  margin: 0 0 6px;
  color: var(--radar-ink);
  font-family: var(--font-ui);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.radar-subscribe__lede {
  margin: 0 0 18px;
  color: var(--radar-meta);
  font-family: var(--font-ui);
  font-size: 0.9375rem;
  line-height: 1.5;
  max-width: 46ch;
}

.radar-subscribe__form {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  /* A single-field form does not get wider just because the page did. */
  max-width: 420px;
}

/* The label is read by screen readers; the placeholder is not a label. */
.radar-subscribe__label {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

.radar-subscribe__input {
  flex: 1 1 220px;
  min-width: 0;
  box-sizing: border-box;
  padding: 10px 12px;
  border: 1px solid var(--radar-border);
  border-radius: 6px;
  background: var(--radar-surface);
  color: var(--radar-ink);
  font-family: var(--font-ui);
  font-size: 0.9375rem;
}

.radar-subscribe__input:focus-visible {
  outline: 2px solid var(--app-focus-ring);
  outline-offset: 1px;
}

/*
 * Honeypot. Off-screen rather than `display: none` or `hidden`: form-filling
 * bots skip fields the browser reports as hidden, and this one only works if
 * they can see it. aria-hidden and tabindex keep it away from real people.
 */
.radar-subscribe__trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.radar-subscribe__button {
  flex: 0 0 auto;
  padding: 10px 18px;
  border: 1px solid var(--radar-blue);
  border-radius: 6px;
  background: var(--radar-blue);
  color: var(--radar-canvas);
  font-family: var(--font-ui);
  font-size: 0.9375rem;
  font-weight: 600;
  cursor: pointer;
}

.radar-subscribe__button:hover {
  filter: brightness(1.08);
}

.radar-subscribe__button:focus-visible {
  outline: 2px solid var(--app-focus-ring);
  outline-offset: 2px;
}

.radar-subscribe__button[disabled] {
  cursor: default;
  opacity: 0.6;
}

/*
 * Reserves its line whether or not it holds a message, so an answer does not
 * shove the note underneath it down the page as the reader is reading it.
 */
.radar-subscribe__status {
  margin: 10px 0 0;
  min-height: 1.35em;
  color: var(--radar-meta);
  font-family: var(--font-ui);
  font-size: 0.875rem;
  line-height: 1.35;
}

.radar-subscribe__status[data-tone="ok"] {
  color: var(--radar-green);
}

.radar-subscribe__status[data-tone="error"] {
  color: var(--radar-red);
}

.radar-subscribe__note {
  margin: 6px 0 0;
  color: var(--app-text-tertiary);
  font-family: var(--font-ui);
  font-size: 0.8125rem;
}
