/* ============================================================================
 * sections-delta.css — restored feature styling
 *
 * sections.css was lost to a zero-fill on disk (204044 bytes of 0x00). It was
 * rebuilt from the Sep-24 baseline; this file carries every rule that lived in
 * the lost tail, reconstructed against the class names the live markup actually
 * renders. Loaded last so it wins on ties.
 * ========================================================================= */

/* ---- Large KPI cards (global: Analytics, Orders, Retailers) ---- */
.kpi-lg {
  min-height: 132px;
  padding: 15px 16px 13px;
  justify-content: flex-start;
}
.kpi-lg .num { font-size: 30px; letter-spacing: -.9px; line-height: 1.05 }
.kpi-lg .num.money { font-size: 24px }
.kpi-lg .lbl { font-size: 10px }
.kpi-lg .foot { margin-top: auto }

/* ---- Header KPI row: size hierarchy ----
   Six cards sit on one line, so every amount is cut down to 14px to keep each
   figure on one line instead of wrapping mid-number, and the three operating
   figures above them step back again to 24/21px. The labels come down to 9.5px
   and stay regular weight on all six: shouting six headings in caps above six
   numbers is louder than the numbers, and the row has to be scannable at a
   glance rather than read.

   The toggle sits beside the label, so shrinking it is what stops it competing
   with the figure it belongs to - 24px beside a 30px number read as a second
   number rather than as a control.

   The `.kpi-head` hook is load-bearing, not decoration: ui-perf.css sets
   `.analytics-view .kpis > .kpi-lg .num { font-size: 30px }` at the same
   specificity and loads after this file, so a plain `.kpis .kpi-lg .num` here
   loses and the row keeps rendering at 30px regardless. One extra class puts
   these rules ahead of it without resorting to !important. */
.analytics-view .kpis.kpi-head .kpi .num { font-size: 14px; letter-spacing: -.2px; font-weight: 700 }
.analytics-view .kpis.kpi-head .kpi .num.money { font-size: 14px }
.analytics-view .kpis.kpi-head .kpi-lg .num { font-size: 24px; letter-spacing: -.5px }
.analytics-view .kpis.kpi-head .kpi-lg .num.money { font-size: 21px }
.analytics-view .kpis.kpi-head .kpi-hero .num { font-size: 27px; letter-spacing: -.7px }
.analytics-view .kpis.kpi-head .kpi-hero .num.money { font-size: 24px }
.analytics-view .kpis.kpi-head .kpi-lg .lbl,
.analytics-view .kpis.kpi-head .kpi-hero .lbl,
.analytics-view .kpis.kpi-head .kpi .lbl { font-size: 9.5px; font-weight: 600; letter-spacing: .3px; text-transform: uppercase; color: var(--muted) }
/* The arrow switch is a control, not a figure: 19px box, 11px glyph. */
.analytics-view .kpis.kpi-head .kpi-toggle { width: 19px; height: 19px; border-radius: 6px; margin-left: 6px }
.analytics-view .kpis.kpi-head .kpi-toggle svg { width: 11px; height: 11px }
/* Chip is back, but only the direction and the percentage. */
.analytics-view .kpis.kpi-head .kdelta { padding-top: 5px; font-size: 10px; gap: 3px }
.analytics-view .kpis.kpi-head .kdelta em { font-size: 9.5px }
/* ---- Comparison chip under a KPI ----
   Three parts on two lines: the change (arrow + percent + which period it is
   measured against) and, beneath it, the baseline figure itself. Without the
   baseline the percentage is unverifiable — and it had no colour at all, so an
   improvement and a regression were typographically identical. */
.kdelta {
  margin-top: auto;
  padding-top: 7px;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--muted);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  line-height: 1.25;
}
.kdelta .kd-arrow { font-size: 12px; line-height: 1; }
.kdelta .kd-pct { font-variant-numeric: tabular-nums; }
.kdelta em {
  font-style: normal;
  font-weight: 500;
  font-size: 9.5px;
  color: var(--muted);
}
.kdelta .kd-base {
  flex-basis: 100%;
  font-size: 9.5px;
  font-weight: 500;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.kdelta .kd-base b { font-weight: 700; color: var(--label); }
/* Direction is carried by colour as well as by the arrow, so it survives
   greyscale and colour-vision differences. */
.kdelta.good { color: #16A34A; }
.kdelta.bad { color: var(--danger); }
.kdelta.flat { color: var(--muted); }
[data-theme="dark"] .kdelta.good { color: #4ADE80; }
[data-theme="dark"] .kdelta.bad { color: #F87171; }
/* "No prior data" is a state, not a regression — never red. */
.kdelta.muted,
.kdelta.kdelta-none { color: var(--muted); font-weight: 500; }
.kdelta .kd-none { font-weight: 600; }

/* ---- Analytics panel grid ----
   Payment 2/3 + Daily Average 1/3 share one row. The lost file also carried
   `grid-column: 1 / -1` on both, which forced each onto its own full-width row
   and hid the 2/3 + 1/3 split entirely. */
/* ---- Payment & Settlement / Daily Average: equal halves, glassed ----
   Was 2fr 1fr, so Payment carried double Daily Average's width while both were
   asked to hold the same kind of content. */
.analytics-view .grid-pay-daily {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  /* `start`, not `stretch`. This block used to declare BOTH, in this order -
     `start` then `stretch` - and the second won, so the panels were forced to
     one shared height and the Payment column's last card was clipped off the
     bottom. Stretching two panels whose content differs by even a few pixels
     guarantees the shorter one loses something. Each panel now takes its own
     content height and the row grows to fit the taller. */
  align-items: start;
}
.analytics-view .analytics-payment,
.analytics-view .analytics-daily {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
/* The panel is lifted into its own stacking context above the sections that
   follow it. The hover menu is absolutely positioned inside the chart, and
   near the bottom of the donut it reaches past this panel's edge - where,
   without this, Performance Overview painted over it and the menu vanished
   under the next section exactly where you were hovering. */
.analytics-view .analytics-payment { position: relative; z-index: 3 }
/* Stretch both panels to the same height so the pair reads as one row. The
   payment side holds a donut, the daily side a grid of tiles; left to their own
   content they ended up visibly different heights. */
/* Both panels stretch to the taller of the two, so the content wrapper must be
   allowed to be that tall as well. `min-height: 0` let the Daily Average cards
   keep their natural height while the panel stayed sized by the Payment side,
   so the second row of cards spilled past the panel's bottom edge. */
.analytics-view .analytics-payment > div,
.analytics-view .analytics-daily > div { flex: 1; min-height: min-content; }
.analytics-view .analytics-payment,
.analytics-view .analytics-daily {
  background: color-mix(in srgb, var(--card) 44%, transparent);
  -webkit-backdrop-filter: blur(20px) saturate(170%);
  backdrop-filter: blur(20px) saturate(170%);
  border: 1px solid color-mix(in srgb, var(--border) 58%, transparent);
  box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 20%, transparent),
    0 10px 30px -18px rgba(0, 0, 0, .26);
}
/* The Payment legend rows are glassed by `.pay-lg` in ui-perf.css, which loads
   later and sets the full treatment. Nothing is declared here: an earlier
   revision added a second rule scoped to `.analytics-view`, which outranked it
   and replaced the finished glass with a flatter, lighter fill. */
.analytics-view .analytics-payment #paymentChart { min-height: 200px }
.analytics-view .analytics-cities,
.analytics-view .analytics-couriers { min-height: 240px }
.analytics-view .grid-sales-funnel {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 14px;
  align-items: start;
}
.analytics-view .grid-courier-cities {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 14px;
  align-items: start;
}
@media (max-width: 1100px) {
  .analytics-view .grid-pay-daily,
  .analytics-view .grid-sales-funnel,
  .analytics-view .grid-courier-cities { grid-template-columns: 1fr }
}

/* ---- Analytics KPI toggle (delivered / returned as % or raw) ----
   Icon-only button sitting beside the KPI label. It needs an explicit box and
   an explicitly sized SVG, otherwise the icon collapses to a 2px sliver next to
   the label and reads as a rendering fault. */
.kpi-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  margin-left: 8px;
  vertical-align: middle;
  /* Glassed like the other inline controls, not a flat `var(--elev)` chip. */
  border: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  border-radius: 7px;
  background: color-mix(in srgb, var(--card) 48%, transparent);
  -webkit-backdrop-filter: blur(16px) saturate(170%);
  backdrop-filter: blur(16px) saturate(170%);
  /* White glyph with a dark drop-shadow. It was `var(--muted)`, which on the
     dark theme is a mid grey that vanished against the card, and the switch was
     invisible exactly when you needed to find it. */
  color: #fff;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .55));
  cursor: pointer;
  transition: background var(--dur-fast), border-color var(--dur-fast), transform var(--dur-fast);
}
.kpi-toggle svg { width: 14px; height: 14px; display: block; flex: 0 0 auto }
.kpi-toggle svg path { stroke: currentColor }
.kpi-toggle:hover {
  border-color: var(--primary);
  background: color-mix(in srgb, var(--card) 70%, transparent);
  transform: scale(1.06);
}
.kpi-toggle:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px }
.kpi .lbl { display: flex; align-items: center; }

/* ---- Quick-filter group inside a date dropdown ----
   Sits under the date picker and is a plain stack of the same .dd-opt rows, so
   it needs no rules of its own beyond removing the inset the option rows carry
   in the presets section. Styled here so the class the markup emits is not
   left unstyled. */
.date-dropdown-panel .dd-quick { display: flex; flex-direction: column; gap: 2px; padding: 0 2px }

/* ---- Comparison chip inside a Performance Overview tile ----
   The tile is a label over a value with no foot, so the chip needs its own
   placement here - `margin-top: auto` (which the KPI card uses to push the chip
   to the bottom) would do nothing inside a grid item that is not a flex
   column. */
.perf-kpi .kdelta { margin-top: 4px; padding-top: 0; font-size: 9.5px; gap: 3px; justify-content: flex-start }
.perf-kpi .kdelta em { font-size: 9px; font-style: normal }
.perf-kpi .kdelta .kd-arrow { font-size: 10px }
/* The Performance range is a dropdown now, so it has to sit in the header the
   way the page-level one does. */
#perfDateDropdown .date-dropdown-panel { min-width: 230px }

/* The figure is the point of the card, so it is centred on both axes rather
   than left-aligned under a left-aligned label. The label and delta chip keep
   their own alignment; only the number is centred. */
.analytics-view .kpi .num {
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 30px;
}

/* ---- City pie / donut ---- */
.pie-stack { display: flex; flex-direction: column; gap: 10px }
.pie-holder { position: relative; display: flex; justify-content: center }
.pie-svg { width: 150px; height: 150px; overflow: visible }
.pie-svg [data-city-key] { transition: opacity var(--dur-fast) }
.pie-svg [data-city-key]:hover { opacity: .82 }
.pie-tip {
  position: absolute; left: 0; right: 0; bottom: 0;
  pointer-events: none; opacity: 0;
  transition: opacity var(--dur-fast);
}
.pie-cap {
  font-size: 9.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .6px; color: var(--muted); text-align: center;
}
.pie-legend {
  display: flex; flex-direction: column;
  max-height: 190px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: 10px;
}
.pie-legend-row {
  display: grid;
  grid-template-columns: 10px 1fr auto auto;
  align-items: center; gap: 8px;
  padding: 7px 10px; cursor: pointer;
  border-bottom: 1px solid var(--border);
}
.pie-legend-row:last-child { border-bottom: none }
.pie-legend-row:hover { background: var(--elev) }
.pie-legend-row .sw { width: 10px; height: 10px; border-radius: 3px }
.pie-legend-row .nm { font-size: 12px; color: var(--label); font-weight: 500 }
.pie-legend-row .ct { font-size: 11.5px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums }
.pie-legend-row .pc { font-size: 10.5px; color: var(--muted); min-width: 42px; text-align: right; font-variant-numeric: tabular-nums }
.pie-legend-row.is-other { border-top: 1px solid var(--border); margin-top: 3px; padding-top: 6px }
[data-theme="dark"] .pie-legend-row .nm { color: #FFFFFF }
.pie-all-btn {
  align-self: center;
  padding: 7px 14px; border-radius: 8px;
  border: 1px solid var(--primary); background: transparent;
  color: var(--primary); font-size: 10.5px; font-weight: 600;
  font-family: inherit; cursor: pointer;
}
.pie-all-btn:hover { background: var(--primary-soft) }

/* ---- City report full page ----
   "View All Cities" is a full page, not a drawer. Base .modal-bg aligns its
   child to flex-end, which squeezed this panel against the right edge. */
.analytics-view .modal-bg#cityReportPage {
  background: rgba(0,0,0,.55);
  justify-content: stretch;
  align-items: stretch;
  padding: 0;
}
[data-theme="dark"] .analytics-view .modal-bg#cityReportPage { background: rgba(0,0,0,.72) }
.analytics-view .modal-bg#cityReportPage > .odp {
  width: 100%; max-width: 100%; box-shadow: none;
}
.analytics-view .modal-bg.is-drawer {
  justify-content: flex-end; align-items: stretch; padding: 0;
}
.analytics-view .is-drawer .odp-body { flex: 1; overflow-y: auto; padding-bottom: 20px }
.analytics-view .modal-bg#cityOrdersPage { background: rgba(0,0,0,.62) }
[data-theme="dark"] .analytics-view .modal-bg#cityOrdersPage { background: rgba(0,0,0,.78) }
.analytics-view .drawer {
  width: min(560px, 100%);
  height: 100%;
  background: var(--card);
  border-left: 1px solid var(--border);
  box-shadow: -16px 0 44px rgba(0,0,0,.22);
  display: flex; flex-direction: column;
}

/* ---- City toolbar, summary and drill-down rows ---- */
.city-toolbar {
  display: flex; gap: 10px; margin-bottom: 14px;
  align-items: center; flex-wrap: wrap;
}
.city-toolbar input[type="search"] {
  flex: 1; min-width: 180px; height: 34px;
  padding: 0 12px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--elev);
  color: var(--text); font-size: 11.5px; font-family: inherit;
}
.city-toolbar input[type="search"]:focus { outline: none; border-color: var(--primary) }
.city-tools { display: flex; gap: 8px; align-items: center }
.city-summary {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px; margin-bottom: 16px;
}
.city-summary .cs {
  padding: 11px 12px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--elev);
}
.city-summary .cs .cl {
  font-size: 9px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .5px; color: var(--muted); margin-bottom: 3px;
}
.city-summary .cs .cv { font-size: 17px; font-weight: 700; color: var(--text) }
.city-sum-cell { font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums }
.city-report-row td { font-size: 11.5px }
.city-row-link, .city-all-link {
  color: var(--primary); cursor: pointer; font-weight: 600;
  background: none; border: none; font-family: inherit; font-size: inherit;
  padding: 0; text-align: left;
}
.city-row-link:hover, .city-all-link:hover { text-decoration: underline }
/* Row-end arrow. It carried only a colour, so the browser's default grey
   button chrome showed through - the bare box in the screenshot. Same glass
   pill language as the report's own mini buttons. */
