/* ---------------------------------------------------------------------------
   Tokens. Light is the base; dark redefines only what changes, under both the
   OS media query and an explicit data-theme stamp.
   Series colours are the validated categorical slots 1-3 (blue/orange/aqua)
   plus a deliberately neutral grey for the residual "Other" bucket.
--------------------------------------------------------------------------- */
:root {
  color-scheme: light;
  --surface-0:#f4f4f1; --surface-1:#fcfcfb; --surface-2:#efeeea;
  --border:#dedcd5; --border-strong:#c6c4bb;
  --text-primary:#0b0b0b; --text-secondary:#52514e; --text-muted:#7d7b74;
  --series-email:#2a78d6; --series-call:#eb6834; --series-chat:#1baf7a; --series-other:#8b8880;
  --prev-line:#a9a69d;
  --good:#1a7f4b; --bad:#c0392f;
  --heat-0:#f0efec; --heat-1:#cde2fb; --heat-2:#9ec5f4; --heat-3:#5598e7;
  --heat-4:#2a78d6; --heat-5:#1c5cab; --heat-6:#104281;
  --shadow:0 1px 2px rgba(0,0,0,.05), 0 4px 12px rgba(0,0,0,.04);
  --shadow-hover:0 2px 4px rgba(0,0,0,.06), 0 10px 22px rgba(0,0,0,.07);
  --radius:10px;
}
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    color-scheme: dark;
    --surface-0:#121211; --surface-1:#1a1a19; --surface-2:#232322;
    --border:#33322f; --border-strong:#4a4945;
    --text-primary:#ffffff; --text-secondary:#c3c2b7; --text-muted:#8e8d84;
    --series-email:#3987e5; --series-call:#d95926; --series-chat:#199e70; --series-other:#8e8d84;
    --prev-line:#6b6a63;
    --good:#3fae72; --bad:#e66767;
    --heat-0:#2e2e2b; --heat-1:#b7d3f6; --heat-2:#86b6ef; --heat-3:#5598e7;
    --heat-4:#2a78d6; --heat-5:#256abf; --heat-6:#1c5cab;
    --shadow:0 1px 2px rgba(0,0,0,.4), 0 4px 12px rgba(0,0,0,.3);
    --shadow-hover:0 2px 4px rgba(0,0,0,.45), 0 10px 22px rgba(0,0,0,.4);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --surface-0:#121211; --surface-1:#1a1a19; --surface-2:#232322;
  --border:#33322f; --border-strong:#4a4945;
  --text-primary:#ffffff; --text-secondary:#c3c2b7; --text-muted:#8e8d84;
  --series-email:#3987e5; --series-call:#d95926; --series-chat:#199e70; --series-other:#8e8d84;
  --prev-line:#6b6a63;
  --good:#3fae72; --bad:#e66767;
  --heat-0:#2e2e2b; --heat-1:#b7d3f6; --heat-2:#86b6ef; --heat-3:#5598e7;
  --heat-4:#2a78d6; --heat-5:#256abf; --heat-6:#1c5cab;
  --shadow:0 1px 2px rgba(0,0,0,.4), 0 4px 12px rgba(0,0,0,.3);
  --shadow-hover:0 2px 4px rgba(0,0,0,.45), 0 10px 22px rgba(0,0,0,.4);
}

* { box-sizing: border-box; }
/* .field is display:flex, which would otherwise defeat the hidden attribute */
[hidden] { display: none !important; }
body {
  margin:0; background:var(--surface-0); color:var(--text-primary);
  font:14px/1.5 ui-sans-serif, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing:antialiased;
}
.app { max-width:1360px; margin:0 auto; padding:28px 24px 56px; }

.masthead { display:flex; justify-content:space-between; align-items:flex-start; gap:20px; flex-wrap:wrap; margin-bottom:22px; }
h1 { margin:0; font-size:24px; letter-spacing:-.02em; }
.crumbs { display:flex; align-items:center; gap:7px; margin-bottom:5px; font-size:12px; color:var(--text-muted); }
.crumbs a { color:var(--text-secondary); text-decoration:none; font-weight:600; }
.crumbs a:hover { color:var(--text-primary); text-decoration:underline; }

/* Module directory ------------------------------------------------------- */
.modules { display:grid; grid-template-columns:repeat(auto-fill, minmax(330px,1fr)); gap:14px; }
.module { position:relative; display:flex; gap:14px; padding:18px; text-decoration:none; color:inherit;
  background:var(--surface-1); border:1px solid var(--border); border-radius:var(--radius); box-shadow:var(--shadow); }
