/* ============================================================================
   dashboard.css — styles for the redesigned admin dashboard (#tab-dashboard).

   SCOPE: every selector is namespaced under `.nvx`. Nothing here can affect
   any other tab, and nothing outside can reach in. Safe to delete this file
   and its <link> tag to remove the redesign entirely.

   Paired with: public/js/dashboard.js
   ============================================================================ */

/* ============================================================
   NOVA DASHBOARD PREVIEW — standalone, sample data, not wired.
   Every rule below is scoped under .nvx so it cannot collide
   with admin.css / crm-theme.css when this is dropped into the
   CRM later. No global element selectors. No !important.
   ============================================================ */

.nvx {
  /* --- palette: kept from the source comp --- */
  --nvx-page:        #ecedef;
  --nvx-shell:       #f2f4f6;
  --nvx-card:        #ffffff;
  --nvx-ink:         #191c1e;
  --nvx-ink-dim:     #5c5d67;
  --nvx-ink-faint:   #8b8d96;
  --nvx-line:        #e1e3e5;
  --nvx-line-soft:   #edeef0;
  --nvx-blue:        #0062ff;
  --nvx-blue-dark:   #0052d6;
  --nvx-blue-wash:   #e6efff;
  --nvx-dark:        #111216;
  --nvx-cyan:        #37bfd4;
  --nvx-amber:       #e8a13a;
  --nvx-red:         #e0574d;
  --nvx-green:       #1a9d5f;

  --nvx-r-card: 20px;
  --nvx-r-tile: 16px;
  --nvx-r-pill: 999px;
  --nvx-shadow: 0 4px 20px -2px rgba(17, 18, 22, .05);
  --nvx-shadow-lift: 0 18px 38px -10px rgba(17, 18, 22, .16);
  --nvx-ease: cubic-bezier(.22, 1, .36, 1);

  /* One font for the whole CRM. Deliberately `inherit` rather than
     var(--crm-font): admin.css sets `body.crm-app { font-family: Poppins … !important }`,
     which overrides that variable, so reading the variable gave the dashboard
     Urbanist while every other tab rendered Poppins. Inheriting means the
     dashboard always matches the app, whatever the app is set to. */
  --nvx-font: inherit;

  font-family: inherit;
  color: var(--nvx-ink);
  background: transparent;
  -webkit-font-smoothing: antialiased;
  font-size: 14px;
  line-height: 1.45;
  box-sizing: border-box;
}

/* crm-theme.css forces its own font-family onto button, input, select and
   textarea, globally and with !important. The rule below is the only !important
   in this file and exists purely to win that specific fight inside the
   dashboard, so the controls inherit the same face as everything around them. */
.nvx button, .nvx select, .nvx input { font-family: inherit !important; }
.nvx *, .nvx *::before, .nvx *::after { box-sizing: border-box; }
.nvx h1, .nvx h2, .nvx h3, .nvx p { margin: 0; }
.nvx button { font: inherit; color: inherit; cursor: pointer; }
.nvx :focus-visible { outline: 2px solid var(--nvx-blue); outline-offset: 2px; border-radius: 8px; }

.nvx-shell {
  max-width: 1460px;
  margin: 0 auto;
  background: var(--nvx-shell);
  border-radius: 26px;
  padding: 18px 18px 22px;
}