.city-arrow {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0;
  border-radius: 8px;
  border: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
  background: color-mix(in srgb, var(--card) 52%, transparent);
  color: var(--label);
  font-size: 13px; line-height: 1; font-family: inherit;
  cursor: pointer;
  transition: border-color var(--dur-fast), color var(--dur-fast), background var(--dur-fast);
}
.city-arrow:hover {
  border-color: var(--primary);
  color: var(--primary);
  background: var(--primary-soft);
}

/* ---- City report sort: filter icon + two-option menu (C6/C7) ----
   The 8-option select is gone. One menu, two triggers (toolbar + # header). */
.city-filter { position: relative; display: inline-flex; }
.city-filter-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
  background: color-mix(in srgb, var(--card) 52%, transparent);
  -webkit-backdrop-filter: blur(18px) saturate(160%);
  backdrop-filter: blur(18px) saturate(160%);
  color: var(--label);
  cursor: pointer;
  transition: border-color var(--dur-fast), color var(--dur-fast), background var(--dur-fast);
}
.city-filter-btn:hover { border-color: var(--primary); color: var(--primary); }
.city-filter-btn[aria-expanded="true"] { border-color: var(--primary); color: var(--primary); background: var(--primary-soft); }
.city-filter-menu {
  position: fixed; z-index: 60;
  min-width: 180px; padding: 5px;
  display: flex; flex-direction: column; gap: 2px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 18px 40px -12px rgba(0, 0, 0, .35);
}
.city-filter-menu[hidden] { display: none; }
.city-filter-menu button {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; border: 0; border-radius: 8px;
  background: transparent; color: var(--label);
  font-family: inherit; font-size: 11.5px; font-weight: 600; text-align: left;
  cursor: pointer;
}
.city-filter-menu button:hover { background: var(--elev); color: var(--text); }
.city-filter-menu button.is-on { color: var(--primary); background: var(--primary-soft); }
/* The # header keeps its number and gains the same control. */
.city-sort-th { white-space: nowrap; }
.city-sort-th .city-sort-h { font-size: 9px; font-weight: 600; color: var(--muted); margin-right: 4px; }
.city-sort-th .city-filter-btn { width: 24px; height: 24px; }
.city-couriers-h {
  font-size: 9.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .6px; color: var(--muted); margin: 16px 0 8px;
}
.city-couriers { display: flex; flex-direction: column; gap: 6px }
.city-courier-row {
  display: grid; grid-template-columns: 1fr auto auto auto;
  gap: 10px; align-items: center;
  padding: 8px 10px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--elev);
}
.city-courier-row .cc-name { font-size: 11.5px; font-weight: 600; color: var(--label) }
.city-courier-row .cc-n { font-size: 11px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums }
/* Both percentages, matching the KPI strip's own language: delivered green,
   returned red. Each takes its own fixed-width track so the columns line up
   down the whole list. */