a.module { transition:border-color .12s, transform .12s, box-shadow .12s; }
a.module:hover { border-color:var(--series-email); transform:translateY(-1px);
  box-shadow:var(--shadow-hover); }
a.module:focus-visible { outline:2px solid var(--series-email); outline-offset:2px; }
.module.planned { opacity:.62; }
.module-icon { width:30px; height:30px; flex:none; fill:var(--text-secondary); }
a.module:hover .module-icon { fill:var(--series-email); }
.module-body { min-width:0; flex:1; }
.module-head { display:flex; align-items:center; gap:9px; flex-wrap:wrap; }
.module h3 { margin:0; font-size:15.5px; font-weight:650; letter-spacing:-.01em; }
.module p { margin:6px 0 0; font-size:12.5px; line-height:1.55; color:var(--text-secondary); }
.badge { font-size:10px; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  padding:2px 7px; border-radius:999px; border:1px solid var(--border-strong); color:var(--text-muted); }
.badge.live { color:var(--good); border-color:currentColor; }
.module-stats { display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:10px;
  margin-top:13px; padding-top:12px; border-top:1px solid var(--border); }
/* value / change / label on three shared rows, so the columns line up even
   though only some stats carry a change figure */
.module-stats > div { min-width:0; display:grid; grid-template-rows:auto auto auto; align-content:start; }
.module-stats b { font-size:18px; font-weight:650; letter-spacing:-.02em; font-variant-numeric:tabular-nums;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.module-stats .mv-chg { min-height:1.15em; line-height:1.15; }
.module-stats > div > span:last-child { margin-top:2px; font-size:10.5px; line-height:1.35; color:var(--text-muted); }
.module-stats .chg { font-size:11px; }
.module-go { margin-left:auto; color:var(--text-muted); font-size:15px; }
a.module:hover .module-go { color:var(--series-email); }
#view-404 a { color:var(--series-email); }
.sub { margin:4px 0 0; color:var(--text-secondary); font-size:13px; }
.mast-end { display:flex; flex-direction:column; align-items:flex-end; gap:10px; }
.status { display:flex; flex-direction:column; align-items:flex-end; gap:4px; font-size:12px; color:var(--text-muted); text-align:right; }
.pill { display:inline-flex; align-items:center; gap:6px; padding:3px 10px; border:1px solid var(--border); border-radius:999px; background:var(--surface-1); }
.dot { width:7px; height:7px; border-radius:50%; background:var(--good); }
.dot.idle { background:var(--text-muted); }
/* A sync in flight, or one that has gone quiet long enough to be suspicious. */
.dot.warn { background:var(--series-call); }
/* A run that reported an error. */
.dot.bad  { background:var(--bad); }

.filters { display:flex; gap:12px; align-items:flex-end; flex-wrap:wrap; margin-bottom:18px; padding:14px 16px; background:var(--surface-1); border:1px solid var(--border); border-radius:var(--radius); box-shadow:var(--shadow); }
.field { display:flex; flex-direction:column; gap:5px; }
.field > span { font-size:11px; text-transform:uppercase; letter-spacing:.06em; color:var(--text-muted); font-weight:600; }
select, input[type=date] { font:inherit; padding:7px 10px; border:1px solid var(--border-strong); border-radius:7px; background:var(--surface-1); color:var(--text-primary); min-width:150px; }
.btn { font:inherit; font-weight:600; padding:8px 16px; border:1px solid var(--border-strong); border-radius:7px; background:var(--surface-2); color:var(--text-primary); cursor:pointer; }
.btn:hover { border-color:var(--text-muted); }

.notice { margin:0 0 16px; padding:9px 14px; border-radius:7px; font-size:12.5px;
  background:var(--surface-2); border:1px solid var(--border); color:var(--text-secondary); }

/* KPI cards ------------------------------------------------------------- */
.kpis { display:grid; grid-template-columns:repeat(auto-fit, minmax(210px,1fr)); gap:14px; margin-bottom:18px; }
.kpi { position:relative; padding:15px 16px 12px; background:var(--surface-1); border:1px solid var(--border); border-radius:var(--radius); box-shadow:var(--shadow); overflow:hidden; }
.kpi::before { content:""; position:absolute; inset:0 auto 0 0; width:3px; background:var(--accent, transparent); }
.kpi-label { display:flex; align-items:center; gap:7px; font-size:12px; font-weight:600; color:var(--text-secondary); }
.swatch { width:9px; height:9px; border-radius:2px; background:var(--accent); flex:none; }
.kpi-value { margin:7px 0 2px; font-size:29px; font-weight:650; letter-spacing:-.025em; font-variant-numeric:tabular-nums; }
.kpi-meta { display:flex; align-items:baseline; gap:7px; flex-wrap:wrap; font-size:12px; color:var(--text-muted); font-variant-numeric:tabular-nums; }
.chg { font-weight:650; }
.chg.up { color:var(--bad); }      /* more cases arriving = worse */
.chg.down { color:var(--good); }
.chg.flat { color:var(--text-muted); }
.spark { display:block; margin-top:9px; width:100%; height:30px; overflow:visible; }

/* Cards ----------------------------------------------------------------- */
.card { background:var(--surface-1); border:1px solid var(--border); border-radius:var(--radius); box-shadow:var(--shadow); padding:16px 18px 18px; margin-bottom:18px; }
.card-head { display:flex; justify-content:space-between; align-items:flex-start; gap:16px; flex-wrap:wrap; margin-bottom:14px; }
h2 { margin:0; font-size:15px; font-weight:650; letter-spacing:-.01em; }
.card-sub { display:block; margin:3px 0 0; font-size:12.5px; color:var(--text-secondary); }

/* Collapsible sections --------------------------------------------------- */
.card-toggle { display:flex; align-items:flex-start; gap:9px; flex:1; min-width:0;
  margin:0; padding:0; border:0; background:none; font:inherit; color:inherit;
  text-align:left; cursor:pointer; border-radius:6px; }
.card-toggle > span { min-width:0; }
.card-toggle:focus-visible { outline:2px solid var(--series-email); outline-offset:3px; }
.chev { width:14px; height:14px; flex:none; margin-top:3px; fill:none;
  stroke:var(--text-muted); stroke-width:2; stroke-linecap:round; stroke-linejoin:round;
  transform:rotate(90deg); transition:transform .15s ease; }
.card.collapsed .chev { transform:rotate(0deg); }
.card-toggle:hover .chev { stroke:var(--text-primary); }
.card.collapsed .card-head { margin-bottom:0; }
.card.collapsed .toggle { display:none; }   /* view switcher is meaningless closed */
.toggle { display:inline-flex; border:1px solid var(--border-strong); border-radius:7px; overflow:hidden; }
.toggle button { font:inherit; font-size:12px; font-weight:600; padding:6px 12px; border:0; background:var(--surface-1); color:var(--text-secondary); cursor:pointer; }
.toggle button + button { border-left:1px solid var(--border-strong); }
.toggle button.on { background:var(--surface-2); color:var(--text-primary); }
.toggle button:disabled { opacity:.45; cursor:not-allowed; }

.legend { display:flex; gap:16px; flex-wrap:wrap; margin-top:12px; font-size:12px; color:var(--text-secondary); }
.legend-item { display:inline-flex; align-items:center; gap:6px; }
.legend-key { width:11px; height:11px; border-radius:3px; flex:none; }
.legend-key.line { height:3px; border-radius:2px; width:15px; }

svg { display:block; max-width:100%; }
.scroll-x { overflow-x:auto; overflow-y:hidden; padding-bottom:4px; }
/* Both placements: most charts wrap their labels in <g class="axis">, but the
   two percentage axes put the class on the <text> itself. Matching only the
   descendant form left those with no fill at all, so they fell back to SVG's
   default black -- invisible on a dark background, and indistinguishable from
   intent on a light one, which is why it went unnoticed. */
.axis text, text.axis { fill:var(--text-muted); font-size:10.5px; }
.axis line, .axis path { stroke:var(--border); }
.grid line { stroke:var(--border); stroke-dasharray:2 3; }
.val-label { fill:var(--text-secondary); font-size:10.5px; font-variant-numeric:tabular-nums; }

/* Data table ------------------------------------------------------------- */
.tbl-wrap { max-height:430px; overflow:auto; border:1px solid var(--border); border-radius:8px; }
table { border-collapse:collapse; width:100%; font-size:12.5px; font-variant-numeric:tabular-nums; }
th, td { padding:7px 12px; text-align:right; border-bottom:1px solid var(--border); white-space:nowrap; }
th:first-child, td:first-child { text-align:left; position:sticky; left:0; background:var(--surface-1); }
thead th { position:sticky; top:0; background:var(--surface-2); font-weight:650; color:var(--text-secondary); z-index:2; }
thead th:first-child { z-index:3; background:var(--surface-2); }
tbody tr:hover td { background:var(--surface-2); }

.foot { margin-top:26px; font-size:11.5px; color:var(--text-muted); line-height:1.7; }

/* Tooltip ---------------------------------------------------------------- */
.tip { position:fixed; z-index:50; pointer-events:none; opacity:0; transition:opacity .1s;
  background:var(--surface-1); color:var(--text-primary); border:1px solid var(--border-strong);
  border-radius:8px; padding:9px 11px; font-size:12px; box-shadow:0 6px 20px rgba(0,0,0,.16);
  max-width:260px; }
.tip.on { opacity:1; }
.tip-title { font-weight:650; margin-bottom:5px; }
.tip-row { display:flex; justify-content:space-between; gap:16px; font-variant-numeric:tabular-nums; }
.tip-row span:first-child { display:inline-flex; align-items:center; gap:6px; color:var(--text-secondary); }
.tip-key { width:8px; height:8px; border-radius:2px; flex:none; }
.tip-sep { height:1px; background:var(--border); margin:5px 0; }
.empty { padding:40px 0; text-align:center; color:var(--text-muted); font-size:13px; }

/* -- Resolution & SLA ------------------------------------------------------ */
/* Breakdown tables. The four blocks share one scroll box so they stay in
   register when the card is too narrow, and the page body never scrolls
   sideways. */
/* overflow-x:auto forces overflow-y:auto, which would clip the first block's
   label where it rides up over its rule -- the padding gives it that room. */
.slagrid { overflow-x:auto; padding-top:8px; }
.slablock { min-width:760px; margin-bottom:26px; }
.slablock:last-child { margin-bottom:0; }

/* Divider between blocks, with the block's name sitting on the line. The rule
   runs the full width and the label knocks a hole in it, so the separation and
   the thing being separated are one mark rather than two stacked ones. The
   label's background has to match .card for the knockout to read as a gap. */
.slacap { caption-side:top; padding:0; text-align:left; }
/* flex, not block: a block line box would sit the label on a baseline inside
   the caption's strut and drop it below the rule. */
.slacap > span { display:flex; margin-bottom:11px; border-top:1px solid var(--border); }
/* translateY(-50%) on a line-height:1 box centres the label on the rule from
   its own height, so it stays centred if the type ever changes size. The 10px
   inset puts it over the same x as the labels in the column beneath it. */
.slacap b { flex:none; line-height:1; transform:translateY(-50%);
            padding:0 10px; background:var(--surface-1);
            font-size:11px; font-weight:650; text-transform:uppercase;
            letter-spacing:.06em; color:var(--text-secondary); }
/* table-layout:fixed with the shared colgroup below pins every block to the
   same column geometry, so the four tables stack into one continuous grid
   instead of each sizing itself around its own longest label. */
.slatable { width:100%; border-collapse:collapse; font-size:13px;
            min-width:760px; table-layout:fixed; }
/* Six columns: label, then each rate paired with its own case count, then the
   median. The rate columns have to hold bar + value (103px) inside their
   padding, which is what sets the 760px floor. */
.slatable .c-label  { width:26%; }
.slatable .c-rate   { width:17%; }
.slatable .c-count  { width:9%; }
.slatable .c-median { width:22%; }
.slatable th, .slatable td { padding:7px 10px; text-align:left; border-bottom:1px solid var(--border);
                             white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* Header band. Only the header row uses <th> -- body rows are all <td> -- so
   this shades the headers without touching the label column beneath them. */
.slatable th { font-size:11px; text-transform:uppercase; letter-spacing:.06em;
               color:var(--text-muted); font-weight:600; background:var(--surface-2); }
.slatable th.r, .slatable td.r { text-align:right; }
.slatable tr:last-child td { border-bottom:0; }
.slatable tr.empty td { color:var(--text-muted); }
.slatable td .muted { color:var(--text-muted); }

/* Inline attainment bar: a rate is easier to compare down a column with a
   length behind it, but the number stays the thing being read. Bar and number
   are fixed-width slots so a short value ("0%") leaves the bar where a long
   one ("94.6%") does. */
.slameter { display:inline-flex; align-items:center; gap:7px; }
.slabar { flex:none; width:52px; height:6px; border-radius:3px;
          background:var(--grid); overflow:hidden; }
.slabar.blank { background:none; }
.slabar i { display:block; height:100%; background:var(--series-email); border-radius:3px; }
.slaval { flex:none; width:44px; text-align:right; font-weight:inherit;
          font-variant-numeric:tabular-nums; }

.slanote { margin:8px 2px 0; font-size:12px; color:var(--text-muted); line-height:1.5; }

/* -- Breach drill-down drawer ---------------------------------------------- */
.drawer-scrim { position:fixed; inset:0; background:rgba(0,0,0,.45); z-index:40;
                animation:scrim .16s ease-out; }
@keyframes scrim { from { opacity:0 } to { opacity:1 } }

.drawer { position:fixed; top:0; right:0; bottom:0; width:min(1080px, 94vw);
          background:var(--surface-1); border-left:1px solid var(--border);
          box-shadow:-8px 0 28px rgba(0,0,0,.25); z-index:41;
          display:flex; flex-direction:column; animation:slide .18s ease-out; }
@keyframes slide { from { transform:translateX(24px); opacity:.6 } to { transform:none; opacity:1 } }
/* Respect a reduced-motion preference: the drawer still appears, it just does
   not fly in. */
@media (prefers-reduced-motion: reduce) {
  .drawer, .drawer-scrim { animation:none; }
}

.drawer-head { display:flex; align-items:flex-start; justify-content:space-between; gap:16px;
               padding:16px 20px; border-bottom:1px solid var(--border); flex:0 0 auto; }
.drawer-head h2 { margin:0; font-size:16px; }
.drawer-sub { margin:4px 0 0; font-size:12.5px; color:var(--text-muted); line-height:1.5; }
.drawer-close { font:inherit; font-size:22px; line-height:1; padding:2px 9px 5px;
                border:1px solid var(--border-strong); border-radius:7px;
                background:var(--surface-2); color:var(--text-secondary); cursor:pointer; }
.drawer-close:hover { color:var(--text-primary); border-color:var(--text-muted); }
.drawer-close:focus-visible { outline:2px solid var(--series-email); outline-offset:2px; }

.drawer-body { flex:1 1 auto; overflow:auto; padding:0 20px 20px; }

/* Fixed layout so seven columns always fit the drawer instead of scrolling
   sideways; the free-text columns truncate rather than pushing the numbers off.
   Below the min-width the drawer body scrolls, so narrow screens still work. */
.breach-table { width:100%; border-collapse:collapse; font-size:12.5px;
                table-layout:fixed; min-width:860px; }
.breach-table col.c-case { width:9%; }
.breach-table col.c-subject { width:23%; }
.breach-table col.c-biz { width:19%; }
.breach-table col.c-created { width:12%; }
.breach-table col.c-done { width:12%; }
.breach-table col.c-over { width:13%; }
.breach-table col.c-agent { width:12%; }
.breach-table th, .breach-table td { padding:8px 10px; text-align:left;
                                     border-bottom:1px solid var(--border); vertical-align:top; }
/* The header stays put while a long breach list scrolls under it. Labels wrap
   rather than run past their fixed column and collide with the next one, and
   every label is centred in the row that a wrapped one makes taller.
   The background must stay opaque to hide the rows passing beneath; surface-2
   also shades the band, matching the header band in "Where SLAs break". */
.breach-table thead th { position:sticky; top:0; z-index:1; background:var(--surface-2);
                         font-size:11px; text-transform:uppercase; letter-spacing:.06em;
                         color:var(--text-muted); font-weight:600;
                         white-space:normal; vertical-align:middle; }
.breach-table td.num, .breach-table th.num { text-align:right;
                                             font-variant-numeric:tabular-nums; }
.breach-table td.num { white-space:nowrap; }
.breach-table td.when { white-space:nowrap; font-variant-numeric:tabular-nums;
                        color:var(--text-secondary); }
.breach-case { font-weight:600; white-space:nowrap; }
/* Subjects are free text and occasionally very long; cap the column rather than
   letting one case push every other column off screen. */
.breach-subject { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.breach-biz { color:var(--text-muted); font-size:11.5px; }
.breach-table td > div, .breach-table td { overflow:hidden; text-overflow:ellipsis; }
.breach-agent, .breach-account { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.breach-over { font-weight:600; }
.breach-open { color:var(--series-call); font-weight:600; white-space:nowrap; }
.breach-empty { padding:28px 4px; color:var(--text-muted); }

/* An attainment card that can be drilled into. */
.kpi.clickable { cursor:pointer; text-align:left; font:inherit; width:100%;
                 border-color:var(--border); }
.kpi.clickable:hover { border-color:var(--text-muted); }
.kpi.clickable:focus-visible { outline:2px solid var(--series-email); outline-offset:2px; }
.kpi-drill { display:block; margin-top:7px; font-size:11.5px; color:var(--text-muted); }
.kpi.clickable:hover .kpi-drill { color:var(--series-email); }

/* Drawer header: headings on the left, search and close on the right. */
.drawer-headings { min-width:0; }
.drawer-tools { display:flex; align-items:center; gap:10px; flex:0 0 auto; }
.drawer-search input { font:inherit; font-size:13px; padding:7px 11px; width:230px;
                       border:1px solid var(--border-strong); border-radius:7px;
                       background:var(--surface-2); color:var(--text-primary); }
.drawer-search input::placeholder { color:var(--text-muted); }
.drawer-search input:focus-visible { outline:2px solid var(--series-email); outline-offset:1px; }
@media (max-width: 680px) {
  .drawer-search input { width:150px; }
}

/* Visually hidden, still read by screen readers. */
.vh { position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden;
      clip:rect(0 0 0 0); white-space:nowrap; border:0; }

/* Sortable column headers. The whole cell is the button so the hit target
   matches what it looks like. */
.breach-table th.sortable { padding:0; }
.breach-table th.sortable button { font:inherit; font-size:11px; text-transform:uppercase;
  letter-spacing:.06em; color:var(--text-muted); font-weight:600; cursor:pointer;
  background:none; border:0; padding:8px 10px; width:100%; text-align:inherit;
  display:flex; align-items:center; gap:5px; }
.sort-label { min-width:0; }
.breach-table th.num.sortable button { justify-content:flex-end; }
.breach-table th.sortable button:hover { color:var(--text-primary); }
.breach-table th.sortable button:focus-visible { outline:2px solid var(--series-email); outline-offset:-2px; }
.breach-table th.sortable[aria-sort] button { color:var(--text-primary); }
.sort-arrow { flex:none; font-size:9px; opacity:.45; line-height:1.5; }
.breach-table th.sortable[aria-sort] .sort-arrow { opacity:1; color:var(--series-email); }

.breach-case a { color:inherit; text-decoration:none; border-bottom:1px solid transparent; }
.breach-case a:hover { color:var(--series-email); border-bottom-color:currentColor; }
.breach-case a:focus-visible { outline:2px solid var(--series-email); outline-offset:2px; }
.breach-ext { font-size:10px; opacity:.5; margin-left:3px; }

/* Spam / merged opt-ins. Both slices are excluded unless ticked, so the group
   is labelled "Also include" -- the checkbox adds data rather than filtering
   it away, which is the opposite of every other control in the bar. */
.checks { display:flex; align-items:center; gap:14px; height:34px; }
.checks label { display:inline-flex; align-items:center; gap:6px; font-size:13px;
                color:var(--text-secondary); cursor:pointer; white-space:nowrap; }
.checks input { margin:0; cursor:pointer; accent-color:var(--series-email); }
.checks label:hover { color:var(--text-primary); }
.checks input:focus-visible { outline:2px solid var(--series-email); outline-offset:2px; }

/* Selection summary above the KPI cards. Shown only while the filters are
   actually narrowing the period, so an unfiltered view stays uncluttered. */
.selection { margin:0 0 14px; font-size:13px; color:var(--text-secondary);
             display:flex; flex-wrap:wrap; align-items:baseline; gap:4px 10px; }
.selection b { color:var(--text-primary); font-variant-numeric:tabular-nums; }
.selection .sel-of { color:var(--text-muted); }
.selection .sel-chips { display:inline-flex; flex-wrap:wrap; gap:6px; }
.selection .chip { display:inline-block; padding:2px 8px; border-radius:99px;
                   background:var(--surface-2); border:1px solid var(--border);
                   font-size:11.5px; color:var(--text-secondary); white-space:nowrap; }

/* -- Handling quality ------------------------------------------------------ */
/* Scores run 1-5 in two directions at once -- clarity is a virtue, the other
   four are faults -- so the palette keys off "concern" (already sign-flipped in
   app.js), never off the raw number. Green always means fine, red always means
   look at this, whichever dimension it is sitting on. */
.q-kpi .kpi-label { justify-content:flex-start; }
.q-dot { width:8px; height:8px; border-radius:50%; flex:none; background:var(--series-other); }
.q-dot.good { background:var(--good); }
.q-dot.warn { background:var(--series-call); }
.q-dot.bad  { background:var(--bad); }
.q-computed { margin-left:auto; font-size:10px; text-transform:uppercase; letter-spacing:.06em;
              color:var(--text-muted); border:1px solid var(--border); border-radius:999px;
              padding:1px 7px; font-weight:600; }

.qdist-table .c-qdim { width:26%; }
.qdist-table .c-qbar { width:52%; }
.qdist-table .c-qnum { width:11%; }
.qdim-dir { display:block; font-size:11px; color:var(--text-muted); font-weight:400; }
.qbar-cell { vertical-align:middle; }
.qbar { display:flex; height:10px; border-radius:3px; overflow:hidden; background:var(--grid); }
.qbar-seg.good { background:var(--good); }
.qbar-seg.warn { background:var(--series-call); }
.qbar-seg.bad  { background:var(--bad); }
.qbar-seg.none { background:transparent; }

/* A score badge, not a bare number: at a glance the column should read as a
   row of traffic lights, with the digit there for anyone who wants it. */
/* text-align is not inherited-and-forgotten here: the cell is `td.r`, so
   without this the digit sits flush against the right edge of its own badge
   and every column reads as slightly crooked. */
.qscore { display:inline-block; min-width:26px; padding:2px 6px; border-radius:5px;
          text-align:center; font-weight:650; font-variant-numeric:tabular-nums; }
.qscore.good { background:color-mix(in srgb, var(--good) 16%, transparent); color:var(--good); }
.qscore.warn { background:color-mix(in srgb, var(--series-call) 18%, transparent); color:var(--series-call); }
.qscore.bad  { background:color-mix(in srgb, var(--bad) 16%, transparent); color:var(--bad); }
.qscore.none { color:var(--text-muted); }

.qcase-table .qrow td { border-bottom:0; padding-bottom:4px; }
.qcase-table .qnotes td { padding-top:0; font-size:12px; color:var(--text-secondary); }
.qcase-table .qnotes ul { margin:0; padding-left:18px; }
.qcase-table .qnotes li { margin:2px 0; white-space:normal; }
.qcase-table .qnotes b { color:var(--text-primary); font-weight:600; }
.qerror { margin:0 0 6px; color:var(--bad); white-space:normal; }
.q-seed { margin-left:6px; font-size:10px; text-transform:uppercase; letter-spacing:.06em;
          color:var(--text-muted); border:1px solid var(--border); border-radius:999px;
          padding:1px 6px; font-weight:600; }
.notice-line { display:block; }
.notice-line + .notice-line { margin-top:5px; }

/* Chart legend, for the CSAT trend's two audience lines. */
.legend { display:flex; flex-wrap:wrap; gap:16px; margin:10px 0 2px 46px;
          font-size:12px; color:var(--text-secondary); }
.legend span { display:inline-flex; align-items:center; gap:6px; }
.legend .key { width:10px; height:10px; border-radius:3px; flex:none; }

/* Dimension names are long and the columns are narrow, so these headers wrap
   and centre rather than truncate -- same treatment as the breach table. */
.qcase-table th { white-space:normal; vertical-align:middle; }
.qcase-table { min-width:900px; table-layout:fixed; }
.qcase-table th:first-child, .qcase-table td:first-child { width:16%; }
.qcase-table th:last-child, .qcase-table td:last-child { width:8%; }


/* ---------------------------------------------------------------------------
   Sign-in gate. Covers the whole page rather than sitting inside it: until
   there is a session there is no dashboard behind it worth looking at, and the
   masthead would otherwise show a stale "Loading..." above it.
   --------------------------------------------------------------------------- */

.auth-gate {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  padding: 24px;
  background: var(--surface-0);
}

.auth-card {
  width: 100%;
  max-width: 27rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-1);
  box-shadow: var(--shadow);
  padding: 34px 30px;
}

.auth-card h1 {
  margin: 0 0 22px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.auth-card h2 {
  margin: 0 0 10px;
  font-size: 22px;
  font-weight: 600;
  line-height: 1.25;
  color: var(--text-primary);
}

.auth-card p {
  margin: 0;
  color: var(--text-secondary);
  font-size: 14px;
  line-height: 1.55;
}

.auth-button {
  margin-top: 24px;
  width: 100%;
  padding: 11px 16px;
  border: 1px solid var(--series-email);
  border-radius: 8px;
  background: var(--series-email);
  color: #fff;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.auth-button:hover { filter: brightness(1.1); }
.auth-button:focus-visible { outline: 2px solid var(--series-email); outline-offset: 2px; }

.auth-note {
  margin-top: 16px !important;
  font-size: 13px !important;
  color: var(--text-muted) !important;
}

/* Who is signed in, and the way out. Sits in the masthead beside the theme
   toggle, so it reads as chrome rather than as part of a module. */

.who { display: flex; align-items: center; gap: 10px; min-width: 0; }

.who-email {
  font-size: 12px;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 15rem;
}

.auth-signout {
  padding: 4px 10px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--surface-1);
  color: var(--text-secondary);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
  white-space: nowrap;
}

.auth-signout:hover { border-color: var(--border-strong); color: var(--text-primary); }
.auth-signout:focus-visible { outline: 2px solid var(--series-email); outline-offset: 2px; }

@media (max-width: 640px) { .who-email { display: none; } }

/* --- Users: who may open the console ------------------------------------ */
.user-add { display:flex; gap:12px; align-items:flex-end; flex-wrap:wrap;
  margin:16px 0 4px; padding:14px 16px; background:var(--surface-2);
  border:1px solid var(--border); border-radius:var(--radius); }
.user-add .field { flex:1 1 220px; }
.user-add input, .user-add select { width:100%; }
.user-submit { padding:7px 14px; border:1px solid var(--border-strong);
  border-radius:var(--radius); background:var(--surface-1);
  color:var(--text-primary); font:inherit; font-weight:600; cursor:pointer; }
.user-submit:hover:not(:disabled) { background:var(--surface-0); }
.user-submit:disabled { opacity:.55; cursor:progress; }

/* Reserved rather than shown-and-hidden, so a message appearing does not
   shove the table down the page and move the row under the pointer. */
.user-note { min-height:1.2em; margin:10px 2px 0; font-size:12.5px; }
.user-note.err { color:var(--bad); }
.user-note.ok  { color:var(--text-muted); }

.user-wrap { margin-top:14px; overflow-x:auto; }
.user-table { width:100%; border-collapse:collapse; font-size:13px; }
.user-table th { text-align:left; font-size:11px; text-transform:uppercase;
  letter-spacing:.06em; color:var(--text-muted); font-weight:600;
  padding:8px 10px; border-bottom:1px solid var(--border); white-space:nowrap; }
.user-table td { padding:9px 10px; border-bottom:1px solid var(--border);
  vertical-align:middle; }
.user-table tr:last-child td { border-bottom:0; }
.user-table td.user-act { text-align:right; white-space:nowrap; width:1%; }
/* The granted column is the one that can grow without limit, so it is the one
   allowed to wrap. Everything else stays on one line: an email that wraps is
   harder to read, and a wrapped button looks broken. */
.user-table td.user-when { color:var(--text-muted); font-size:12px; line-height:1.45; }
.user-by { display:block; }
.user-table th:first-child, .user-table td:first-child { width:99%; }
.user-you { margin-left:7px; font-size:11px; color:var(--text-muted); }

.user-role { display:inline-block; padding:2px 9px; border-radius:999px;
  border:1px solid var(--border-strong); font-size:11px; font-weight:600;
  text-transform:uppercase; letter-spacing:.05em; color:var(--text-muted); }
.user-role.admin { color:var(--text-primary); border-color:var(--text-primary); }

.user-remove { padding:4px 10px; border:1px solid var(--border);
  border-radius:var(--radius); background:transparent; color:var(--text-muted);
  font:inherit; font-size:12px; cursor:pointer; }
.user-remove:hover:not(:disabled) { color:var(--text-primary);
  border-color:var(--border-strong); }
.user-remove:disabled { opacity:.4; cursor:not-allowed; }

/* Per-day summary on the heatmaps: the whole-day figure beside (typical week)
   or beneath (each day) its own axis. Heavier than the axis labels because it
   is a value, not a tick. */
.heat-sum { fill:var(--text-primary); font-size:11.5px; font-weight:650;
            font-variant-numeric:tabular-nums; }
.heat-sum.muted { fill:var(--text-muted); font-weight:400; }
.heat-sum-head { font-size:10px; text-transform:uppercase; letter-spacing:.05em; }
/* A long period makes the each-day grid taller than its budget; it scrolls in
   the box rather than pushing the rest of the page down. */
.heat-scroll { max-height:640px; overflow:auto; }
