/* ============================================================
   VOLBOO — Statistics layer
   Loads LAST, after css/styles.css and css/dashboard.css, and is
   linked from stats.php only.

   The page holds almost nothing the design system has not already
   named. The four headline figures are the shared .stat-card, the
   outcomes panel is the shared .card, and every control in the
   toolbar is a .btn — the same pair transactions.php uses. What
   actually lives in this file is only what the system has no name
   for yet: the date-range picker, the status-mix bar, and the
   tints that tell one card from the next.

   Two things this file deliberately does NOT redefine:
     · body.figures-hidden — the star mask the eye toggles is
       dashboard.css §6, which this page also links. Duplicating it
       here is what produced blurred stars.
     · dark mode — every colour below comes from a styles.css token,
       so [data-theme="dark"] is already handled. The only dark
       blocks here are the --tint triplets, which are literals by
       design and so have to be restated, and the native date
       input's calendar glyph.
   ============================================================ */

/* ------------------------------------------------------------
   0. Card tints

   .stat-card derives its whole skin — icon chip, pill hairline,
   corner wash, hover border — from one "r,g,b" triplet (styles.css
   § Stat cards). Naming them here keeps the triplets out of the
   markup, and lets dark lift each hue rather than reuse a colour
   that was mixed for white.
   ------------------------------------------------------------ */
.stats-page .tint-accent{--tint:14,167,116}
.stats-page .tint-purple{--tint:109,95,209}
.stats-page .tint-blue  {--tint:37,99,235}
.stats-page .tint-orange{--tint:192,120,7}
.stats-page .tint-red   {--tint:229,72,77}
.stats-page .tint-slate,
.stats-page .stats-outcomes{--tint:100,116,139}

[data-theme="dark"] .stats-page .tint-accent{--tint:52,211,153}
[data-theme="dark"] .stats-page .tint-purple{--tint:191,179,245}
[data-theme="dark"] .stats-page .tint-blue  {--tint:96,165,250}
[data-theme="dark"] .stats-page .tint-orange{--tint:240,194,96}
[data-theme="dark"] .stats-page .tint-red   {--tint:249,112,102}
[data-theme="dark"] .stats-page .tint-slate,
[data-theme="dark"] .stats-page .stats-outcomes{--tint:147,160,150}

/* ------------------------------------------------------------
   1. Toolbar — the range reads left, the controls trail right

   Same shape as .tbl-toolbar on the list pages: one quiet line of
   context on the left, pill controls pushed to the right edge.
   The line carries the applied range AND the period the deltas are
   measured against, which is why no card has to repeat "vs
   previous period" seven times.
   ------------------------------------------------------------ */
.stats-toolbar{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin-bottom:22px;
}
/* baseline, not centre: on a phone the line wraps to two rows and a
   centred glyph would float between them. */
.stats-range-note{
  display:inline-flex;align-items:baseline;gap:8px;min-width:0;
  font-size:.75rem;color:var(--text3);letter-spacing:-.005em;
}
.stats-range-note i{color:var(--text4);font-size:.6875rem;flex-shrink:0}
.stats-range-note b{font-weight:600;color:var(--text2)}
.stats-range-note span{min-width:0;overflow:hidden;text-overflow:ellipsis}

.stats-toolbar-actions{
  display:flex;align-items:center;gap:8px;margin-left:auto;
}
/* Icon-only member of the .btn family: square, no label gutter */
.stats-eye{width:32px;padding:0;flex-shrink:0}
.stats-eye i{font-size:.75rem}

/* ------------------------------------------------------------
   2. Date range picker

   The trigger is an ordinary .btn-secondary; only the panel is new.
   Presets are pill chips on the accent, the calendar selection is
   the accent, and the two footer buttons are .btn-outline and
   .btn-accent — the same pair every dialog on the site ends with.
   ------------------------------------------------------------ */