.city-courier-row .cc-dp,
.city-courier-row .cc-rp {
  font-size: 10.5px; font-weight: 700; font-variant-numeric: tabular-nums;
  min-width: 44px; text-align: right;
}
.city-courier-row .cc-dp { color: #16A34A }
.city-courier-row .cc-rp { color: #DC2626 }
[data-theme="dark"] .city-courier-row .cc-dp { color: #4ADE80 }
[data-theme="dark"] .city-courier-row .cc-rp { color: #F87171 }
/* Reconciliation line under the list: courier rows vs every order in the
   drawer, so the two panels cannot quietly disagree. */
.cc-total {
  margin-top: 10px; padding: 8px 10px;
  font-size: 10.5px; color: var(--muted);
  border-top: 1px solid var(--border);
}
.cc-total b { color: var(--text); font-weight: 700 }
.cc-bar {
  grid-column: 1 / -1; height: 8px; border-radius: 4px;
  background: color-mix(in srgb, var(--border) 70%, transparent);
  overflow: hidden;
}
/* Three status bands, same colours as Courier Performance: delivered green,
   returned red, in transit blue. This bar used to be a single fill in a
   per-courier identity colour, so it named the courier rather than the outcome. */
.cc-split { display: flex; height: 100%; width: 100%; }
.cc-bar .cc-s { display: block; height: 100%; flex: 0 0 auto; transition: filter .12s ease, transform .12s ease; }
.cc-bar .cc-del { background: #22C55E; }
.cc-bar .cc-ret { background: #EF4F57; }
.cc-bar .cc-tra { background: #3B82F6; }
/* Fourth band: cancelled / unrecognised statuses. Without it the three known
   bands did not fill the track and the bar under-reported the courier. */
.cc-bar .cc-oth { background: #94A3B8; }
.cc-bar:hover .cc-s { filter: brightness(1.12) saturate(1.1); }
.cc-bar .cc-s:hover { filter: brightness(1.24) saturate(1.16); transform: scaleY(1.35); }
.cc-legend {
  display: flex; gap: 14px; margin-top: 2px;
  font-size: 9.5px; color: var(--muted);
}
.cc-legend span { display: inline-flex; align-items: center; gap: 5px; }
.cc-legend i { width: 9px; height: 9px; border-radius: 3px; display: block; }
.cc-legend i.d { background: #22C55E; }
.cc-legend i.r { background: #EF4F57; }
.cc-legend i.t { background: #3B82F6; }
.cc-legend i.o { background: #94A3B8; }
[data-theme="dark"] .city-courier-row .cc-name { color: #FFFFFF }
.city-detail-row td { font-size: 11px }

/* ---- Payment / settlement money blocks ----
   Markup is <div class="pay-cell"><span>Label</span><b class="pay-net">Money</b></div>
   — the label span carries NO class, so keying off .pay-label never matched and
   the label and figure ran together on one line ("Gross COD Volume955,700 PKR"). */
.pay-cell,
.pay-settle-cell {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.pay-cell > span,
.pay-settle-cell > span {
  display: block;
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .5px;
  color: var(--muted);
}
.pay-cell > b,
.pay-settle-cell > b {
  display: block;
  font-size: 18px;
  font-weight: 700;
  line-height: 1.15;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  word-break: break-word;
}
.pay-settle-cell > b { font-size: 17px }
.pay-cell > b.pay-deduct { color: var(--danger) }
.pay-cell > b.pay-pending,
.pay-settle-cell > b.pay-pending { color: #B8760F }
.pay-cell > b.pay-net,
.pay-settle-cell > b.pay-net { color: var(--text) }
.pay-sub { font-size: 10px; color: var(--muted); margin-top: 3px }
.pay-block { margin-bottom: 18px }
.pay-gross { font-size: 18px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums }
.pay-status-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 9px 12px; border-radius: 9px;
  border: 1px solid var(--border); background: var(--elev);
  margin-bottom: 7px;
}
.pay-status-row .pay-bar-lbl { font-size: 11.5px; font-weight: 600; color: var(--label) }
.pay-status-row .pay-bar-val { font-size: 12px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums }
.pay-bar-row { margin-bottom: 12px }
.pay-bar-meta {
  display: flex; justify-content: space-between; margin-bottom: 5px;
  font-size: 11px; color: var(--label);
}
.pay-bar-meta b { color: var(--text); font-variant-numeric: tabular-nums }
.pay-bar-track {
  height: 8px; border-radius: 4px;
  background: var(--border); overflow: hidden;
}
.pay-bar-track > i { display: block; height: 100%; border-radius: 4px; background: var(--primary) }

/* ---- Sales funnel (vertical bars) ----
   Markup is value / track(filled by inline height:%) / caption(count + label),
   so the track has to be a tall column for that percentage to mean anything.
   Without a definite track height the percentage resolved against nothing and
   every bar rendered full width. */
.funnel-bars { display: flex; flex-direction: column; gap: 13px }
.funnel-bars .fn-col { display: flex; flex-direction: column; gap: 5px; min-width: 0 }
.funnel-bars .fn-val { font-size: 13px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums }
.funnel-bars .fn-track {
    /* No height here on purpose. An identical selector in ui-perf.css sets the
       real value and that file loads later, so anything declared in this block
       was silently overridden - which is why the bars stayed at 190px through
       several attempts to shrink them. The height lives with the rule that
       actually wins. */
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--elev);
  display: flex;
  align-items: flex-end;
  overflow: hidden;
}
/* ---- Order Funnel: liquid pools ----
   Each stage is a capsule ("vessel") holding a pool of coloured liquid whose
   surface is an ellipse that drifts and tilts, with a soft sheen sliding across
   it. This replaces the previous scalloped bar, whose identical repeating bumps
   read as a decorative texture rather than as liquid.

   --fn-h is the fill target as a percentage of the vessel; --fn-c is the stage
   colour. The pool is anchored to the bottom and the vessel clips it, so the
   liquid takes the capsule's own curve at the bottom instead of sitting in a
   rectangle inside it. */
.funnel-bars .fn-track {
  overflow: hidden;
  isolation: isolate;
}
.funnel-bars .fn-liquid {
  position: absolute;
  /* Wider than the vessel and offset left, so the drifting surface never exposes
     an edge at either end of the capsule. */
  left: -8%;
  width: 116%;
  bottom: 0;
  /* Starts empty and rises to its target on first paint, so the pools read as
     filling rather than as bars that were already full. `forwards` holds the
     final height; without it the pool drops back to 0 the moment the animation
     ends. */
  height: 0;
  animation: fn-fill-up .95s cubic-bezier(.2, .8, .2, 1) .12s forwards;
  border-radius: 0 0 999px 999px;
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--fn-c, var(--primary)) 82%, #fff) 0%,
      var(--fn-c, var(--primary)) 52%,
      color-mix(in srgb, var(--fn-c, var(--primary)) 86%, #101a2e) 100%);
  box-shadow:
    inset 0 8px 15px rgba(255, 255, 255, .13),
    0 -4px 16px color-mix(in srgb, var(--fn-c, var(--primary)) 15%, transparent);
}
@keyframes fn-fill-up {
  from { height: 0; }
  to   { height: var(--fn-h, 0%); }
}
/* The surface: one wide ellipse riding the top of the pool. Drifting and tilting
   it is what sells the liquid - a static ellipse reads as a lid. */
.funnel-bars .fn-liquid::before {
  content: '';
  position: absolute;
  left: -4%;
  width: 108%;
  /* The surface crest. Was 25px, which stood taller than the coloured pool it
     sits on and read as a separate band rather than the top of the same
     liquid. The vessel keeps its full height - only the wave is reduced. */
  height: 11px;
  top: -5px;
  border-radius: 50%;
  background: var(--fn-c, var(--primary));
  box-shadow: inset 0 1px 4px rgba(255, 255, 255, .16);
  animation: fn-drift .8s ease-in-out infinite alternate;
}
/* Sheen: a blurred highlight sliding across the surface. */
.funnel-bars .fn-liquid::after {
  content: '';
  position: absolute;
  top: -3px;
  left: -10%;
  width: 120%;
  height: 8px;
  opacity: .42;
  border-radius: 50%;
  background: radial-gradient(ellipse at 30% 55%, rgba(255, 255, 255, .65), transparent 40%);
  filter: blur(3px);
  animation: fn-sheen .7s ease-in-out infinite alternate;
  pointer-events: none;
}
/* A paler swell trailing behind the surface, on the far side of the pool. */
.funnel-bars .fn-wave {
  position: absolute;
  z-index: -1;
  top: -8px;
  left: -10%;
  width: 120%;
  height: 12px;
  opacity: .38;
  border-radius: 45%;
  background: color-mix(in srgb, var(--fn-c, var(--primary)) 70%, #fff);
  animation: fn-drift 1s ease-in-out infinite alternate-reverse;
  pointer-events: none;
}
@keyframes fn-drift {
  from { transform: translateX(-3%) rotate(-1deg) scaleY(.9); }
  to   { transform: translateX(4%) rotate(1.2deg) scaleY(1.08); }
}
@keyframes fn-sheen {
  from { transform: translateX(-9%) scaleX(.88); opacity: .22; }
  to   { transform: translateX(12%) scaleX(1.1); opacity: .55; }
}
/* Motion reduced: drop the drift and sheen movement but keep the pool filled at
   its target height, so it still reads as liquid rather than as an empty vessel.
   The fill-up animation is disabled too — its end state IS the target height,
   so cancelling it and setting the height directly is the same result. */
@media (prefers-reduced-motion: reduce) {
  .funnel-bars .fn-liquid,
  .funnel-bars .fn-liquid::before,
  .funnel-bars .fn-liquid::after,
  .funnel-bars .fn-wave { animation: none; }
  .funnel-bars .fn-liquid { height: var(--fn-h, 0%); }
  .funnel-bars .fn-liquid::after { opacity: .5; }
}
.funnel-bars .fn-cap {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 10px; min-width: 0;
}
.funnel-bars .fn-cap b { font-size: 12px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; flex: 0 0 auto }
.funnel-bars .fn-cap span {
  font-size: 11px; color: var(--label);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  text-align: right;
}
.funnel-bars .fn-time {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 10px; font-size: 10.5px; color: var(--muted);
}
.funnel-bars .fn-time b { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums }
.funnel-bars .fn-times { font-size: 10px; color: var(--muted); min-height: 14px }
.funnel-bars .fn-note { font-size: 10px; color: var(--muted); margin-top: 2px }
/* These two live OUTSIDE .funnel-bars (the stage list and the timing block are
   siblings), so scoping them under it never matched and the label ran into the
   value: "Avg time to deliver2.0 days". */
.fn-times { font-size: 10px; color: var(--muted); margin-top: 10px }
.fn-time {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 10px; font-size: 10.5px; color: var(--muted);
}
.fn-time b { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums }
/* Grid children default to min-width:auto, which lets a wide label blow the
   column out and push the card past the panel edge. */
.analytics-view .analytics-sales,
.analytics-view .analytics-funnel,
.analytics-view .analytics-daily,
.analytics-view .analytics-payment,
.analytics-view .analytics-cities,
.analytics-view .analytics-couriers { min-width: 0 }

/* ---- Order status split (donut + list) ---- */
.os-list { display: flex; flex-direction: column; gap: 7px }
.os-row {
  display: grid; grid-template-columns: 10px 1fr auto auto;
  gap: 8px; align-items: center;
  padding: 7px 9px; border-radius: 8px; cursor: pointer;
  border: 1px solid transparent;
}
.os-row:hover { background: var(--elev); border-color: var(--border) }
.os-swatch { width: 10px; height: 10px; border-radius: 3px }
.os-label { font-size: 11.5px; color: var(--label); font-weight: 500 }
.os-n { font-size: 12px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums }
.os-pct { font-size: 10.5px; color: var(--muted); min-width: 44px; text-align: right }
.os-bar { grid-column: 1 / -1; height: 4px; border-radius: 2px; background: var(--border); overflow: hidden }
.os-bar > i { display: block; height: 100%; background: var(--primary) }
.os-foot { font-size: 10.5px; color: var(--muted); margin-top: 10px }
.os-row.other .os-label { color: var(--muted) }

/* ---- Performance chart legend ---- */
.perf-legend {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  font-size: 10.5px; color: var(--muted); margin-top: 8px;
}
.perf-legend span { display: inline-flex; align-items: center; gap: 6px }
.perf-legend i { width: 9px; height: 9px; border-radius: 3px; display: inline-block }
.perf-legend-note { margin-left: auto }
/* Courier performance toolbar: the List/Cards switch on the left, the search
   field filling the remaining width, both on ONE line.

   They were on separate rows, and because the switch row carried no bottom
   margin of its own the courier cards underneath started immediately below it,
   which read as the tabs sitting on top of the cards. */
.cq-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 10px 0 14px;
  flex-wrap: wrap;
}
/* The switch keeps its intrinsic width; only the search flexes. */
.cq-toolbar > .seg {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: color-mix(in srgb, var(--elev) 72%, transparent);
  position: relative;
}
.cq-toolbar > .seg .seg-btn {
  height: 28px;
  padding: 0 13px;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--label);
  font-family: inherit;
  font-size: 10.5px;
  font-weight: 600;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  position: relative;
  z-index: 1;
}
.cq-toolbar input[type="search"] {
  flex: 1 1 200px;
  min-width: 160px;
  height: 34px;
  padding: 0 13px;
  border-radius: 10px;
  border: 1px solid color-mix(in srgb, var(--border) 62%, transparent);
  background: color-mix(in srgb, var(--card) 44%, transparent);
  -webkit-backdrop-filter: blur(16px) saturate(165%);
  backdrop-filter: blur(16px) saturate(165%);
  box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 22%, transparent);
  color: var(--text);
  font-size: 11.5px;
  font-family: inherit;
}
.cq-toolbar input[type="search"]::placeholder { color: var(--muted); }
.cq-toolbar input[type="search"]:focus {
  outline: none;
  border-color: var(--primary);
  background: color-mix(in srgb, var(--card) 62%, transparent);
}
.perf-empty { padding: 26px; text-align: center; color: var(--muted); font-size: 11.5px }
.perf-range-hint { font-size: 10px; color: var(--muted); margin-top: 6px; text-align: center }

/* ---- Courier performance: table + cards ---- */
.cq-table { width: 100%; border-collapse: collapse }
.cq-tr td { font-size: 11.5px; padding: 8px 6px; border-bottom: 1px solid var(--border) }
.cq-td-name { font-weight: 600; color: var(--text) }
.cq-row {
  display: grid; grid-template-columns: 1fr 46px 60px;
  gap: 8px; align-items: center;
  padding: 9px 4px; border-bottom: 1px solid var(--border);
  cursor: pointer;
}
.cq-row:hover { background: var(--elev) }
.cq-name { font-size: 11.5px; font-weight: 600; color: var(--label) }
.cq-n { font-size: 11px; font-weight: 700; text-align: right; color: var(--text); font-variant-numeric: tabular-nums }
.cq-na { font-size: 10.5px; color: var(--muted); text-align: right }
.cq-bar { grid-column: 1 / -1; display: flex; height: 5px; border-radius: 3px; overflow: hidden; background: var(--border) }
.cq-bar > i { display: block; height: 100% }
.cq-mix-del { background: #22C55E }
.cq-mix-ret { background: #EF4F57 }
.cq-scroll { max-height: 320px; overflow-y: auto }
.cq-cards {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 11px;
}
.cq-card {
  border: 1px solid var(--border); border-radius: 12px;
  padding: 13px; background: var(--card); cursor: pointer;
  transition: transform var(--dur-fast), box-shadow var(--dur-fast);
}
.cq-card:hover { transform: translateY(-2px); box-shadow: 0 8px 22px rgba(0,0,0,.10) }
.cqc-top { display: flex; align-items: center; gap: 9px; margin-bottom: 10px }
.cqc-logo {
  width: 32px; height: 32px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden; flex: 0 0 auto;
}
.cqc-logo img { width: 100%; height: 100%; object-fit: cover }
.cqc-initials { font-size: 11px; font-weight: 700 }
.cqc-nm { font-size: 12px; font-weight: 700; color: var(--text); line-height: 1.2 }
.cqc-duo { font-size: 10px; color: var(--muted); margin-top: 1px }
.cqc-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px }
.cqc-lbl { font-size: 8.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--muted) }
.cqc-flag { font-size: 10px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums }
.cqc-rate { font-size: 10px; color: var(--muted); margin-top: 8px }
.cqc-sep { grid-column: 1 / -1; height: 1px; background: var(--border); margin: 6px 0 }
.cq-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block }
/* The courier delivery-rate legend was removed from the panel; its rule goes with
   it. `.cq-mixcap` below is still used by the card view. */
.cq-mixcap { font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--muted); margin: 12px 0 6px }
.cq-stat { font-size: 11px; color: var(--label) }
.cq-stat b { color: var(--text); font-variant-numeric: tabular-nums }

/* ---- Courier detail popup (X-only by design) ----
   Same shell as every other dialog in the app: glassed surface, matching radius
   and shadow, centred. It was the one overlay still painted as an opaque
   var(--card) block with a hard 1px border, so opening a courier from Analytics
   looked like a different product. */
.cq-popup {
  position: fixed; inset: 0; margin: auto;
  width: min(560px, 92vw); height: fit-content;
  max-height: 86vh; overflow-y: auto;
  z-index: 260; padding: 22px;
  border-radius: 20px;
  border: 1px solid color-mix(in srgb, var(--border) 48%, transparent);
  background: color-mix(in srgb, var(--card) 82%, transparent);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  backdrop-filter: blur(24px) saturate(180%);
  box-shadow: 0 24px 64px rgba(15, 17, 23, .28);
  animation: cqPop .22s cubic-bezier(.2, .9, .3, 1.05);
}
@keyframes cqPop {
  from { opacity: 0; transform: translateY(12px) scale(.97); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .cq-popup { animation: none; } }
/* Inside the popup the tiles sit on glass, so they get a solid face of their own
   to keep their figures legible against the blur. */
.cq-popup .cq-pop-grid > div {
  background: color-mix(in srgb, var(--card) 88%, transparent);
  border: 1px solid color-mix(in srgb, var(--border) 40%, transparent);
  border-radius: 12px;
  padding: 11px 13px;
}
.cq-pop-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px; margin: 14px 0;
}
.cq-pop-duo { display: flex; flex-direction: column; gap: 2px }
/* Courier popup headline figures: four KPI cards laid out ACROSS the panel.
   They were a vertical flex column, so the cards stacked downward and pushed
   the money grid off the bottom. */
.cq-popup .cq-pop-kpis {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}
.cq-popup .cq-kpi {
  display: flex; flex-direction: column; gap: 3px;
  min-width: 0;
  padding: 12px 13px 11px;
  border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
  border-top: 3px solid var(--kpi-t, var(--border));
  background: color-mix(in srgb, var(--card) 70%, transparent);
}
.cq-popup .cq-kpi-l {
  font-size: 9.5px; font-weight: 700; letter-spacing: .5px;
  text-transform: uppercase; color: var(--muted); line-height: 1.2;
}
.cq-popup .cq-kpi b {
  font-size: 19px; font-weight: 700; line-height: 1.15;
  font-variant-numeric: tabular-nums; letter-spacing: -.3px;
  color: var(--text);
}
.cq-popup .cq-kpi i {
  font-style: normal; font-size: 10.5px; color: var(--muted); line-height: 1.3;
}
@media (max-width: 720px) {
  .cq-popup .cq-pop-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)) }
}
/* Each cell holds a bare <b> and a bare <span>. Both are inline by default, so
   they ran together on one line - "68.4%Deliver", "COD16,766,269 PKR" - which
   is what made the popup look broken. Each cell stacks them instead. This is
   the same defect the customer panel had (.cd-cell), so both now match. */
.cq-popup .cq-pop-duo > div,
.cq-popup .cq-pop-grid > div {
  display: flex; flex-direction: column; gap: 3px;
  min-width: 0;
}
.cq-popup .cq-pop-duo > div > b,
.cq-popup .cq-pop-grid > div > b {
  font-size: 15px; font-weight: 700; line-height: 1.2;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
/* The duo's <b> carries an inline brand colour per figure, so no colour is set
   here for it - only size, letting those semantic hues through. */
.cq-popup .cq-pop-grid > div > b { color: var(--text) }
.cq-popup .cq-pop-duo > div > span,
.cq-popup .cq-pop-grid > div > span {
  font-size: 10.5px; color: var(--muted); line-height: 1.35;
}
.cq-pop-bar { height: 6px; border-radius: 3px; background: var(--border); overflow: hidden; margin-top: 8px }
.cq-pop-bar > i { display: block; height: 100%; background: var(--primary) }

/* ---- Products performance table ---- */
.ptable { width: 100%; border-collapse: collapse }
.ptable td { padding: 8px 6px; font-size: 11.5px; border-bottom: 1px solid var(--border) }
.pmeta { font-size: 10px; color: var(--muted) }
.thumb {
  width: 34px; height: 34px; border-radius: 7px;
  object-fit: cover; background: var(--elev); flex: 0 0 auto;
}
.ps-bar { height: 5px; border-radius: 3px; background: var(--border); overflow: hidden; margin-top: 4px }
.ps-bar > i { display: block; height: 100%; background: var(--primary) }
.ps-num { font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums }
.rank-list { display: flex; flex-direction: column; gap: 2px }
.rank-row {
  display: grid; grid-template-columns: 22px 1fr 70px 54px;
  gap: 8px; align-items: center;
  padding: 8px 6px; border-radius: 8px;
}
.rank-row:hover { background: var(--elev) }
.rank-n {
  width: 20px; height: 20px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--elev); color: var(--muted);
  font-size: 9.5px; font-weight: 700;
}
.rank-row:nth-child(1) .rank-n { background: var(--primary); color: #fff }
.rank-nm { font-size: 11.5px; font-weight: 600; color: var(--label) }
.rank-qty { font-size: 11px; color: var(--muted); text-align: right; font-variant-numeric: tabular-nums }
.rank-bar { grid-column: 2 / -1; height: 4px; border-radius: 2px; background: var(--border); overflow: hidden }
.rank-bar > i { display: block; height: 100%; background: var(--primary) }
.rank-foot { font-size: 10.5px; color: var(--muted); margin-top: 8px }

/* ---- Product ranking: sample data ----
   The panel falls back to invented rows when no product data exists, so the
   layout can still be judged. The labelling is deliberately loud: a filled
   amber tag, an explanatory line, and a dashed border down the list, because a
   ranking of plausible numbers is exactly the thing someone could mistake for
   their own. Amber is used rather than the primary blue so it never reads as a
   normal informational state. */
.sample-banner {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  margin-bottom: 12px; padding: 10px 12px;
  border: 1px dashed color-mix(in srgb, #F5A524 55%, transparent);
  border-radius: 10px;
  background: color-mix(in srgb, #F5A524 9%, transparent);
}
.sample-banner .sb-tag {
  flex: none; padding: 2px 8px; border-radius: 999px;
  background: #F5A524; color: #1A1408;
  font-size: 9.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .4px;
}
.sample-banner .sb-text { font-size: 11px; color: var(--text); line-height: 1.45; flex: 1 1 220px; min-width: 0 }
.sample-banner .sb-actions { display: flex; gap: 6px; margin-left: auto }
.sample-banner .sb-actions .mini-btn {
  font: inherit; font-size: 10.5px; font-weight: 600; color: var(--text);
  background: var(--card); border: 1px solid var(--border);
  border-radius: 8px; padding: 5px 10px; cursor: pointer;
}
.sample-banner .sb-actions .mini-btn:hover { border-color: var(--primary); color: var(--primary) }
.rank-list:has(.rank-row.is-sample) { border-left: 2px dashed color-mix(in srgb, #F5A524 45%, transparent); padding-left: 8px; margin-left: -10px }
.rank-row.is-sample .rank-nm { font-style: italic }
.sample-foot { color: color-mix(in srgb, #F5A524 70%, var(--muted)); font-weight: 600 }

/* ---- Export modal ---- */
.exp-modal { width: min(560px, 94vw) }
.es-body { padding: 18px 20px }
.es-title { font-size: 14px; font-weight: 700; color: var(--text) }
.es-actions {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 14px 20px; border-top: 1px solid var(--border);
}
.exp-sects { display: flex; flex-direction: column; gap: 6px; margin: 14px 0 }
.exp-label { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--muted); margin-bottom: 6px }
.exp-chk { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--label); cursor: pointer }
.exp-quick { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px }
.exp-fmt { position: relative; display: inline-block }
.exp-fmt-menu {
  position: absolute; left: 0; bottom: calc(100% + 6px);
  min-width: 190px; z-index: 220;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--card); box-shadow: 0 12px 30px rgba(0,0,0,.20);
  padding: 4px;
}
.exp-fmt-menu button {
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 8px 10px;
  border: none; background: none; cursor: pointer;
  font-size: 11px; font-family: inherit; color: var(--label);
  border-radius: 7px; text-align: left;
}
.exp-fmt-menu button small { margin-left: auto; font-weight: 400; color: var(--muted) }
.exp-fmt-menu button:hover { background: var(--elev) }
.exp-fmt-menu button.on { color: var(--primary) }
.exp-note { font-size: 10.5px; color: var(--muted); margin-top: 10px }

/* ---- Orders: advanced filter panel ---- */
.orders-view .flt { position: relative }
.orders-view .flt-panel {
  position: absolute; right: 0; top: calc(100% + 8px);
  width: min(560px, 92vw); z-index: 210;
  border: 1px solid var(--border); border-radius: 14px;
  background: var(--card);
  box-shadow: 0 18px 44px rgba(0,0,0,.22);
  padding: 16px;
}
.orders-view .flt-title { font-size: 12px; font-weight: 700; color: var(--text); margin-bottom: 12px }
.orders-view .flt-grid { display: flex; flex-direction: column; gap: 14px }
.orders-view .flt-group { display: flex; flex-direction: column; gap: 7px }
.orders-view .flt-box { display: flex; flex-wrap: wrap; gap: 7px }
.orders-view .flt-dates { display: grid; grid-template-columns: 1fr 1fr; gap: 10px }
.orders-view .flt-check {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 10px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--elev);
  font-size: 11px; color: var(--label); cursor: pointer;
}
.orders-view .flt-check:hover { border-color: var(--primary) }
.orders-view .flt-check input { accent-color: var(--primary); margin: 0 }
.orders-view .flt-drop { position: relative }
.orders-view .flt-drop-btn {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; height: 34px; padding: 0 11px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--elev); color: var(--text);
  font-size: 11.5px; font-family: inherit; cursor: pointer;
}
.orders-view .flt-drop-btn:hover { border-color: var(--primary) }
.orders-view .flt-drop-list {
  position: absolute; left: 0; top: calc(100% + 5px);
  min-width: 100%; max-height: 240px; overflow-y: auto; z-index: 230;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--card); box-shadow: 0 12px 30px rgba(0,0,0,.20);
  padding: 4px;
}
.orders-view .flt-drop-list input[type="search"] {
  width: 100%; height: 30px; margin: 2px 2px 6px;
  padding: 0 9px; border-radius: 7px;
  border: 1px solid var(--border); background: var(--elev);
  color: var(--text); font-size: 11px; font-family: inherit;
}
.orders-view .flt-drop-opts { display: flex; flex-direction: column; gap: 1px }
.orders-view .flt-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px; margin-left: 6px;
  border-radius: 9px; background: var(--primary); color: #fff;
  font-size: 9.5px; font-weight: 700;
}
.orders-view .flt-foot {
  display: flex; align-items: center; gap: 10px;
  margin-top: 14px; padding-top: 12px;
  border-top: 1px solid var(--border);
  position: sticky; bottom: -16px;
  background: var(--card);
}
.orders-view .flt-foot .spacer { flex: 1 }
.orders-view .mini-btn {
  height: 28px; padding: 0 11px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--elev);
  color: var(--label); font-size: 10.5px; font-weight: 600;
  font-family: inherit; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
}
.orders-view .mini-btn:hover { border-color: var(--primary); color: var(--primary) }
.orders-view .acts-wrap { position: relative }
.orders-view .acts-menu {
  position: absolute; right: 0; top: calc(100% + 6px);
  min-width: 190px; z-index: 220;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--card); box-shadow: 0 12px 30px rgba(0,0,0,.20);
  padding: 4px;
}
.orders-view .acts-menu button {
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 8px 10px;
  border: none; background: none; cursor: pointer;
  font-size: 11px; font-family: inherit; color: var(--label);
  border-radius: 7px; text-align: left;
}
.orders-view .acts-menu button:hover { background: var(--elev) }
.orders-view .acts-menu button.danger { color: var(--danger) }

/* ---- Orders: per-page popover ----
   .pp (the wrapper) is the positioning context. Without position:relative the
   absolutely-positioned panel resolved against a far ancestor and rendered in
   the bottom-right corner of the page, hundreds of px from its own trigger.
   It also opens upward so it is never clipped by the viewport edge. */
.orders-view .pp { position: relative }
.orders-view .pp-panel {
  position: absolute;
  right: 0;
  bottom: calc(100% + 8px);
  top: auto;
  min-width: 190px;
  z-index: 210;
  /* The JS opens this with .pp.open on the wrapper. Without this gate the
     panel was permanently visible on page load. */
  display: none;
  border: 1px solid var(--border); border-radius: 12px;
  background: var(--card); box-shadow: 0 16px 38px rgba(0,0,0,.20);
  padding: 10px;
}
.orders-view .pp.open .pp-panel { display: block }
.orders-view .pp-row { display: flex; flex-direction: column; gap: 4px }
.orders-view .pp-opt {
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 7px 9px;
  border: none; background: none; border-radius: 8px;
  font-size: 11.5px; font-family: inherit; color: var(--label);
  cursor: pointer; text-align: left; white-space: nowrap;
}
.orders-view .pp-opt:hover { background: var(--elev) }
.orders-view .pp-opt.active { color: var(--primary); font-weight: 600 }
.orders-view .pp-trigger {
  display: inline-flex; align-items: center; gap: 6px;
  height: 30px; padding: 0 10px; border-radius: 8px;
  border: 1px solid color-mix(in srgb, var(--border) 62%, transparent);
  /* Glassed like the other toolbar buttons. `var(--elev)` is a flat dark fill,
     so on the dark theme the control read as a dead grey box - visibly outside
     the family next to the date pill, which is already translucent. */
  background: color-mix(in srgb, var(--card) 46%, transparent);
  -webkit-backdrop-filter: blur(22px) saturate(180%);
  backdrop-filter: blur(22px) saturate(180%);
  color: var(--text);
  font-size: 10.5px; font-weight: 600;
  font-family: inherit; cursor: pointer;
  /* "50 / page" was wrapping onto two lines and lifting the toolbar row. */
  white-space: nowrap;
  transition: border-color .18s ease, background-color .18s ease;
}
.orders-view .pp-trigger:hover { border-color: var(--primary) }
/* The chevron inherits `currentColor`, which is near-white text on the glass -
   but on the dark theme it rendered as a dark wedge against the dark fill and
   was almost invisible. Forced light so it reads as an affordance. */
.orders-view .pp-trigger .chev {
  width: 13px; height: 13px; flex: 0 0 auto;
  color: var(--text);
  stroke: var(--text);
  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, .45));
}
[data-theme="dark"] .orders-view .pp-trigger .chev {
  color: #fff; stroke: #fff; filter: none;
}

/* ---- Orders: table rows, lazy sentinel, pagination ---- */
.orders-view .order-row td { font-size: 11.5px }
.orders-view .td-addr { max-width: 220px; color: var(--muted) }
.orders-view .row-in { animation: row-in .22s ease-out both }
@keyframes row-in { from { opacity: 0; transform: translateY(4px) } to { opacity: 1; transform: none } }
.orders-view .lazy-sentinel td { border-bottom: none; padding: 14px 0 }
.orders-view .lazy-pulse {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-size: 11px; color: var(--muted);
}
.orders-view .lazy-pulse::before {
  content: ""; width: 13px; height: 13px; border-radius: 50%;
  border: 2px solid var(--border); border-top-color: var(--primary);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg) } }