/* ---------------- title row ---------------- */
.nvx-titlebar { display: flex; align-items: flex-end; justify-content: space-between; gap: 14px; flex-wrap: wrap; margin-bottom: 13px; }
.nvx-titlebar h1 { font-size: 22px; font-weight: 800; letter-spacing: -.5px; }
.nvx-crumb { font-size: 12.5px; color: var(--nvx-ink-dim); margin-top: 3px; display: flex; align-items: center; gap: 8px; }
.nvx-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.nvx-btn { display: inline-flex; align-items: center; gap: 7px; border: 0; background: var(--nvx-card); padding: 9px 16px; border-radius: var(--nvx-r-pill); font-size: 13px; font-weight: 600; box-shadow: 0 1px 3px rgba(17,18,22,.05); transition: transform .3s var(--nvx-ease), box-shadow .3s var(--nvx-ease); }
.nvx-btn:hover { transform: translateY(-2px); box-shadow: 0 8px 16px -6px rgba(17,18,22,.18); }
.nvx-btn svg { width: 15px; height: 15px; color: var(--nvx-ink-dim); }
.nvx-btn select { border: 0; background: transparent; font: inherit; font-weight: 600; color: inherit; cursor: pointer; padding: 0; }

/* ---------------- grid ---------------- */
.nvx-grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 13px; }
.nvx-card { background: var(--nvx-card); border-radius: var(--nvx-r-card); padding: 17px 18px; box-shadow: var(--nvx-shadow); transition: transform .45s var(--nvx-ease), box-shadow .45s var(--nvx-ease); }
.nvx-card-dark { background: var(--nvx-dark); color: #fff; }
.nvx-lift:hover { transform: translateY(-4px); box-shadow: var(--nvx-shadow-lift); }
.nvx-c7 { grid-column: span 7; } .nvx-c5 { grid-column: span 5; }
.nvx-c8 { grid-column: span 8; } .nvx-c4 { grid-column: span 4; }

.nvx-cardhead { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 13px; }
.nvx-eyebrow { font-size: 10.5px; font-weight: 700; letter-spacing: .7px; text-transform: uppercase; color: var(--nvx-ink-faint); }
.nvx-cardhead h2 { font-size: 15.5px; font-weight: 700; letter-spacing: -.2px; margin-top: 3px; }

/* figures */
.nvx-figure { font-size: 31px; font-weight: 800; letter-spacing: -1.1px; line-height: 1; font-variant-numeric: tabular-nums; }
.nvx-figure-sm { font-size: 22px; font-weight: 800; letter-spacing: -.6px; line-height: 1; font-variant-numeric: tabular-nums; }
.nvx-delta { display: inline-flex; align-items: center; gap: 4px; font-size: 12.5px; font-weight: 700; }
.nvx-up { color: var(--nvx-green); } .nvx-down { color: var(--nvx-red); }
.nvx-delta svg { width: 13px; height: 13px; }
.nvx-sub { font-size: 12px; color: var(--nvx-ink-dim); }

/* legend */
.nvx-legend { display: flex; flex-wrap: wrap; gap: 14px; }
.nvx-legend span { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 600; color: var(--nvx-ink-dim); }
.nvx-dot { width: 9px; height: 9px; border-radius: 3px; flex: none; }

/* charts */
.nvx-chart { position: relative; }
.nvx-chart-vol { height: 180px; }
.nvx-fill { display: flex; flex-direction: column; }
.nvx-fill .nvx-chart-vol { flex: 1 1 auto; height: auto; min-height: 200px; }
.nvx-fill { justify-content: flex-start; }
.nvx-fill .nvx-list { flex: 1 1 auto; }
.nvx-donut-wrap { position: relative; height: 152px; display: grid; place-items: center; }
.nvx-donut-center { position: absolute; text-align: center; pointer-events: none; }
.nvx-donut-center strong { display: block; font-size: 24px; font-weight: 800; letter-spacing: -1px; line-height: 1; font-variant-numeric: tabular-nums; }
.nvx-donut-center span { font-size: 11px; font-weight: 600; color: var(--nvx-ink-dim); }

/* tiles */
.nvx-side { grid-column: span 5; display: grid; grid-template-rows: auto 1fr; gap: 13px; }
.nvx-tilerow { display: grid; grid-template-columns: 1fr 1fr; gap: 13px; }
.nvx-tile { display: flex; flex-direction: column; gap: 10px; padding: 15px 16px; border-radius: var(--nvx-r-tile); }
.nvx-tile-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.nvx-seg { display: flex; gap: 2px; height: 6px; }
.nvx-seg i { display: block; height: 100%; border-radius: 2px; }
.nvx-brk { display: flex; flex-direction: column; gap: 4px; }
.nvx-brk-row { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 7px; }
.nvx-brk-row span { font-size: 11.5px; font-weight: 600; color: var(--nvx-ink-dim); }
.nvx-brk-row strong { font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; }
.nvx-foot { font-size: 11px; color: var(--nvx-ink-dim); border-top: 1px solid var(--nvx-line-soft); padding-top: 8px; margin-top: auto; }
.nvx-foot b { color: var(--nvx-ink); font-weight: 700; }
.nvx-badge { width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; flex: none; background: var(--nvx-shell); color: var(--nvx-blue); }
.nvx-badge svg { width: 15px; height: 15px; }

/* dispatch (dark) card */
.nvx-dispatch { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 16px 18px; }
.nvx-dispatch .nvx-figure { color: #fff; }
.nvx-dispatch-sub { font-size: 12px; color: rgba(255,255,255,.68); margin-top: 6px; }
.nvx-cta { border: 0; background: var(--nvx-blue); color: #fff; border-radius: var(--nvx-r-pill); padding: 11px 20px; font-size: 13px; font-weight: 700; display: inline-flex; align-items: center; gap: 7px; transition: transform .3s var(--nvx-ease), background .25s; }
.nvx-cta:hover { transform: translateY(-2px); background: var(--nvx-blue-dark); }
.nvx-cta svg { width: 14px; height: 14px; }
.nvx-split { display: flex; gap: 22px; margin-top: 14px; }
.nvx-split div span { display: block; font-size: 10.5px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase; color: rgba(255,255,255,.5); }
.nvx-split div strong { font-size: 16px; font-weight: 700; font-variant-numeric: tabular-nums; }

/* lists */
.nvx-list { display: flex; flex-direction: column; gap: 4px; }
.nvx-row { display: grid; grid-template-columns: 22px 1fr auto; align-items: center; gap: 10px; padding: 8px 8px; border-radius: 14px; transition: background .25s var(--nvx-ease); }
.nvx-row:hover { background: var(--nvx-shell); }
.nvx-rank { font-size: 11.5px; font-weight: 700; color: var(--nvx-ink-faint); font-variant-numeric: tabular-nums; }
.nvx-row-name { font-size: 13.5px; font-weight: 600; }
.nvx-row-meta { font-size: 11.5px; color: var(--nvx-ink-dim); margin-top: 2px; }
.nvx-row-val { font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums; text-align: right; }
.nvx-bar { height: 5px; border-radius: 99px; background: var(--nvx-line-soft); overflow: hidden; margin-top: 7px; }
.nvx-bar i { display: block; height: 100%; border-radius: 99px; background: var(--nvx-blue); transform-origin: left; }
.nvx-lane { display: flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 600; }
.nvx-lane svg { width: 13px; height: 13px; color: var(--nvx-ink-faint); flex: none; }
.nvx-substats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--nvx-line-soft); border-radius: 14px; overflow: hidden; margin-top: 13px; }
.nvx-substats div { background: var(--nvx-card); padding: 10px 12px; }
.nvx-substats span { display: block; font-size: 10.5px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase; color: var(--nvx-ink-faint); }
.nvx-substats strong { display: block; font-size: 14.5px; font-weight: 700; letter-spacing: -.3px; margin-top: 4px; font-variant-numeric: tabular-nums; }
.nvx-substats em { font-style: normal; font-size: 11px; color: var(--nvx-ink-dim); }

/* source rows */
.nvx-src { display: grid; grid-template-columns: 1fr 60px auto; align-items: center; gap: 10px; padding: 7px 8px; border-radius: 12px; transition: background .25s var(--nvx-ease); }
.nvx-src:hover { background: var(--nvx-shell); }
.nvx-src-name { font-size: 12.5px; font-weight: 600; }
.nvx-src-val { font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; }

/* activity log */
.nvx-log { display: grid; grid-template-columns: 29px 1fr auto; align-items: center; gap: 11px; padding: 8px 8px; border-radius: 14px; transition: background .25s var(--nvx-ease); }
.nvx-log:hover { background: var(--nvx-shell); }
.nvx-log-av { width: 29px; height: 29px; border-radius: 50%; display: grid; place-items: center; font-size: 11.5px; font-weight: 700; background: var(--nvx-shell); color: var(--nvx-ink); }
.nvx-log-title { font-size: 13.5px; font-weight: 600; }
.nvx-log-sub { font-size: 11.5px; color: var(--nvx-ink-dim); margin-top: 2px; }
.nvx-tag { font-size: 10px; font-weight: 700; padding: 3.5px 9px; border-radius: var(--nvx-r-pill); background: var(--nvx-ink-dim); color: #fff; white-space: nowrap; letter-spacing: .2px; }
.nvx-tag-blue { background: var(--nvx-blue); color: #fff; }
.nvx-tag-warn { background: var(--nvx-red); color: #fff; }
.nvx-legend-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2px 14px; margin-top: 12px; }

.nvx-c3 { grid-column: span 3; }
.nvx-chart-trend { height: 158px; }

@media (max-width: 1120px) {
.nvx-c3 { grid-column: span 12; } }
@media (max-width: 900px) {
.nvx-substats { grid-template-columns: repeat(3, 1fr) !important; } }
@media (max-width: 720px) {
.nvx-substats { grid-template-columns: 1fr 1fr !important; } }

.nvx-hero-split { margin-top: 7px; display: flex; flex-wrap: wrap; gap: 4px 14px; }
.nvx-hero-split b { color: var(--nvx-ink); font-weight: 700; font-variant-numeric: tabular-nums; }
.nvx-hero-split span { white-space: nowrap; }

/* needs-attention rows */
.nvx-attn { display: flex; flex-direction: column; gap: 6px; flex: 1 1 auto; }
.nvx-attn-row { display: grid; grid-template-columns: 30px 1fr auto; align-items: center; gap: 11px; padding: 9px 8px; border-radius: 12px; transition: background .25s var(--nvx-ease); }
.nvx-attn-row:hover { background: var(--nvx-shell); }
.nvx-attn-ico { width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; background: var(--nvx-shell); color: var(--nvx-ink-dim); }
.nvx-attn-ico svg { width: 15px; height: 15px; }
.nvx-attn-ico.is-warn { background: #fdf1de; color: #a9700f; }
.nvx-attn-ico.is-crit { background: #fbe6e4; color: #b3392f; }
.nvx-attn-title { font-size: 13px; font-weight: 600; }
.nvx-attn-sub { font-size: 11.5px; color: var(--nvx-ink-dim); margin-top: 1px; }
.nvx-attn-n { font-size: 17px; font-weight: 800; font-variant-numeric: tabular-nums; letter-spacing: -.4px; }
.nvx-attn-n.is-warn { color: #a9700f; }
.nvx-attn-n.is-crit { color: #b3392f; }
.nvx-attn-clear { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--nvx-ink-dim); padding: 14px 8px; }

/* single-column logs now that the card is half width */
.nvx-logs-single { display: flex; flex-direction: column; gap: 2px; }

.nvx-empty { font-size: 12px; color: var(--nvx-ink-faint); padding: 14px 8px; text-align: center; }

.nvx-logs-pager { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--nvx-line-soft); }
.nvx-pg-count { font-size: 11.5px; font-weight: 600; color: var(--nvx-ink-dim); font-variant-numeric: tabular-nums; }
.nvx-pg-btns { display: flex; gap: 6px; }
.nvx-pg { width: 28px; height: 28px; padding: 0; display: grid; place-items: center; border: 1px solid var(--nvx-line); background: var(--nvx-card); border-radius: 8px; color: var(--nvx-ink-dim); transition: background .2s var(--nvx-ease), color .2s, border-color .2s; }
.nvx-pg svg { width: 14px; height: 14px; }
.nvx-pg:hover:not(:disabled) { background: var(--nvx-shell); color: var(--nvx-ink); border-color: #cfd4db; }
.nvx-pg:disabled { opacity: .38; cursor: default; }
.nvx-loading .nvx-logs-pager { display: none; }

/* ---------------- loading skeleton ----------------
   Shown from page load until the first render. The dashboard used to sit at
   $0 / 0 while the server aggregate was in flight, which read as "you have no
   data" rather than "still loading". Shapes mirror the real content so nothing
   jumps when the numbers arrive. */
@keyframes nvxShimmer { from { background-position: -460px 0; } to { background-position: 460px 0; } }

.nvx-sk {
  background: linear-gradient(90deg, #edf0f4 25%, #e2e7ee 37%, #edf0f4 63%);
  background-size: 920px 100%;
  animation: nvxShimmer 1.5s linear infinite;
  border-radius: 7px;
  display: block;
}
.nvx-sk-row { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 12px; padding: 10px 8px; }
.nvx-sk-line { height: 10px; }
.nvx-sk-sm { height: 8px; margin-top: 7px; opacity: .75; }
.nvx-sk-pill { height: 20px; width: 62px; border-radius: 999px; }
.nvx-sk-av { width: 29px; height: 29px; border-radius: 50%; }
.nvx-sk-logrow { display: grid; grid-template-columns: 29px 1fr auto; align-items: center; gap: 11px; padding: 9px 8px; }

/* headline figures become bars of roughly the right size */
.nvx-loading .nvx-figure,
.nvx-loading .nvx-figure-sm,
.nvx-loading .nvx-substats strong,
.nvx-loading .nvx-split strong,
.nvx-loading .nvx-donut-center strong,
.nvx-loading .nvx-donut-center span,
.nvx-loading .nvx-sub,
.nvx-loading .nvx-foot,
.nvx-loading .nvx-dispatch-sub,
.nvx-loading .nvx-hero-split {
  color: transparent !important;
  background: linear-gradient(90deg, #edf0f4 25%, #e2e7ee 37%, #edf0f4 63%);
  background-size: 920px 100%;
  animation: nvxShimmer 1.5s linear infinite;
  border-radius: 7px;
  border-color: transparent !important;
}
.nvx-loading .nvx-figure { width: 190px; height: 32px; }
.nvx-loading .nvx-figure-sm { width: 74px; height: 24px; }
.nvx-loading .nvx-substats strong { width: 76%; height: 15px; }
.nvx-loading .nvx-split strong { width: 54px; height: 16px; display: inline-block; }
.nvx-loading .nvx-sub,
.nvx-loading .nvx-dispatch-sub { width: 62%; height: 11px; }
.nvx-loading .nvx-hero-split { width: 46%; height: 11px; }
.nvx-loading .nvx-foot { width: 55%; height: 10px; border-top-color: transparent !important; }
.nvx-loading .nvx-donut-center strong { width: 54px; height: 26px; margin: 0 auto 5px; }
.nvx-loading .nvx-donut-center span { width: 42px; height: 9px; display: block; margin: 0 auto; }

/* the delta chip and peak label have nothing to show yet */
.nvx-loading .nvx-delta,
.nvx-loading #nvxTrendPeak { visibility: hidden !important; }

/* charts: a soft block over the canvas area */
.nvx-loading .nvx-chart { position: relative; }
.nvx-loading .nvx-chart::after,
.nvx-loading .nvx-donut-wrap::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, #edf0f4 25%, #e2e7ee 37%, #edf0f4 63%);
  background-size: 920px 100%;
  animation: nvxShimmer 1.5s linear infinite;
  border-radius: 12px;
}
.nvx-loading .nvx-donut-wrap { position: relative; }
.nvx-loading .nvx-donut-wrap::after { border-radius: 50%; width: 152px; height: 152px; inset: auto; }
.nvx-loading .nvx-donut-center { z-index: 2; }

/* the little segment bars on the lead / quote tiles */
.nvx-loading .nvx-seg i { background: #e6eaf0 !important; animation: none !important; }

/* the dark dispatch card shimmers in its own key so it doesn't flash white */
.nvx-loading .nvx-card-dark .nvx-figure,
.nvx-loading .nvx-card-dark .nvx-split strong,
.nvx-loading .nvx-card-dark .nvx-dispatch-sub {
  background: linear-gradient(90deg, rgba(255,255,255,.10) 25%, rgba(255,255,255,.20) 37%, rgba(255,255,255,.10) 63%);
  background-size: 920px 100%;
}

@media (prefers-reduced-motion: reduce) {
  .nvx-sk,
  .nvx-loading .nvx-chart::after,
  .nvx-loading .nvx-donut-wrap::after,
  .nvx-loading .nvx-figure,
  .nvx-loading .nvx-figure-sm { animation: none !important; }
}

/* ---------------- motion ---------------- */
@media (prefers-reduced-motion: no-preference) {
  @keyframes nvxRise { from { opacity: 0; transform: translateY(26px); } to { opacity: 1; transform: translateY(0); } }
  @keyframes nvxGrow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
  .nvx-anim { opacity: 0; animation: nvxRise .85s var(--nvx-ease) forwards; }
  .nvx-d1 { animation-delay: .05s; } .nvx-d2 { animation-delay: .13s; }
  .nvx-d3 { animation-delay: .21s; } .nvx-d4 { animation-delay: .29s; }
  .nvx-d5 { animation-delay: .37s; } .nvx-d6 { animation-delay: .45s; }
  .nvx-bar i { animation: nvxGrow 1.1s var(--nvx-ease) .5s both; }
}
@media (prefers-reduced-motion: reduce) {
  .nvx-anim { opacity: 1; }
  .nvx *, .nvx *::before { transition: none !important; }
}

/* ---------------- responsive ---------------- */
@media (max-width: 1120px) {
  .nvx-c7, .nvx-c8, .nvx-c5, .nvx-c4, .nvx-side { grid-column: span 12; }
}
@media (max-width: 720px) {
  .nvx { padding: 12px; }
  .nvx-shell { border-radius: 26px; padding: 18px 14px 22px; }
  .nvx-card { padding: 18px; border-radius: 24px; }
  .nvx-tilerow { grid-template-columns: 1fr; }
  .nvx-figure { font-size: 33px; }
  .nvx-dispatch { flex-direction: column; align-items: flex-start; }
}

/* ---------------- touch targets (2026-08-31) ----------------
   Measured on a 390px viewport: the period picker came out 121x20 and the log
   pager arrows 28x34 — both under the ~44px a thumb needs. Sizes grow only on
   coarse pointers and narrow screens, so the desktop layout is unchanged. */
@media (pointer: coarse), (max-width: 720px) {
  /* Padding on the wrapper grew the pill but not the tap target — the <select>
     is the child that actually opens, and a tap on the wrapper's padding does
     nothing. So the padding moves onto the select and the select fills the
     pill. */
  .nvx .nvx-btn { padding: 0; min-height: 44px; }
  .nvx .nvx-btn select {
    min-height: 44px;
    padding: 0 16px;
    font-size: 14px;
    align-self: stretch;
    flex: 1 1 auto;
  }
  .nvx .nvx-pg { width: 40px; height: 40px; }
  .nvx .nvx-pg svg { width: 16px; height: 16px; }
  .nvx .nvx-pg-btns { gap: 10px; }
}
