/* Macro dashboard — dark, typographic, AlphaHunterz.
   Surfaces, type and spacing are deliberately identical to the strategy dashboard so the two
   read as siblings. The SERIES palette differs: this page carries far more categorical data,
   and the sector colours used there fail the colour-vision gates at this density
   (Health Care vs Industrials measured at normal-vision dE 6.2 against a floor of 15).
   See docs/design_system.md. */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');

:root {
  --bg: #0b0e14;
  --panel: #141922;
  --panel2: #1b2230;
  --border: #242c3a;
  --text: #e6edf6;
  --muted: #8494ad;
  --accent: #4db6e8;
  --green: #3ecf8e;
  --red: #f2615c;
  --amber: #f2c94c;
}

html, body, #root { background: var(--bg) !important; }
body {
  color: var(--text);
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  -webkit-font-smoothing: antialiased;
}
.wrap { max-width: 1320px; padding: 0 1.25rem 4rem; }
a { color: var(--accent); }

/* ---------------- hero ---------------- */
.hero {
  display: flex; gap: 2rem; align-items: center; justify-content: space-between;
  flex-wrap: wrap; max-width: 1320px; margin: 0 auto; padding: 2.5rem 1.25rem 1.5rem;
}
.hero-left { flex: 1 1 520px; }
.hero-mark { height: 62px; width: auto; display: block; margin-bottom: 1rem; }
.hero-h {
  font-size: clamp(1.9rem, 4.2vw, 2.9rem); font-weight: 700; letter-spacing: -0.02em;
  margin: 0 0 .5rem; line-height: 1.08;
}
.hero-sub { color: var(--muted); font-size: 1.02rem; margin: 0 0 1rem; max-width: 62ch; }
.pill-row { display: flex; gap: .5rem; flex-wrap: wrap; }
.pill {
  font-size: .72rem; letter-spacing: .04em; text-transform: uppercase;
  padding: .28rem .6rem; border-radius: 999px;
  border: 1px solid var(--border); color: var(--muted); background: var(--panel);
}
.pill-live { color: var(--green); border-color: rgba(62,207,142,.35); }
.pill-live::before {
  content: ''; display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: var(--green); margin-right: .4rem; vertical-align: middle;
}

/* ---------------- KPI ---------------- */
.kpi-row { display: grid; gap: .9rem; grid-template-columns: repeat(5, minmax(0, 1fr)); }
@media (max-width: 1100px) { .kpi-row { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 640px) {
  .kpi-row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .65rem; }
  .kpi-row > :last-child:nth-child(odd) { grid-column: 1 / -1; }
}
.kpi {
  background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
  padding: 1rem 1.1rem; height: 100%;
}
.kpi-l { color: var(--muted); font-size: .74rem; text-transform: uppercase; letter-spacing: .06em; }
.kpi-v { font-size: 1.65rem; font-weight: 650; margin-top: .25rem; letter-spacing: -.02em;
         font-variant-numeric: tabular-nums; }
.kpi-v.pos { color: var(--green); }
.kpi-v.neg { color: var(--red); }
.kpi-s { color: var(--muted); font-size: .78rem; margin-top: .15rem; line-height: 1.35; }

/* ---------------- sections ---------------- */
.sec { margin-top: 3.25rem; }
.sec-h {
  font-size: 1.45rem; font-weight: 650; letter-spacing: -.015em; margin-bottom: .4rem;
  padding-bottom: .6rem; border-bottom: 1px solid var(--border);
}
.sec-sub { color: var(--muted); font-size: .92rem; max-width: 84ch; margin: .75rem 0 1.25rem;
           line-height: 1.6; }