.orders-view .pag-prev, .orders-view .pag-next {
  min-width: 30px; height: 30px; padding: 0 8px;
  border-radius: 8px; border: 1px solid var(--border);
  background: var(--elev); color: var(--label);
  font-size: 11px; font-family: inherit; cursor: pointer;
}
.orders-view .pag-prev:disabled, .orders-view .pag-next:disabled { opacity: .4; cursor: default }
.orders-view .ret-date { font-size: 10.5px; color: var(--muted) }
.orders-view .reloadrow { color: var(--primary); font-size: 10.5px }

/* ---- Analytics panel identities ----
   These carry no layout of their own; they mark which panel a chart or block
   belongs to so the grid rows and any per-panel overrides have a hook. */
.analytics-view .analytics-sales,
.analytics-view .analytics-funnel,
.analytics-view .analytics-daily,
.analytics-view .analytics-payment,
.analytics-view .analytics-cities,
.analytics-view .analytics-couriers { min-width: 0 }
.analytics-view .analytics-daily { min-height: 220px }
.pay-settle { display: flex; flex-direction: column; gap: 10px }
.pay-bar-sub { font-size: 10px; color: var(--muted); margin-top: 2px }
.cq-mixbar { height: 6px; border-radius: 3px; background: var(--border); overflow: hidden; display: flex }
/* The three-up money row has to be able to shrink, or long currency figures
   push the grid wider than the panel. */