.drp{position:relative}
.drp-trigger{max-width:100%;min-width:0}
.drp-trigger .drp-label{
  min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.drp-trigger .drp-caret{
  font-size:.5625rem;color:var(--text3);flex-shrink:0;
  transition:transform .18s cubic-bezier(.4,0,.2,1);
}
.drp.is-open .drp-trigger{
  border-color:var(--accent-border);background:var(--accent-light);color:var(--text);
}
.drp.is-open .drp-trigger .drp-caret{transform:rotate(180deg)}

.drp-panel{
  position:absolute;top:calc(100% + 8px);right:0;z-index:40;
  width:320px;max-width:calc(100vw - 32px);
  padding:14px;
  background:var(--bg-card);
  border:1px solid var(--border);border-radius:var(--radius-xl);
  box-shadow:var(--shadow-lg);
  opacity:0;visibility:hidden;transform:translateY(-6px);
  transition:opacity .18s cubic-bezier(.4,0,.2,1),
             transform .18s cubic-bezier(.4,0,.2,1),
             visibility .18s;
}
.drp.is-open .drp-panel{opacity:1;visibility:visible;transform:none}

/* ---- presets ------------------------------------------------ */
.drp-presets{
  display:grid;grid-template-columns:1fr 1fr;gap:6px;
  padding-bottom:12px;margin-bottom:12px;
  border-bottom:1px solid var(--border);
}
.drp-preset{
  display:inline-flex;align-items:center;justify-content:center;
  height:30px;padding:0 10px;border-radius:999px;
  border:1px solid var(--border);background:transparent;
  color:var(--text2);
  font-size:.75rem;font-weight:500;letter-spacing:-.01em;
  transition:var(--transition);
}
.drp-preset:hover{background:var(--bg-hover);border-color:var(--border-strong);color:var(--text)}
.drp-preset.is-active{
  background:var(--accent-light);border-color:var(--accent-border);
  color:var(--accent);font-weight:600;
}
.drp-preset[data-preset="custom"]{grid-column:1 / -1}

/* ---- calendar ----------------------------------------------- */
.drp-cal[hidden]{display:none}

.drp-cal-nav{
  display:flex;align-items:center;justify-content:space-between;gap:8px;
  margin-bottom:10px;
}
.drp-cal-nav span{
  font-size:.8125rem;font-weight:600;letter-spacing:-.015em;color:var(--text);
}
.drp-nav-btn{
  display:inline-flex;align-items:center;justify-content:center;
  width:28px;height:28px;flex-shrink:0;
  border-radius:var(--radius-sm);border:1px solid var(--border);
  background:transparent;color:var(--text3);font-size:.6875rem;
  transition:var(--transition);
}
.drp-nav-btn:hover{background:var(--bg-hover);border-color:var(--border-strong);color:var(--text)}

.drp-cal-dow{display:grid;grid-template-columns:repeat(7,1fr);margin-bottom:4px}
.drp-cal-dow span{
  text-align:center;
  font-size:.625rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  color:var(--text4);
}

.drp-cal-grid{display:grid;grid-template-columns:repeat(7,1fr)}

/* A day is a pill; the two ends of a range keep their round cap and
   the days between square off, so the run reads as one bar rather
   than as seven separate chips. */
.drp-day{
  height:32px;border:none;background:transparent;
  color:var(--text2);font-size:.75rem;font-weight:500;
  border-radius:999px;
  transition:background-color .15s ease,color .15s ease;
}
.drp-day--pad{visibility:hidden;cursor:default}
.drp-day:disabled{color:var(--text4);opacity:.4;cursor:not-allowed}
.drp-day:not(:disabled):not(.range-start):not(.range-end):hover{
  background:var(--bg-hover);color:var(--text);
}
.drp-day.is-today{font-weight:700;color:var(--text)}
.drp-day.in-range{background:var(--accent-light);color:var(--text);border-radius:0}
.drp-day.range-start,
.drp-day.range-end{background:var(--accent);color:#fff;font-weight:600}
.drp-day.range-start{border-radius:999px 0 0 999px}
.drp-day.range-end{border-radius:0 999px 999px 0}
.drp-day.range-start.range-end{border-radius:999px}

/* ---- typed dates -------------------------------------------- */
.drp-inputs{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:12px}
.drp-inputs label{
  display:flex;flex-direction:column;gap:5px;min-width:0;
  font-size:.6875rem;font-weight:600;color:var(--text3);
}
.drp-inputs input{
  width:100%;height:32px;padding:0 12px;
  border:1px solid var(--border-strong);border-radius:999px;
  background:var(--bg-input);color:var(--text);
  font-size:.75rem;transition:var(--transition);
}
.drp-inputs input:focus{
  outline:none;border-color:var(--accent);background:var(--bg);
  box-shadow:0 0 0 3px var(--accent-light);
}
/* The native calendar glyph is painted black and stays black on a
   dark field, so it has to be inverted by hand. */
[data-theme="dark"] .drp-inputs input::-webkit-calendar-picker-indicator{
  filter:invert(1);opacity:.55;
}

.drp-actions{
  display:flex;justify-content:flex-end;gap:8px;
  padding-top:12px;margin-top:12px;
  border-top:1px solid var(--border);
}

/* ------------------------------------------------------------
   3. Headline figures

   Four shared .stat-cards, so .stats-grid's own breakpoints
   (4 → 2 → 2) carry the whole responsive story for free. The only
   additions are the delta pill's colour and the direction glyph.
   ------------------------------------------------------------ */

/* The card's count. Money uses .num instead, because .num is what
   the star mask covers — an eye labelled "hide amounts" should not
   also blank out how many transactions were made. */
.stats-page .stat-count{font-variant-numeric:tabular-nums}

/* The pill stays lifted — card surface, tint hairline — exactly as
   styles.css draws it. Only the ink carries the direction, so it
   never competes with the filled icon chip above it. */
.stats-page .stat-pill{gap:5px;font-variant-numeric:tabular-nums}
.stats-page .stat-pill i{font-size:.5625rem}
.stat-pill--good{color:var(--accent)}
.stat-pill--bad{color:var(--red)}
.stat-pill--flat{color:var(--text4)}

/* A hidden figure clips its star row to the width of the text
   underneath, so a masked "0" would come out as a single star and
   read as damage. Same floor the dashboard uses. */
body.figures-hidden .stats-page .stat-value .num{min-width:4.5ch}

/* ------------------------------------------------------------
   4. Outcomes panel

   Successful / pending / failed are stated once, at the top, with
   their deltas, and the bar underneath is the same three numbers
   as a proportion. Collections and withdrawals then break that
   total down, one hairline apart.
   ------------------------------------------------------------ */
/* The pair sits in .dashboard-grid, the dashboard's own bottom row:
   two equal halves that stretch to the taller of them, and that
   collapse to one column at 1100px. It also means both panels
   inherit the staggered rise styles.css already gives
   .dashboard-grid > .card, so nothing is animated by hand here. */
.stats-outcomes > .card{display:flex;flex-direction:column}
.stats-outcomes .card-header{align-items:flex-start}

/* Capped, so the three figures stay a group rather than drifting to
   the far corners once the panel goes full width under 1100px. */
.mix-figures{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:16px;max-width:600px;
}
/* Both panels centre their body in whatever height the taller of the
   pair sets, so the row reads as one band rather than two boxes with
   their content stranded at the top. */
.mix-summary{display:flex;flex-direction:column;justify-content:center;flex:1}
.mix-fig{display:flex;flex-direction:column;gap:7px;min-width:0}
.mix-fig-label{
  display:inline-flex;align-items:center;gap:7px;
  font-size:.75rem;color:var(--text3);letter-spacing:-.005em;
}
.mix-fig-row{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
.mix-fig-value{
  font-size:1.5rem;font-weight:600;letter-spacing:-.035em;
  color:var(--text);line-height:1.15;
}

.mix-summary .mix-bar{margin:16px 0 10px}
/* align-self, not inline-block: .mix-summary is a flex column, which
   blockifies an inline-block child and stretches it. Without this the
   loading shimmer lays a full-width grey bar across the panel. */
.mix-caption{
  align-self:flex-start;
  font-size:.6875rem;font-weight:500;color:var(--text4);
}
.mix-caption b{font-weight:600;color:var(--text2);font-variant-numeric:tabular-nums}

.mix-rows{display:flex;flex-direction:column;justify-content:center;flex:1}
.mix-row + .mix-row{
  margin-top:18px;padding-top:18px;border-top:1px solid var(--border);
}

.mix-row-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.mix-row-label{font-size:.8125rem;font-weight:600;letter-spacing:-.015em;color:var(--text)}
.mix-row-total{font-size:.75rem;color:var(--text3);font-variant-numeric:tabular-nums;white-space:nowrap}

.mix-bar{
  display:flex;width:100%;height:8px;
  border-radius:999px;overflow:hidden;
  background:var(--bg-input);
  margin:11px 0;
}
.mix-seg{height:100%;transition:width .45s cubic-bezier(.16,1,.3,1)}
.mix-seg--ok     {background:var(--accent)}
.mix-seg--pending{background:var(--orange)}
.mix-seg--failed {background:var(--red)}

.mix-legend{
  display:flex;gap:8px 20px;flex-wrap:wrap;
  font-size:.75rem;color:var(--text3);
}
.mix-legend span{display:inline-flex;align-items:center;gap:7px}
.mix-legend b{font-weight:600;color:var(--text);font-variant-numeric:tabular-nums}

.mix-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
.mix-dot--ok     {background:var(--accent)}
.mix-dot--pending{background:var(--orange)}
.mix-dot--failed {background:var(--red)}

/* A period with nothing in it gets a flat track and says so,
   rather than showing an empty bar that reads as a failure. */
.mix-row.is-empty .mix-bar,
.mix-summary.is-empty .mix-bar{opacity:.5}

/* ------------------------------------------------------------
   5. Loading

   Every figure becomes a shimmer block of its own width while the
   range is in flight — the same treatment, and the same timing, as
   the skeleton rows on the list pages.
   ------------------------------------------------------------ */
@keyframes s-shimmer{0%{background-position:100% 50%}100%{background-position:0 50%}}

.stats-page.is-loading .stat-value,
.stats-page.is-loading .mix-fig-value,
.stats-page.is-loading .stat-pill,
.stats-page.is-loading .mix-row-total,
.stats-page.is-loading .mix-caption{
  border-radius:var(--radius-xs);border-color:transparent!important;
  background:linear-gradient(90deg,var(--bg-input) 25%,var(--bg-hover) 37%,var(--bg-input) 63%);
  background-size:400% 100%;
  animation:s-shimmer 1.4s ease infinite;
  color:transparent!important;
}
.stats-page.is-loading .stat-value .cur,
.stats-page.is-loading .stat-value .num,
.stats-page.is-loading .stat-count,
.stats-page.is-loading .stat-pill i,
.stats-page.is-loading .mix-caption b{color:transparent!important}

/* Floors, so a short value still reads as a bar being loaded */
.stats-page.is-loading .stat-value{min-width:96px;min-height:24px}
.stats-page.is-loading .mix-fig-value{min-width:64px;min-height:24px}
.stats-page.is-loading .stat-pill{min-width:62px}
.stats-page.is-loading .mix-row-total{min-width:92px}
.stats-page.is-loading .mix-caption{min-width:130px;min-height:14px}
.stats-page.is-loading .mix-bar{opacity:.5}
.stats-page.is-loading .mix-legend{opacity:.45}

@media(prefers-reduced-motion:reduce){
  .stats-page.is-loading .stat-value,
  .stats-page.is-loading .mix-fig-value,
  .stats-page.is-loading .stat-pill,
  .stats-page.is-loading .mix-row-total,
  .stats-page.is-loading .mix-caption{animation:none}
}

/* ------------------------------------------------------------
   6. Responsive

   .stats-grid and .stat-card are already handled by styles.css at
   every breakpoint, so only this page's own parts appear here.
   ------------------------------------------------------------ */
@media(max-width:768px){
  .mix-figures{gap:14px}
  .mix-legend{gap:6px 16px}
}

@media(max-width:640px){
  /* The range line drops to its own row and the controls take the
     full width under it, with the picker taking the slack. */
  .stats-range-note{flex:1 0 100%}
  .stats-toolbar-actions{margin-left:0;width:100%}
  .drp{flex:1 1 auto;min-width:0}
  .drp-trigger{width:100%;justify-content:space-between}
  .drp-panel{left:0;right:0;width:auto;max-width:none}

  /* Three figures side by side stop being readable well before the
     cards do — each gets its own line instead. */
  .mix-figures{grid-template-columns:1fr;gap:12px}
  .mix-fig{
    flex-direction:row;align-items:baseline;justify-content:space-between;
    gap:10px;flex-wrap:wrap;
  }
  .mix-fig-value{font-size:1.125rem}
}

@media(max-width:480px){
  .drp-presets{grid-template-columns:1fr 1fr;gap:5px}
  .drp-preset{height:28px;font-size:.71875rem}
  .drp-inputs{grid-template-columns:1fr}
}