.body-p { color: #c7d3e3; line-height: 1.68; margin-bottom: .9rem; max-width: 84ch; }

/* the provenance strip under every chart: universe, weighting, coverage, history start */
.prov {
  color: var(--muted); font-size: .72rem; margin-top: .45rem; line-height: 1.5;
  border-left: 2px solid var(--border); padding-left: .6rem;
}
.prov b { color: #a9b6cb; font-weight: 500; }

/* ---------------- panels ---------------- */
.panel {
  background: var(--panel); border: 1px solid var(--border); border-radius: 14px;
  padding: 1.1rem 1.2rem 1rem; height: 100%;
}
.panel-h { font-size: 1.02rem; font-weight: 620; margin-bottom: .15rem; }
.panel-s { color: var(--muted); font-size: .84rem; margin-bottom: .7rem; line-height: 1.5; }
.grid2 { display: grid; gap: 1.1rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid3 { display: grid; gap: 1.1rem; grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* minmax(0, 1fr), NOT 1fr. A bare `1fr` track carries an implicit min-content floor, so the
   560px-wide chart inside .gscroll pushes the track open instead of scrolling inside it:
   measured on a 390px phone, every panel rendered 601px wide and the page scrolled sideways
   by 318px, clipping titles mid-word and pushing the heatmap and modal off screen. The whole
   scroll-inside-the-panel design below never got a chance to run. */
@media (max-width: 980px) { .grid2, .grid3 { grid-template-columns: minmax(0, 1fr); } }

/* ---------------- stat grid ---------------- */
.sg { display: grid; gap: .55rem; }
.sg-2 { grid-template-columns: repeat(2, minmax(0,1fr)); }
.sg-3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
.sg-4 { grid-template-columns: repeat(4, minmax(0,1fr)); }
@media (max-width: 820px) { .sg-3, .sg-4 { grid-template-columns: repeat(2, minmax(0,1fr)); } }
.sg-item { background: var(--panel2); border: 1px solid var(--border); border-radius: 9px;
           padding: .6rem .7rem; }
.sg-k { color: var(--muted); font-size: .7rem; text-transform: uppercase; letter-spacing: .04em; }
.sg-v { font-size: 1.02rem; font-variant-numeric: tabular-nums; margin-top: .15rem; }
.sg-v.pos { color: var(--green); }
.sg-v.neg { color: var(--red); }

/* ---------------- notes ---------------- */
.note-t { color: var(--accent); font-size: .74rem; text-transform: uppercase;
          letter-spacing: .06em; margin-bottom: .3rem; }
.callout {
  background: var(--panel); border: 1px solid var(--border);
  border-left: 3px solid var(--accent); border-radius: 10px; padding: 1.1rem 1.3rem;
  color: #c7d3e3; line-height: 1.65;
}
.callout.warn { border-left-color: var(--amber); }

/* thin-sample badge — the honest marker on a bucket below 30 effective members */
.badge-thin {
  display: inline-block; font-size: .66rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--amber); border: 1px solid rgba(242,201,76,.35); border-radius: 999px;
  padding: .1rem .45rem; margin-left: .4rem; vertical-align: middle;
}

/* ---------------- controls ---------------- */
.ctl-row { display: flex; gap: 1.4rem; flex-wrap: wrap; align-items: center;
           margin-bottom: .9rem; }
.ctl-lab { color: var(--muted); font-size: .72rem; text-transform: uppercase;
           letter-spacing: .05em; margin-right: .5rem; }
.ctl .form-check-label, .ctl label { color: var(--muted) !important; font-size: .85rem; }
.ctl .form-check-input:checked { background-color: var(--accent); border-color: var(--accent); }

/* ---------------- scroll-instead-of-squeeze ---------------- */
.gscroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.gscroll::-webkit-scrollbar { height: 6px; }
.gscroll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
@media (max-width: 700px) {
  .gscroll > div { min-width: 560px; }
  .gscroll { border-right: 1px solid var(--border); }
}

/* ---------------- entry gate ---------------- */
/* The modal repaints every dbc modal on the page; there is only one, deliberately. */
.smodal .modal-content, .modal-content {
  background: var(--panel) !important; border: 1px solid var(--border) !important;
  color: var(--text); border-radius: 14px;
}
.consent-head { border-bottom: 1px solid var(--border) !important; }
.consent-head .modal-title { font-size: 1.15rem; font-weight: 650; letter-spacing: -.01em; }
.consent-body { max-height: 68vh; overflow-y: auto; }
.consent-p { color: #c7d3e3; line-height: 1.6; font-size: .95rem; margin-bottom: .4rem; }
.consent-hr { border-color: var(--border); opacity: 1; margin: 1rem 0; }
.consent-lead { font-weight: 600; font-size: .95rem; margin-bottom: .5rem; }
.consent-list { padding-left: 1.15rem; margin-bottom: .9rem; }
.consent-li { color: #c7d3e3; line-height: 1.55; font-size: .89rem; margin-bottom: .55rem; }
.consent-li::marker { color: var(--accent); font-weight: 600; }
.consent-fine { color: var(--muted); font-size: .76rem; }
.consent-foot { border-top: 1px solid var(--border) !important; }
.agree-btn {
  background: var(--accent) !important; border-color: var(--accent) !important;
  color: #06121b !important; font-weight: 600;
}
.agree-btn:hover { filter: brightness(1.08); }
.decline-btn { color: var(--muted) !important; text-decoration: none; }
.decline-btn:hover { color: var(--text) !important; }
.declined { max-width: 620px; margin: 6rem auto; padding: 0 1.25rem; text-align: center; }
.decl-h { font-size: 1.5rem; font-weight: 650; margin-bottom: .5rem; }
.decl-p { color: var(--muted); }
@media (max-width: 576px) {
  .consent-body { max-height: 74vh; }
  .consent-foot { flex-direction: column-reverse; }
  .consent-foot .btn { width: 100%; }
}

/* ---------------- footer ---------------- */
.foot { background: #080b10; border-top: 1px solid var(--border);
        margin-top: 4rem; padding: 2rem 1.25rem; }
.foot-in { max-width: 1320px; margin: 0 auto; }
.foot-legal { color: var(--muted); font-size: .78rem; line-height: 1.6; max-width: 100ch; }
.foot-legal strong { color: var(--amber); }
.foot-meta { color: var(--muted); font-size: .74rem; margin-top: .8rem;
             font-variant-numeric: tabular-nums; }

@media (max-width: 576px) {
  .hero { padding: 1.75rem 1rem 1rem; }
  .hero-mark { height: 48px; }
  .kpi-v { font-size: 1.35rem; }
  .sec { margin-top: 2.25rem; }
  .sec-h { font-size: 1.2rem; }
}

/* ---------------- cohort comparison ---------------- */
/* The two halves of the market read as a comparison, so the value columns are equal width
   and tabular — the eye should be able to run down them without re-anchoring. */
.coh-table td, .coh-table th { border-color: var(--border) !important; }
.coh-table th { color: var(--muted); font-size: .72rem; text-transform: uppercase;
                letter-spacing: .05em; font-weight: 500; }
.coh-table td:first-child { color: var(--muted); font-size: .86rem; width: 42%; }
.coh-table td:nth-child(2), .coh-table td:nth-child(3) {
  font-variant-numeric: tabular-nums; text-align: right; width: 24%; font-size: .95rem;
}
.coh-table td.pos { color: var(--green); }
.coh-table td.neg { color: var(--red); }
.coh-table tbody tr:first-child td { font-weight: 600; color: var(--text); }

/* ---------------------------------------------------------------------------
   Explorer controls. Filters sit in ONE row directly above the chart they act
   on, so the relationship is positional rather than remembered.
   --------------------------------------------------------------------------- */
.ctlbar { display: flex; gap: 1.25rem; align-items: flex-end; flex-wrap: wrap;
          margin: 0 0 .9rem; }
.ctl { display: flex; flex-direction: column; gap: .35rem; }
.ctl-grow { flex: 1 1 320px; min-width: 260px; }
.ctl-l { color: var(--muted); font-size: .72rem; text-transform: uppercase;
         letter-spacing: .05em; font-weight: 500; }

/* Dash 4.4's Dropdown is NOT react-select — it renders its own `.dash-dropdown-*` tree and
   ships a white control. The legacy `.Select-*` selectors every example uses match nothing
   here; these class names were read off the rendered DOM. Verified: the control, the search
   box and the option list all default to a white background with our light text on top,
   i.e. invisible, so each surface is set explicitly rather than inherited. */
.ctl-dd.dash-dropdown, .ctl-dd .dash-dropdown-content,
.ctl-dd .dash-dropdown-grid-container, .ctl-dd .dash-dropdown-search-container,
.ctl-dd .dash-dropdown-focus-target {
  background: var(--panel2) !important; color: var(--text) !important;
  border-color: var(--border) !important; border-radius: 8px;
}
.ctl-dd .dash-dropdown-value, .ctl-dd .dash-dropdown-value-item,
.ctl-dd .dash-dropdown-search, .ctl-dd .dash-dropdown-trigger-icon,
.ctl-dd .dash-dropdown-search-icon { color: var(--text) !important; }
/* The menu panel is a SIBLING of the trigger inside .dash-dropdown-wrapper, not a child of
   the element carrying .ctl-dd — which is why a descendant selector on .ctl-dd silently
   matches nothing. Scoped to the wrapper, verified against the rendered tree. */
.dash-dropdown-wrapper .dash-dropdown-options,
.dash-dropdown-wrapper .dash-dropdown-search-container,
.dash-dropdown-wrapper .dash-dropdown-content {
  background: var(--panel2) !important; border-color: var(--border) !important;
  border-radius: 8px; color: var(--text) !important;
}
.dash-dropdown-wrapper .dash-dropdown-search { background: var(--panel) !important; color: var(--text) !important;
  border: 1px solid var(--border) !important; border-radius: 6px; }
.dash-dropdown-wrapper .dash-dropdown-search::placeholder { color: var(--muted) !important; }
.dash-dropdown-wrapper .dash-dropdown-option { color: var(--text) !important; padding: .45rem .7rem;
  border-color: var(--border) !important; }
.dash-dropdown-wrapper .dash-dropdown-option:hover { background: var(--panel) !important; }
/* Group headings are disabled options: recessive, not clickable, and clearly not a choice. */
.dash-dropdown-wrapper .dash-dropdown-option[aria-disabled="true"],
.dash-dropdown-wrapper .dash-dropdown-option.disabled {
  color: var(--muted) !important; font-size: .72rem; text-transform: uppercase;
  letter-spacing: .05em; cursor: default; pointer-events: none; padding-top: .7rem;
  background: transparent !important;
}
/* The default focus ring is a browser-blue box; keep focus visible but on-palette. */
.ctl-dd:focus-within { outline: none; border-color: var(--accent) !important;
  box-shadow: 0 0 0 2px rgba(77, 182, 232, .25); }

/* Radio hit targets are deliberately larger than the dot: the whole label is clickable. */
.ctl-radio { display: flex; gap: .25rem; flex-wrap: wrap; }
.ctl-radio label { display: inline-flex; align-items: center; gap: .4rem;
                   padding: .42rem .7rem; border: 1px solid var(--border);
                   border-radius: 999px; color: var(--muted); font-size: .82rem;
                   cursor: pointer; background: var(--panel2); }
.ctl-radio label:hover { color: var(--text); border-color: var(--accent); }
.ctl-radio input { accent-color: var(--accent); margin: 0; }

@media (max-width: 640px) {
  .ctlbar { gap: .75rem; }
  .ctl-grow { flex: 1 1 100%; }
}

/* The menu floats over a chart, so it needs its own opaque surface and a shadow — without
   one the plot lines read straight through the option labels. */
.dash-dropdown-wrapper .dash-dropdown-content {
  box-shadow: 0 14px 40px rgba(0, 0, 0, .55); border: 1px solid var(--border);
  overflow: hidden;
}
/* 55 metrics in ten groups, so the list must be tall enough that scrolling reads as "there
   is more" rather than as a truncated menu.
   Dash builds this on Radix Popover, which writes `max-height: min(200px, 100vh - 100px)`
   and `overflow: hidden` as an INLINE style on .dash-dropdown-content. An inline declaration
   outranks any stylesheet rule of normal weight, so the 200px cap silently clipped a 420px
   list — !important is load-bearing here, not decoration. */
.dash-dropdown-wrapper .dash-dropdown-content {
  max-height: min(58vh, 460px) !important; overflow: hidden !important;
}
.dash-dropdown-wrapper .dash-dropdown-options,
.dash-dropdown-wrapper .dash-options-list {
  max-height: min(50vh, 400px) !important; overflow-y: auto !important;
}

/* Affordance for the correlation heatmap: the cells are clickable, which nothing about a
   heatmap otherwise suggests. */
.hint { color: var(--muted); font-size: .78rem; margin-top: .5rem; font-style: italic; }
#corr-heat .nsewdrag { cursor: pointer !important; }

/* The drill-down modal inherits Bootstrap's light surface otherwise. */
#corr-modal .modal-content { background: var(--panel); border: 1px solid var(--border);
                             color: var(--text); border-radius: 12px; }
#corr-modal .modal-header, #corr-modal .modal-footer { border-color: var(--border); }
#corr-modal .modal-title { color: var(--text); font-size: 1.05rem; font-weight: 600; }
#corr-modal .btn-close { filter: invert(1) grayscale(1) brightness(1.6); opacity: .7; }

/* The heatmap hint and its escape hatch share a row: the click affordance and the
   "just show me the overall history" option belong together. */
.hintrow { display: flex; align-items: baseline; gap: .75rem; flex-wrap: wrap;
           margin-top: .5rem; }
.hintrow .hint { margin-top: 0; }
.linkbtn { color: var(--accent) !important; text-decoration: none !important;
           padding: 0 !important; font-size: .8rem; border: 0; }
.linkbtn:hover { text-decoration: underline !important; }

/* Numeric table cells: right-aligned and tabular, so a reader can run down a column. The
   cohort table already does this; the sector table was left-aligned and ragged. */
.sect-table td:not(:first-child), .sect-table th:not(:first-child) {
  text-align: right; font-variant-numeric: tabular-nums;
}
.sect-table th { color: var(--muted); font-size: .7rem; text-transform: uppercase;
                 letter-spacing: .04em; font-weight: 500; }
.sect-table td, .sect-table th { padding: .3rem .45rem !important; font-size: .84rem; }
.sect-table td:first-child { color: var(--text); }

/* ---------------------------------------------------------------------------
   Brand backdrop, entry blur, and the loading state
   --------------------------------------------------------------------------- */

/* The oversized mark, blurred, behind everything. Fixed rather than absolute so it does not
   travel with the scroll, and pointer-events:none so it can never intercept a click on a
   chart sitting above it. Deliberately very low contrast — it is a wash, not a watermark to
   be read. */
.brandwash {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.brandwash img {
  /* Contained, not cropped: sized against BOTH axes so the wordmark under the glyph stays
     inside the viewport instead of running off the bottom edge. */
  width: auto; height: auto;
  max-width: 150vw; max-height: 150vh; object-fit: contain;
  opacity: .075; filter: blur(2px) grayscale(1) brightness(2.4);
}
/* Everything real sits above the wash. NOTE: only z-index — Bootstrap's backdrop must keep
   its own `position: fixed`, and forcing it to `relative` made it cover only part of the
   viewport, leaving a hard horizontal seam across the middle of the entry screen. */
.wrap, .container, #page { position: relative; z-index: 1; }

/* The gate frosts whatever is behind it — on arrival that is the brand wash, and on a later
   drill-down it is the page. Applied to the shared backdrop so both modals behave alike. */
.modal-backdrop.show {
  backdrop-filter: blur(7px) saturate(.8);
  -webkit-backdrop-filter: blur(7px) saturate(.8);
  background: rgba(4, 6, 10, .72); opacity: 1 !important;
}

/* The mark in the gate's own header, beside the title. */
.consent-mark { height: 26px; width: auto; margin-right: .6rem; vertical-align: -6px; }

/* ---- loading ------------------------------------------------------------- */
/* Shown while the page is being BUILT server-side after acceptance. Without it the reader
   clicks "enter" and watches an empty screen, which reads as a freeze rather than as work. */
.loading {
  min-height: 62vh; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 1.4rem;
}
.load-mark { width: 168px; max-width: 46vw; opacity: .92; }
.load-t { color: var(--muted); font-size: .86rem; letter-spacing: .02em; }
.spinner {
  width: 34px; height: 34px; border-radius: 50%;
  border: 2.5px solid var(--border); border-top-color: var(--accent);
  animation: spin .9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Respect a reader who has asked for less motion: keep the cue, drop the rotation. */
@media (prefers-reduced-motion: reduce) {
  .spinner { animation: none; border-top-color: var(--accent); opacity: .8; }
}

/* Dash's own overlay tint would grey the mark out; we supply the whole visual instead. */
#page-loading .dash-loading, #page-loading [data-dash-is-loading] { background: transparent; }

/* The conditional view leads with a sentence, not a chart: the number is the finding and the
   box plot is the evidence for it. */
.cd-headline { font-size: 1.02rem; line-height: 1.55; margin-bottom: .9rem; color: var(--text); }
.cd-headline b { color: var(--accent); font-variant-numeric: tabular-nums; }