.pay-trio,
.pay-settle-grid { display: grid; gap: 10px; min-width: 0 }
.pay-trio { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-bottom: 14px }
.pay-settle-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) }

/* ---- Payment & Settlement: rebuilt to the reference design ----
   Two columns, chart left and the metric list right, per
   "Payment and Settlement.html": a fixed chart column, the list taking the
   rest, centred on one axis.

   Both boxes are deliberately smaller than the reference's 260px. This panel
   shares a grid row with Daily Average, and the row's height is set by
   whichever side is taller - so a large chart plus four metric cards made the
   content ~409px inside a ~372px row, and the surplus was clipped off the
   bottom of the card. The chart is now 180px and the cards are tighter, which
   brings the total back inside the row. */
.analytics-view .pay-donut-wrap {
  display: grid;
  grid-template-columns: 180px minmax(0, 1fr);
  gap: 18px;
  align-items: center;
  /* The whole chart-and-legend group is centred in the panel rather than
     sitting against the left edge, which is what left the rows looking a
     little out of the box. */
  justify-content: center;
}
.analytics-view .pay-donut-box {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 180px;
  height: 180px;
  flex: 0 0 180px;
}
.analytics-view .pay-donut {
  width: 180px;
  height: 180px;
  display: block;
}
/* Segments thicken and glow on hover, as in the reference. */
.analytics-view .pay-arc { transition: stroke-width .2s ease, opacity .2s ease, filter .2s ease }
.analytics-view .pay-arc:hover { filter: drop-shadow(0 0 7px currentColor) }
.analytics-view .pay-legend {
  display: flex; flex-direction: column; gap: 7px;
  min-width: 0;
}
/* One metric card: dot + (title over sub-line) + figure on the right. */
.analytics-view .pay-lg {
  display: grid;
  grid-template-columns: 12px minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 12px;
  padding: 7px 12px;
  border-radius: 13px;
  border: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  border-left: 3px solid var(--lg, var(--border));
  background: color-mix(in srgb, var(--lg, var(--card)) 13%, transparent);
  min-width: 0;
  transition: background .25s ease, transform .25s ease, box-shadow .25s ease;
}
.analytics-view .pay-lg:hover {
  /* From the reference: the whole card lifts on hover, `all` transitioned so
     fill, lift and shadow arrive together rather than in separate steps. */
  background: color-mix(in srgb, var(--lg, var(--card)) 24%, transparent);
  transform: translateY(-2px);
  box-shadow: 0 8px 20px rgba(0, 0, 0, .16);
}
.analytics-view .pay-lg-sw { width: 12px; height: 12px; border-radius: 50%; flex: 0 0 12px }
.analytics-view .pay-lg-t { display: flex; flex-direction: column; min-width: 0 }
.analytics-view .pay-lg-k { font-size: 13px; font-weight: 600; color: var(--text); line-height: 1.25 }
.analytics-view .pay-lg-s {
  font-size: 11px; color: var(--muted); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.analytics-view .pay-lg-v {
  font-size: 15px; font-weight: 700; color: var(--text);
  font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap;
}
@media (max-width: 900px) {
  .analytics-view .pay-donut-wrap { grid-template-columns: minmax(0, 1fr); justify-items: center }
}

/* ---- Customer history + shipper advice ---- */
.cd-metrics {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px; margin-bottom: 14px;
}
/* Styled by CHILD TAG, not by class. The two rules below targeted `.cl` and
   `.cv`, but the markup emits a plain <span> and <b>
   (`<div class="cd-cell"><span>Label</span><b>Value</b></div>`), so neither
   selector matched anything and the cells rendered bare - label and figure
   jammed onto one line, which is exactly what the screenshot showed.
   `.orders-view` is included because the panel is a .modal-bg, outside
   .cd-metrics in the tree for some routes. */
.cd-metrics .cd-cell,
.orders-view .cd-cell {
  display: flex; flex-direction: column; gap: 4px;
  padding: 11px 13px 12px;
  border-radius: 11px;
  border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  background: color-mix(in srgb, var(--card) 62%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  backdrop-filter: blur(14px) saturate(150%);
  box-shadow: 0 4px 14px -8px rgba(15, 17, 23, .3);
  min-width: 0;
}
.orders-view .cd-cell > span,
.cd-metrics .cd-cell > span,
.orders-view .cd-cell .cl,
.cd-metrics .cd-cell .cl {
  font-size: 9.5px; font-weight: 700; letter-spacing: .5px;
  text-transform: uppercase; color: var(--muted); line-height: 1.25;
}
.orders-view .cd-cell > b,
.cd-metrics .cd-cell > b,
.orders-view .cd-cell .cv,
.sa-opt {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 12px; margin-bottom: 8px; cursor: pointer;
  border: 1px solid var(--border); border-radius: 10px; background: var(--elev);
}
.sa-opt:hover { border-color: var(--primary) }
.sa-opt input { accent-color: var(--primary); margin-top: 2px }
.sa-opt b { display: block; font-size: 11.5px; color: var(--text) }
.sa-opt i { font-style: normal; font-size: 10.5px; color: var(--muted); display: block; margin-top: 2px }
.pbody { font-size: 11.5px; line-height: 1.6; color: var(--label) }

/* ---- Posts grid: Instagram / TikTok profile-card layout ----

   This was inheriting the retailer table's .thumb, which is a 34px square —
   a shared class from a completely different table. So the Posts tab rendered
   a row of postage stamps. Everything below is scoped to .comm-panel so the
   retailer table keeps its own thumbnail sizing.

   Image-dominant on purpose: this is a moderation queue, and the operator
   needs to recognise the post at a glance, not read it. Caption and stats
   reveal on hover behind a scrim, which keeps the grid calm while still
   surfacing the comment count at all times — that number is the reason the
   operator opened this view. */
.comm-panel .post-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 5px;
  padding: 2px;
}
.comm-panel .post-card {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: 8px;
  overflow: hidden;
  background: var(--elev);
  cursor: pointer;
  isolation: isolate;
}
.comm-panel .post-card .thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  border-radius: 0;
  background-size: cover;
  background-position: center;
  background-color: var(--elev);
  transition: transform .28s ease;
}
.comm-panel .post-card:hover .thumb { transform: scale(1.04); }
/* No image returned — a reel or a private post. Avoid a blank tile. */
.comm-panel .post-card .thumb:not([style*="background-image"]) {
  background-image: linear-gradient(135deg, var(--elev) 0%, var(--border) 100%);
}
.comm-panel .post-card .kind {
  position: absolute;
  top: 6px; left: 6px;
  z-index: 2;
  padding: 2px 7px;
  border-radius: 999px;
  background: rgba(10, 12, 18, .62);
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .4px;
  text-transform: uppercase;
  backdrop-filter: blur(4px);
}
.comm-panel .post-card .pbody {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 2;
  padding: 22px 10px 9px;
  background: linear-gradient(to top, rgba(8, 10, 16, .92) 12%, rgba(8, 10, 16, 0) 100%);
  color: #fff;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity .2s ease, transform .2s ease;
}
.comm-panel .post-card:hover .pbody,
.comm-panel .post-card:focus-visible .pbody { opacity: 1; transform: translateY(0); }
.comm-panel .post-card .pbody p {
  margin: 0 0 4px;
  font-size: 11px;
  line-height: 1.45;
  color: rgba(255, 255, 255, .94);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.comm-panel .post-card .pbody .pmeta {
  font-size: 10px;
  color: rgba(255, 255, 255, .78);
}
.comm-panel .post-card .pbody .cdot { opacity: .6; }
/* Comment count stays visible without hover: it is the signal that says
   "this post has something to moderate". */
.comm-panel .post-card .ccount {
  position: absolute;
  right: 6px; bottom: 6px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 7px;
  border-radius: 999px;
  background: rgba(10, 12, 18, .62);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  backdrop-filter: blur(4px);
}
.comm-panel .post-card .ccount.is-zero { opacity: .45; }
.comm-panel .post-card .ccount svg { width: 11px; height: 11px; fill: currentColor; }

/* Refresh button in-flight state. A refresh that gives no feedback is
   indistinguishable from a dead control, and with an API round trip behind it
   there is a real gap between click and result worth filling. */
.comm-panel [data-act="refresh"].is-busy {
  position: relative;
  color: transparent;
  pointer-events: none;
}
.comm-panel [data-act="refresh"].is-busy::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 13px;
  height: 13px;
  margin: -6.5px 0 0 -6.5px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  color: var(--primary);
  animation: bk-refresh-spin .62s linear infinite;
}
@keyframes bk-refresh-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .comm-panel [data-act="refresh"].is-busy::after { animation-duration: 1.6s; }
}

/* A refused read shown in place of the empty state. Same layout as
   .comm-empty so nothing shifts, but in the danger tone — "we were not allowed
   to read this" must never look like "there is nothing here". */
.communication-view .comm-empty.comm-readerr .ic {
  background: color-mix(in srgb, var(--danger) 13%, transparent);
  color: var(--danger);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 26%, transparent);
}
.communication-view .comm-empty.comm-readerr b { color: var(--danger); }
.communication-view .comm-empty.comm-readerr span {
  max-width: 48ch;
  text-align: center;
  line-height: 1.55;
  overflow-wrap: anywhere;
}
@media (max-width: 780px) {
  .comm-panel .post-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.shp-howto {
  font-size: 10.5px; color: var(--muted); line-height: 1.6;
  padding: 11px 13px; border-radius: 10px; background: var(--elev);
  margin-top: 10px;
}

/* ---- Timeline rows (returns / order history) ---- */
.tl-row {
  display: grid; grid-template-columns: 90px 18px 1fr;
  gap: 10px; align-items: start; padding: 7px 0;
}
.tl-day {
  font-size: 10.5px; font-weight: 600; color: var(--text);
  text-align: right; font-variant-numeric: tabular-nums;
}
.tl-row .tl-date { text-align: right }
.tl-row + .tl-row { border-top: 1px solid var(--border) }

/* ---- Misc controls ---- */
.orders-view .pp-card {
  border: 1px solid var(--border); border-radius: 11px;
  padding: 13px; background: var(--card);
}
.batch-remove {
  height: 28px; padding: 0 11px; border-radius: 8px;
  border: 1px solid var(--border); background: transparent;
  color: var(--danger); font-size: 10.5px; font-weight: 600;
  font-family: inherit; cursor: pointer;
}
.open-courier-btn {
  display: inline-flex; align-items: center; gap: 6px;
  height: 30px; padding: 0 12px; border-radius: 8px;
  border: 1px solid var(--primary); background: transparent;
  color: var(--primary); font-size: 11px; font-weight: 600;
  font-family: inherit; cursor: pointer;
}
.city-row { display: flex; align-items: center; gap: 8px }

/* ---- Landing page stats ---- */
.lp-stat { display: flex; flex-direction: column; gap: 3px }

.zc-brand-mark {
  display: inline-flex; align-items: center; gap: 8px;
  font-weight: 700; color: var(--text);
}

/* ---- Shared popover visibility safety net ----
   Several popovers are toggled with the `hidden` attribute. Any author rule
   that sets `display` on the same element silently defeats the UA
   `[hidden]{display:none}`, so make `hidden` authoritative for all of them. */
.pp-panel[hidden],
.flt-panel[hidden],
.acts-menu[hidden],
.exp-fmt-menu[hidden],
.flt-drop-list[hidden],
.cq-popup[hidden] { display: none !important }

/* ---- Empty / error states ---- */
.empty-state {
  display: flex; flex-direction: column; align-items: center;
  gap: 10px; padding: 40px 20px; text-align: center;
}
.empty-state .empty-rich {
  width: 54px; height: 54px; border-radius: 16px;
  display: flex; align-items: center; justify-content: center;
  background: var(--elev); color: var(--muted);
}
.empty-state .empty-msg { font-size: 12.5px; font-weight: 600; color: var(--text) }
.empty-state .empty-hint { font-size: 11px; color: var(--muted); max-width: 320px }

.panel-error .err-icon { color: var(--danger) }
.panel-error .err-msg { font-size: 12px; color: var(--label) }
.panel-error .err-retry {
  height: 30px; padding: 0 14px; border-radius: 8px;
  border: 1px solid var(--primary); background: transparent;
  color: var(--primary); font-size: 11px; font-weight: 600;
  font-family: inherit; cursor: pointer;
}
.err-body { font-size: 10.5px; color: var(--muted); font-family: ui-monospace, Menlo, Consolas, monospace; text-align: left; white-space: pre-wrap }

/* ---- Returns filter bar and KPIs ---- */
.returns-view .returns-kpis {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px;
}
.returns-view .returns-filterbar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 11px 14px; border-radius: 12px;
  /* Glass rather than the flat --card fill the rest of the section uses, so the
     one control that scopes the whole page reads as a control and not as
     another panel. The inset top edge is what makes it read as glass. */
  border: 1px solid color-mix(in srgb, var(--border) 58%, transparent);
  background: color-mix(in srgb, var(--card) 48%, transparent);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 24%, transparent),
    0 6px 18px -12px rgba(0, 0, 0, .24);
  -webkit-backdrop-filter: blur(16px) saturate(165%);
  backdrop-filter: blur(16px) saturate(165%);
  margin-bottom: 16px;
}
/* Two native date inputs at intrinsic width overflowed the bar and wrapped
   under it. A fixed basis keeps them on the bar at any column width. After the
   range upgrade only one trigger is visible, so this basis just reserves a
   stable slot for it. */
.returns-view .returns-filterbar .ret-date {
  flex: 0 1 200px;
  width: 200px;
  height: 34px;
  min-width: 0;
}
.returns-view .returns-filterbar-note { font-size: 10.5px; color: var(--muted); margin-left: auto }
@media (max-width: 1100px) {
  .returns-view .returns-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)) }
}

/* ---- Retailers: page slides offset past the sidebar, order drawer ----
   Base .page-slide is inset:0, which slid these panels over the left nav. */
.retailers-view .page-slide#retailerPage,
.retailers-view .page-slide#groupPage {
  left: var(--sidebar-w);
  background: var(--bg);
}
.sidebar.collapsed ~ .main .retailers-view .page-slide#retailerPage,
.sidebar.collapsed ~ .main .retailers-view .page-slide#groupPage { left: var(--sidebar-w-collapsed) }
@media (max-width: 768px) {
  .retailers-view .page-slide#retailerPage,
  .retailers-view .page-slide#groupPage { left: 0 }
}
.retailers-view .page-slide#retOrderPage {
  inset: 0 0 0 auto;
  width: min(720px, 96vw);
  z-index: 120;
  background: var(--card);
  border-left: 1px solid var(--border);
  box-shadow: -16px 0 44px rgba(0,0,0,.22);
  transform: translateX(100%);
  transition: transform .22s cubic-bezier(.22,.7,.3,1);
}
.retailers-view .page-slide#retOrderPage.show { transform: translateX(0) }
.retailers-view #retOrderPage .ps-topbar {
  position: sticky; top: 0; z-index: 2;
  background: var(--card); border-bottom: 1px solid var(--border);
}
.retailers-view #retOrderPage .ps-body { padding-bottom: 28px }
/* Scrim must sit above the group page slide (100) and below the drawer (120). */
.retailers-view .ret-scrim {
  position: fixed; inset: 0; z-index: 110;
  background: rgba(0,0,0,.5);
  animation: scrim-in .2s ease-out;
}
.retailers-view .ret-scrim[hidden] { display: none }
@keyframes scrim-in { from { opacity: 0 } to { opacity: 1 } }
.retailers-view .post-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px;
}
.retailers-view .post-card {
  border: 1px solid var(--border); border-radius: 12px;
  padding: 14px; background: var(--card);
}
.retailers-view .ro { cursor: pointer }

/* ---- Communication ---- */
.communication-view .comm-panel {
  display: flex; flex-direction: column;
  border: 1px solid var(--border); border-radius: 14px;
  background: var(--card); overflow: hidden;
}
.communication-view .comm-split { display: grid; grid-template-columns: 320px 1fr; height: calc(100vh - 190px) }
.communication-view .comm-list { border-right: 1px solid var(--border); overflow-y: auto }
.communication-view .comm-detail { display: flex; flex-direction: column; min-width: 0 }
.communication-view .comm-toolbar {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; border-bottom: 1px solid var(--border);
}
.communication-view .comm-body { flex: 1; display: flex; flex-direction: column; min-height: 0; width: 100% }
.communication-view .comm-panel-plain { padding: 0 }
.communication-view .comm-filters { display: flex; gap: 8px; flex-wrap: wrap }
.communication-view .comm-search {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
  min-width: 0;
  height: 32px;
  padding: 0 11px;
  border-radius: 2px;
  border: 1px solid var(--border);
  background: var(--elev);
  color: var(--muted);
}
.communication-view .comm-search .i { flex: none; width: 13px; height: 13px; }
/* The wrapper carries the chrome; the real input has to give up its own border
   and background or it paints a second box inside the first one. */
.communication-view .comm-search input {
  flex: 1;
  min-width: 0;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text);
  font-size: 11.5px;
  font-family: inherit;
  outline: none;
}
.communication-view .comm-search input::placeholder { color: var(--muted); }
.communication-view .comm-filters { display: flex; gap: 8px; flex-wrap: wrap }
.communication-view .comm-empty, .communication-view .comm-none {
  display: flex; flex-direction: column; align-items: center;
  gap: 8px; padding: 40px 20px; color: var(--muted); font-size: 11.5px;
}
.communication-view .comm-state { font-size: 10.5px; color: var(--muted) }
.communication-view .thread { display: flex; flex-direction: column; gap: 8px; padding: 14px }
.communication-view .thread-head {
  display: flex; align-items: center; gap: 9px;
  padding-bottom: 10px; border-bottom: 1px solid var(--border);
}
.communication-view .thread-body { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 8px }
.communication-view .bubble {
  max-width: 76%; padding: 9px 12px; border-radius: 12px;
  font-size: 11.5px; line-height: 1.5;
}
.communication-view .bubble.out { align-self: flex-end; background: var(--primary); color: #fff }
.communication-view .bubble.in { align-self: flex-start; background: var(--elev); color: var(--text) }
.communication-view .composer {
  display: flex; gap: 9px; align-items: flex-end;
  padding: 12px 14px; border-top: 1px solid var(--border);
}
.communication-view .composer-foot { display: flex; gap: 7px }
.communication-view .unread { font-weight: 700; color: var(--primary) }
.communication-view .when { font-size: 9.5px; color: var(--muted) }
.communication-view .copy-details-btn {
  height: 26px; padding: 0 9px; border-radius: 7px;
  border: 1px solid var(--border); background: var(--elev);
  color: var(--label); font-size: 10px; font-family: inherit; cursor: pointer;
}

/* ---- Settings: Control Panel schedule ---- */
.settings-view .ecp-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 11px;
}
.settings-view .ecp-out {
  border: 1px solid var(--border); border-radius: 12px;
  padding: 14px; background: var(--card);
  display: flex; flex-direction: column; gap: 7px;
}
/* `.ecp-line` had NO rule anywhere, so every log row rendered as an unstyled
   block inside a translucent panel - which read as an empty "cover" over the
   logs rather than a list. The panel is a terminal-style surface, not a glass
   card: it is given a solid, dark, monospace-friendly fill so the payload is
   actually readable, and the JSON is printed under its own line. */
.settings-view .ecp-line {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 9px; border-radius: 8px;
  background: color-mix(in srgb, var(--elev) 70%, transparent);
  border: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
}
.settings-view .ecp-line.has-data { align-items: flex-start; flex-wrap: wrap }
.settings-view .ecp-line-total { font-weight: 700 }
/* The payload. Wrapped and monospaced, and it is the reason the panel is now
   solid - a 46% translucent fill behind small white text was unreadable. */
.settings-view .ecp-json {
  flex: 1 0 100%; margin: 6px 0 2px;
  padding: 9px 11px; border-radius: 7px;
  background: #12141c; color: #d7dce8;
  border: 1px solid rgba(255, 255, 255, .08);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11px; line-height: 1.55;
  white-space: pre-wrap; overflow-wrap: anywhere;
  max-height: 260px; overflow: auto;
}
.settings-view .ecp-json::-webkit-scrollbar { width: 6px; height: 6px }
.settings-view .ecp-json::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .2); border-radius: 3px }
.settings-view .ecp-out {
  max-height: 60vh; overflow: auto;
}
.settings-view .ecp-top { display: flex; align-items: center; gap: 9px }
.settings-view .ecp-ic {
  width: 30px; height: 30px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  background: var(--elev); color: var(--primary);
}
.settings-view .ecp-name { font-size: 11.5px; font-weight: 700; color: var(--text) }
.settings-view .ecp-txt { font-size: 10.5px; color: var(--muted); line-height: 1.5 }
.settings-view .ecp-time { font-size: 10px; color: var(--muted); font-variant-numeric: tabular-nums }
.settings-view .ecp-status { font-size: 10.5px; font-weight: 700 }
.settings-view .ecp-status.ok { color: #22C55E }
.settings-view .ecp-status.bad { color: var(--danger) }
.settings-view .ecp-note { font-size: 10.5px; color: var(--muted); margin-top: 10px }
.settings-view .ecp-hint { font-size: 10px; color: var(--muted) }
.settings-view .ecp-btn {
  /* Was `height: 28px` on a row whose content is a 30px icon plus a label AND a
     hint. The content overflowed a fixed-height box and painted straight over the
     action buttons below the grid. min-height lets the card grow instead. */
  display: flex; align-items: center; gap: 10px;
  min-height: 52px; padding: 9px 12px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--elev);
  color: var(--label); font-size: 10.5px; font-weight: 600;
  font-family: inherit; cursor: pointer; text-align: left;
  align-self: stretch;
  transition: background var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.settings-view .ecp-btn:hover {
  background: color-mix(in srgb, var(--card) 70%, transparent);
  border-color: var(--primary); color: var(--primary);
}
.settings-view .ecp-txt { min-width: 0; flex: 1; }
/* display:block on both is load-bearing — as inline elements the label and the
   hint ran together on one line ("Get New OrdersFetch new and in-transit..."). */
.settings-view .ecp-txt strong {
  display: block; font-size: 11.5px; font-weight: 700; color: var(--text);
  line-height: 1.25;
}
.settings-view .ecp-txt small {
  display: block; font-size: 10px; color: var(--muted);
  margin-top: 3px; line-height: 1.4;
}
.settings-view .ecp-ic { flex: none; }
/* Dim the cadence controls while paused, but keep them readable so an interval
   can be chosen before switching the schedule on. */
.settings-view .ecp-sched:not(.is-on) .ecp-sched-body { opacity: .55 }
.settings-view .ecp-sched-top {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; border-radius: 12px;
  border: 1px solid var(--border); background: var(--card);
}
.settings-view .ecp-sched-body { display: flex; flex-direction: column; gap: 12px; padding-top: 12px }
.settings-view .ecp-sched-title { font-size: 11.5px; font-weight: 700; color: var(--text); min-width: 0 }
/* Same inline-collision as .ecp-txt: the title and the explanation are siblings
   and were collapsing onto one line. */
.settings-view .ecp-sched-title strong { display: block; font-size: 11.5px; line-height: 1.25; }
.settings-view .ecp-sched-title small {
  display: block; margin-top: 3px; font-size: 10px; font-weight: 400;
  color: var(--muted); line-height: 1.4;
}
.settings-view .ecp-sched-fld { display: flex; align-items: center; gap: 8px }
.settings-view .ecp-sched-fld label { font-size: 9.5px; color: var(--muted) }
.settings-view .ecp-sched-stat { display: flex; flex-direction: column; gap: 2px }
.settings-view .ecp-sched-stat b { font-size: 11.5px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums }
.settings-view .ecp-sched-stat b.ok { color: #22C55E }
.settings-view .ecp-sched-stat b.bad { color: var(--danger) }
@media (max-width: 640px) { .settings-view .ecp-sched-body { gap: 14px } }

/* ---- Settings: integrations ---- */
.int-group {
  border: 1px solid var(--border); border-radius: 12px;
  padding: 14px; background: var(--card);
  display: flex; flex-direction: column; gap: 10px;
}
.int-glyph {
  width: 34px; height: 34px; border-radius: 9px;
  display: flex; align-items: center; justify-content: center;
  background: var(--elev); color: var(--primary);
}
.int-toggle {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 11px; color: var(--label); cursor: pointer;
}
.int-ok { color: #22C55E; font-size: 10.5px; font-weight: 700 }
.int-warn { color: #F5A524; font-size: 10.5px; font-weight: 700 }
.int-none { color: var(--muted); font-size: 10.5px }
.int-disconnect {
  height: 28px; padding: 0 11px; border-radius: 8px;
  border: 1px solid var(--border); background: transparent;
  color: var(--danger); font-size: 10.5px; font-weight: 600;
  font-family: inherit; cursor: pointer; align-self: flex-start;
}
.int-consent {
  display: flex; flex-direction: column; gap: 8px;
  padding: 12px; border-radius: 10px; background: var(--elev);
}
/* Rendered empty for every integration until the consent lookup fills it in.
   With padding and a background it was a 24px grey bar sitting across the card,
   which read as a blank cover over the row. Nothing to show, nothing drawn. */
.int-consent:empty { display: none; }
.int-consent-btn {
  height: 30px; padding: 0 13px; border-radius: 8px;
  border: none; background: var(--primary); color: #fff;
  font-size: 11px; font-weight: 600; font-family: inherit;
  cursor: pointer; align-self: flex-start;
}
.int-shopify-connect { color: #95BF47; font-size: 10.5px; font-weight: 700 }

/* ---- Home hero + order rows ---- */
.home-hero .hero-text { min-width: 0 }
.home-view .home-order-row {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 4px; border-bottom: 1px solid var(--border);
  cursor: pointer;
}
.home-view .home-order-row:hover { background: var(--elev) }

/* ---- Insights cards ---- */
.insights { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 12px }
.ins-card {
  border: 1px solid var(--border); border-radius: 13px;
  padding: 15px; background: var(--card); position: relative;
}
.ins-x {
  position: absolute; top: 10px; right: 10px;
  width: 22px; height: 22px; border-radius: 6px;
  border: none; background: transparent; color: var(--muted);
  cursor: pointer; font-size: 13px; line-height: 1;
}
.ins-x:hover { background: var(--elev); color: var(--text) }
.ins-title { font-size: 12px; font-weight: 700; color: var(--text); margin-bottom: 6px; padding-right: 24px }
.ins-text { font-size: 11px; color: var(--label); line-height: 1.6 }
.ins-body { margin-top: 10px }
/* Insight action buttons are bare <button> elements; unstyled they render as
   grey OS buttons against the flat cards. */
.ins-go {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 28px;
  padding: 0 12px;
  border: 1px solid var(--primary);
  border-radius: 8px;
  background: transparent;
  color: var(--primary);
  font-size: 10.5px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  align-self: flex-start;
}
.ins-go:hover { background: var(--primary-soft) }
.ins-empty { font-size: 11.5px; color: var(--muted) }
/* Daily Average: three tiles on the first row, two on the second.
   It was a single five-across run inside a half-width panel - roughly 100px a
   tile - so the figures clipped and the row wrapped with one card stranded. */
/* A six-column track: the three count tiles take two columns each on row one,
   the two money tiles take three each on row two. That is what makes the last
   pair cover the full panel width instead of leaving a third of the row empty -
   a 3-column track simply cannot express "two cards spanning the remainder".
   Padding, min-height and type are all up from the original cramped sizing. */
.analytics-view .analytics-daily .micro-stats-grid {
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 10px;
}
.analytics-view .analytics-daily .micro-stats-grid .micro-stat {
  min-width: 0;
  padding: 16px 18px 15px;
  min-height: 108px;
  display: flex; flex-direction: column; justify-content: center; gap: 6px;
}
.analytics-view .analytics-daily .micro-stats-grid .micro-stat:nth-child(-n+3) { grid-column: span 2 }
.analytics-view .analytics-daily .micro-stats-grid .micro-stat:nth-child(n+4) { grid-column: span 3 }
.analytics-view .analytics-daily .micro-stats-grid .ms-label { font-size: 10.5px }
.analytics-view .analytics-daily .micro-stats-grid .ms-value { font-size: 23px; line-height: 1.1 }
.analytics-view .analytics-daily .micro-stats-grid .ms-trend { font-size: 10.5px }
@media (max-width: 1180px) {
  .analytics-view .analytics-daily .micro-stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) }
  .analytics-view .analytics-daily .micro-stats-grid .micro-stat:nth-child(n) { grid-column: span 1 }
}

/* The LAYOUT lives in `.micro-stats` in ui-perf.css, which loads after this
   file. ui-perf therefore wins on equal specificity - so the 3+2 column rule
   above is written with three classes (.analytics-view .analytics-daily
   .micro-stats-grid) to outrank it deliberately, rather than relying on being
   first. An earlier attempt declared the grid at single-class specificity and
   ui-perf silently flattened it, which is what left five cards across a
   half-width panel at a 128px floor.

   Type scale only below: restating the surface here would outrank ui-perf and
   flatten the glass card it draws. Labels shrink and ellipsise rather than
   wrapping to two lines, and money steps down a size so "71,522 PKR" stays on
   one line - wrapping was what doubled the card height and made the row ragged. */
.micro-stats-grid .ms-label {
  font-size: 8px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .2px;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.micro-stats-grid .ms-value {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  letter-spacing: -.3px;
  margin-top: 3px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.micro-stats-grid .ms-value.money { font-size: 11.5px; }
.micro-stats-grid .ms-trend {
  margin-top: auto;
  padding-top: 5px;
  font-size: 9px;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Funnel timing tiles sit under the pools: two cards, same glass as Daily
   Average but a fixed pair. Declared after the auto-fit rule so this wins. */
.fn-times-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  max-width: 520px;
}
.fn-times-grid .ms-trend { font-weight: 400; }
/* Wider cards, so the funnel tiles can keep the larger type. */
.fn-times-grid .ms-label { font-size: 9px; }
.fn-times-grid .ms-value { font-size: 17px; }
.fn-times-grid .ms-value.money { font-size: 15px; }
.micro-stat { display: flex; flex-direction: column; gap: 1px }
.ms-label { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--muted) }
.ms-note { font-size: 10px; color: var(--muted) }
.ms-trend { font-size: 10.5px; font-weight: 700 }
.ms-trend.up { color: #22C55E }
.ms-trend.down { color: var(--danger) }

/* ---- Segmented control (perf tabs, sales mode, city/courier view) ----
   The pill only covers the active button, so the container needs real padding
   and the buttons real size. Previously these carried no geometry at all:
   no padding, no height, no radius, which made the pill sit on top of the
   labels and the whole control collide with the panel title. */
.seg, .perf-tabs {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--elev);
}
.seg-btn, .perf-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 28px;
  padding: 0 14px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: transparent;
  box-shadow: none;
  color: var(--label);
  font-family: inherit;
  font-size: 10.5px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--dur-fast);
}
.seg-btn .i, .perf-tab .i { width: 14px; height: 14px; flex: 0 0 auto }
.seg-btn:hover, .perf-tab:hover { color: var(--primary) }
.has-glider .seg-btn, .has-glider .perf-tab { position: relative; z-index: 1 }
.has-glider .seg-btn.active, .has-glider .perf-tab.active {
  background: none; box-shadow: none; color: #fff;
}
/* Shared glider pill. attachGlider owns placement; CSS only owns looks. */
.glider-pill {
  position: absolute; top: 0; left: 0;
  background: var(--primary);
  border-radius: 999px;
  box-shadow: 0 3px 10px rgba(87,116,183,.4);
  transition: transform .5s cubic-bezier(.22,.9,.28,1.08), width .5s cubic-bezier(.22,.9,.28,1.08), height .5s cubic-bezier(.22,.9,.28,1.08), opacity .2s;
  pointer-events: none;
  z-index: 0;
}
@media (prefers-reduced-motion: reduce) { .glider-pill { transition: none } }

/* ---- Orders filter chips: sliding pill ---- */
.orders-view #statusChips { position: relative; gap: 8px }
.orders-view #statusChips .chip {
  height: 38px; padding: 0 18px; border-radius: 19px;
  font-size: 12.5px; font-weight: 600;
  background: transparent; box-shadow: none;
  border: 1px solid var(--border);
  position: relative; z-index: 1;
  transition: color var(--dur-fast), border-color var(--dur-fast);
}
.orders-view #statusChips.has-glider .chip { position: relative; z-index: 1 }
.orders-view #statusChips .chip .cnt {
  margin-left: 8px; font-size: 11px; font-weight: 700; opacity: .75;
  font-variant-numeric: tabular-nums;
}
.orders-view #statusChips .chip:hover { border-color: var(--primary) }
.orders-view #statusChips .chip.on {
  background: transparent; color: #fff; border-color: transparent; box-shadow: none;
}
.orders-view #statusChips .chip-glider {
  position: absolute; top: 0; left: 0; border-radius: 19px;
  background: var(--primary);
  box-shadow: 0 3px 10px rgba(87,116,183,.4);
  transition: transform .5s cubic-bezier(.22,.9,.28,1.08), width .5s cubic-bezier(.22,.9,.28,1.08), height .5s cubic-bezier(.22,.9,.28,1.08);
  z-index: 0; pointer-events: none;
}
@media (prefers-reduced-motion: reduce) { .orders-view #statusChips .chip-glider { transition: none } }

/* ---- Ambient orb layer ----
   Orbs live in global.css; only the fixed-coverage guard is repeated here so
   the layer still fills the viewport if global.css is reordered. */
.bg-orbs { position: fixed; inset: 0; }
.orb { border-radius: 50%; pointer-events: none; position: absolute }

/* ---- Glass UI ----
   Deliberately NOT applied to .card / .panel / .odp / .drawer here. Those are
   pre-existing selectors with their own solid backgrounds from global.css and
   the restored sections.css; overriding them with color-mix transparency made
   every panel on every route translucent and destroyed text contrast. This file
   only adds rules for classes that had none.

   Glass stays scoped to the KPI and table surfaces, which is what it was
   originally limited to. */
.card.kpi,
.table-wrap {
  background: color-mix(in srgb, var(--card) 72%, transparent);
  backdrop-filter: blur(18px) saturate(160%);
  -webkit-backdrop-filter: blur(18px) saturate(160%);
  border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
}
/* Analytics KPI cards run at full glass like the panels around them. The old
   72% left them noticeably more opaque than everything else on the page, so
   the KPI row read as a solid band sitting on top of the glassy dashboard. */
.analytics-view .card.kpi {
  background: color-mix(in srgb, var(--card) 46%, transparent);
  backdrop-filter: blur(22px) saturate(180%);
  -webkit-backdrop-filter: blur(22px) saturate(180%);
  border: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
}
@media (prefers-reduced-transparency: reduce) {
  .card.kpi, .table-wrap,
  .analytics-view .card.kpi { backdrop-filter: none; -webkit-backdrop-filter: none; }
}

/* ---- Shared utility bits used by generated markup ---- */
.muted { color: var(--muted) }
.txt { font-size: 11.5px; color: var(--label) }
.txt.strong { color: var(--text); font-weight: 600 }
.txt.meta { font-size: 10px; color: var(--muted) }
.txt.mono { font-family: ui-monospace, Menlo, Consolas, monospace }
.txt.upd { color: var(--primary); font-weight: 600 }
.txt.req { color: var(--danger) }
.txt.ok { color: #22C55E }
.txt.ready { color: #22C55E; font-weight: 600 }
.txt.kind { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--muted) }
.txt.tone { font-weight: 600 }
.json {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 10px; color: var(--label);
  white-space: pre-wrap; word-break: break-word;
  max-height: 320px; overflow: auto;
}
/* ---- Tooltip type ----
   The plate is a dark surface in BOTH themes (--tt-bg), so every run of text
   inside it has to be light. The label colour was --muted, a mid grey picked for
   the light dashboard; on the dark plate it read as near-black, which is what
   made the funnel's hover menu look black-on-black. Everything inside a tooltip
   now tracks the --tt-* scale instead of the page's. */
.tt-k { color: var(--tt-muted); font-size: 10.5px }
.perf-tooltip,
.chart-tooltip {
  color: var(--tt-fg);
}
.perf-tooltip .tt-date { color: var(--tt-fg) }
.perf-tooltip .tt-row b { color: var(--tt-fg); font-weight: 700 }
.perf-tooltip .tt-k { color: var(--tt-muted) }
.perf-tooltip .tt-val { color: var(--tt-fg) }
.bubble .when, .tl-date, .when { font-size: 9.5px; color: var(--muted) }
.mini { font-size: 10px; color: var(--muted) }
.card-foot { margin-top: auto; padding-top: 10px }
.charges { display: flex; flex-direction: column; gap: 5px }
.qempty, .ins-empty { font-size: 11.5px; color: var(--muted); padding: 22px; text-align: center }
.cid { font-size: 10px; color: var(--muted); font-family: ui-monospace, Menlo, Consolas, monospace }
.from { font-size: 10px; color: var(--muted) }
.cdot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; flex: 0 0 auto }
.cbar { height: 5px; border-radius: 3px; background: var(--border); overflow: hidden }
.cbar > i { display: block; height: 100%; background: var(--primary) }
.cpick, .rad { accent-color: var(--primary) }
.qsel { height: 30px; padding: 0 9px; border-radius: 8px; border: 1px solid var(--border); background: var(--elev); color: var(--text); font-size: 11px; font-family: inherit }
.sbox { padding: 12px; border-radius: 10px; background: var(--elev); border: 1px solid var(--border) }
.steps { display: flex; flex-direction: column; gap: 10px }
.stp { display: flex; gap: 10px; align-items: flex-start }
.chart-pt { transition: opacity var(--dur-fast) }
.chart-pt:hover { opacity: .8 }
.bkstep { display: flex; gap: 10px }
.bkstep-n {
  width: 24px; height: 24px; border-radius: 50%; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  background: var(--primary-soft); color: var(--primary);
  font-size: 10px; font-weight: 700;
}
.cx-row td { font-size: 11.5px }
.cls { display: inline-flex; gap: 6px; align-items: center }
.crumbs { display: flex; align-items: center; gap: 6px; font-size: 10.5px; color: var(--muted) }
.toolbar-group { display: flex; align-items: center; gap: 8px; flex-wrap: wrap }
.toolbar-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap }

.crumbs .nav-text { color: var(--label) }


/* ---- Analytics KPI row: label to the top, format toggle to the corner ----
   The label carried a 10px top margin and the card is a flex column, so the
   name floated toward the middle instead of sitting under the top edge. The
   format toggle lived inside the label, which pushed it away from the corner and
   made the name read as indented. The toggle is now absolutely positioned in the
   card's top-right, so the label can be a plain left-aligned caption again. */
.analytics-view .kpi { position: relative; }
.analytics-view .kpi .lbl {
  display: block;
  margin-top: 0;
  padding-right: 26px;      /* room for the corner toggle, text never under it */
  text-align: left;
}
.analytics-view .kpi .kpi-toggle {
  position: absolute; top: 9px; right: 9px;
  margin-left: 0;
  vertical-align: top;
}

/* One flat six-column split. An earlier revision gave the first three cards
   `grid-column: span 2`, which is 9 tracks in 6 columns and wrapped the row in
   half; a later one weighted the columns 1.18fr vs 1fr. Both were attempts to
   make the headline figures carry more weight, and both were reverted: every
   card is the same size now. */
.analytics-view .kpis { grid-template-columns: repeat(6, minmax(0, 1fr)); }
@media (max-width: 1240px) {
  .analytics-view .kpis { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  .analytics-view .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
