/* Lifted from the <style> block of mocks/admin/dashboard.html.
   Left behind on purpose: the :root token block, .ti, .img-ph, .content and
   .form-grid - all four either fight admin.css or already live there. The purchase
   series on the bar chart is gone with purchasing, so the legend carries one entry. */

.page-actions{display:flex;gap:8px;align-items:center}
.date-filter{display:flex;gap:4px;background:var(--card);border:1px solid var(--border);border-radius:10px;padding:3px}
.df-btn{padding:5px 12px;border:none;border-radius:6px;cursor:pointer;font-size:12px;font-family:inherit;font-weight:600;color:var(--muted);background:transparent}
.df-btn.on{background:var(--primary);color:#fff}

/* On the same 20px axis every other screen stands on. The whole board was running
   0 → 1360 - flush against the sidebar on one side and under the scrollbar on the
   other - while orders, invoices and customers all sit 20 → 1340. The page header
   carries its own padding from admin.css, so only what comes after it needed saying. */
.quick-acts{display:flex;gap:8px;margin:0 20px 14px;flex-wrap:wrap}
.qa{display:flex;align-items:center;gap:6px;padding:7px 14px;border-radius:10px;border:none;cursor:pointer;font-size:12px;font-weight:700;font-family:inherit;transition:.12s;text-decoration:none}
.qa.blue{background:var(--primary);color:#fff}
.qa.blue:hover{background:var(--primary-d)}
.qa.orange{background:var(--warning);color:#fff}
.qa.ghost{background:var(--card);color:var(--text2);border:1px solid var(--border)}
.qa.ghost:hover{border-color:var(--primary);color:var(--primary)}

.dash-content{display:flex;flex-direction:column;gap:14px;margin:0 20px}

/* One regular grid for all eight. It was 4-then-3, which put 333px cards above 445px
   cards and read as a mistake rather than two rows. */
.kpi-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
.kpi{background:var(--card);border-radius:12px;padding:15px 16px;border:1px solid var(--border);
     display:flex;flex-direction:column;gap:6px;transition:.15s;
     text-decoration:none;color:inherit;line-height:1.45}
.kpi:hover{box-shadow:var(--elev-2);border-color:var(--primary-l)}
.kpi-top{display:flex;justify-content:space-between;align-items:center;gap:8px}
.kpi .ks-label{font-size:12px;color:var(--muted)}
.kpi .ks-value{font-size:22px;font-weight:800;letter-spacing:-.01em}
.kpi .ks-sub{font-size:11px;color:var(--muted)}
/* The two figures that are warnings by nature carry it in the number, not in a border
   drawn round the whole card - a red frame shouts louder than what is inside it. */
.kpi .ks-v-warn{color:var(--warning)}
.kpi .ks-v-bad{color:var(--danger)}
.kpi .ks-icon.ks-warn{color:var(--warning)}
.kpi .ks-icon.ks-bad{color:var(--danger)}

/* The slot the mock keeps for a trend, finally carrying one. */
.kpi-trend{font-size:11px;font-weight:700;padding:3px 8px;border-radius:20px;
           display:inline-flex;align-items:center;gap:3px;white-space:nowrap}
.kpi-trend i{font-size:12px}
.kpi-trend.up{background:var(--success-l);color:var(--success)}
.kpi-trend.down{background:var(--danger-l);color:var(--danger)}
.kpi-trend.neu{background:var(--bg);color:var(--muted)}

.charts-row{display:grid;grid-template-columns:1.8fr 1fr;gap:14px}
.chart-card{background:var(--card);border-radius:12px;border:1px solid var(--border);overflow:hidden}
.chart-head{padding:14px 16px 0;display:flex;justify-content:space-between;align-items:center}
.chart-legend{display:flex;gap:10px;flex-wrap:wrap}
.legend-item{display:flex;align-items:center;gap:5px;font-size:11px;color:var(--text2)}
.legend-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}
/* ── the plot ──
   Bars used to stand on nothing: no scale, no baseline, and the value printed over
   every column. A bar with no axis behind it only says "taller than its neighbour". */
.plot{position:relative;padding:14px 16px 6px}
.plot-grid{position:absolute;inset:14px 16px 28px;display:flex;flex-direction:column;
           justify-content:space-between;pointer-events:none}
.grid-line{border-top:1px dashed var(--border);position:relative;height:0}
.grid-line:last-child{border-top-style:solid}
.grid-line span{position:absolute;inset-inline-start:0;top:-8px;font-size:10px;
                color:var(--muted);background:var(--card);padding-inline-end:6px}

.bar-chart-wrap{position:relative;height:190px;display:flex;align-items:flex-end;gap:2px;
                padding-inline-start:46px}
.bar-col{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;
         height:100%;min-width:0}
.bar-col .bar-val{font-size:10px;color:var(--muted);white-space:nowrap;margin-bottom:3px}
.bar-col .bar-body{width:min(70%,26px);border-radius:5px 5px 0 0;background:var(--primary);
                   min-height:2px;transform-origin:bottom;
                   animation:bar-rise .5s cubic-bezier(.22,1,.36,1) both;
                   animation-delay:calc(var(--i,0) * 22ms)}
/* A day with no sales still gets a mark on the baseline, or the eye reads a gap in the
   series as missing data rather than a quiet day. */
.bar-col.is-nil .bar-body{background:var(--border);min-height:2px}
.bar-col:hover .bar-body{background:var(--primary-d)}

.plot-axis{display:flex;gap:2px;padding-inline-start:46px;margin-top:6px}
.axis-tick{flex:1;text-align:center;font-size:10px;color:var(--muted);
           white-space:nowrap;min-width:0;overflow:hidden}

@keyframes bar-rise{from{transform:scaleY(0)}to{transform:scaleY(1)}}

.donut-wrap{padding:16px;display:flex;flex-direction:column;align-items:center;gap:12px}
.donut-ring{position:relative;width:140px;height:140px;flex-shrink:0}
.donut-ring svg{transform:rotate(-90deg)}
.donut-hole{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);text-align:center}
.donut-legend{display:flex;flex-direction:column;gap:7px;width:100%}
.dl-item{display:flex;align-items:center;gap:8px;font-size:12px}
.dl-dot{width:10px;height:10px;border-radius:6px;flex-shrink:0}
.dl-name{flex:1;color:var(--text2)}
.dl-pct{font-weight:700;color:var(--text)}
.dl-amt{font-size:11px;color:var(--muted)}

.tables-row{display:grid;grid-template-columns:1.6fr 1fr;gap:14px}
.table-card{background:var(--card);border-radius:12px;border:1px solid var(--border);overflow:hidden;display:flex;flex-direction:column}
.table-head{padding:12px 16px;display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid var(--border);flex-shrink:0}
.table-head h4{font-size:14px;font-weight:700}
.table-head a{font-size:12px;color:var(--primary);cursor:pointer;text-decoration:none}
.table-head a:hover{text-decoration:underline}
.inv-num{color:var(--primary);font-weight:700;font-size:12px}
.amount-pos{color:var(--success);font-weight:700}
.amount-neu{color:var(--text);font-weight:700}

.alerts-card{background:var(--card);border-radius:12px;border:1px solid var(--border);overflow:hidden;display:flex;flex-direction:column}
.alert-item{display:flex;align-items:flex-start;gap:10px;padding:10px 14px;border-bottom:1px solid var(--border);text-decoration:none;color:inherit;transition:.12s}
.alert-item:last-child{border-bottom:none}
.alert-item:hover{background:var(--bg)}
.alert-icon{width:32px;height:32px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0;margin-top:1px}
.ai-red{color:var(--danger)}
.ai-warn{color:var(--warning)}
.ai-blue{color:var(--primary)}
.ai-green{color:var(--success)}
.alert-body{flex:1;min-width:0}
.alert-count{font-size:14px;font-weight:800;white-space:nowrap;flex-shrink:0}

.recv-item{display:flex;align-items:center;gap:10px;padding:9px 14px;border-bottom:1px solid var(--border)}
.recv-item:last-child{border-bottom:none}
.recv-avatar{width:32px;height:32px;border-radius:50%;background:var(--primary);color:#fff;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:700;flex-shrink:0}
.recv-days.ok{color:var(--success)}
.recv-days.warn{color:var(--warning)}
.recv-days.late{color:var(--danger)}
.recv-amount{font-size:13px;font-weight:800}
.recv-amount.late{color:var(--danger)}
.recv-amount.warn{color:var(--warning)}

.rank-1{color:var(--warning);font-weight:800}
.rank-2{color:#94A3B8;font-weight:800}
.rank-3{color:#CD7F32;font-weight:800}

/* ── movement ──
   All of it CSS on markup that is already there: no library, no second script file.
   The cards arrive in sequence rather than all at once, the bars grow off the
   baseline, and the donut draws itself round.

   `animation-delay` off a --i custom property set in the markup, so the stagger is the
   element's own position and nothing has to count in script. */
.kpi{animation:card-in .45s cubic-bezier(.22,1,.36,1) both}
.kpi-grid .kpi:nth-child(1){animation-delay:0ms}
.kpi-grid .kpi:nth-child(2){animation-delay:45ms}
.kpi-grid .kpi:nth-child(3){animation-delay:90ms}
.kpi-grid .kpi:nth-child(4){animation-delay:135ms}
.kpi-grid .kpi:nth-child(5){animation-delay:180ms}
.kpi-grid .kpi:nth-child(6){animation-delay:225ms}
.kpi-grid .kpi:nth-child(7){animation-delay:270ms}
.kpi-grid .kpi:nth-child(8){animation-delay:315ms}

.chart-card,.table-card,.alerts-card{animation:card-in .45s cubic-bezier(.22,1,.36,1) both;
                                     animation-delay:120ms}

@keyframes card-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

/* The ring draws round from its start rather than appearing whole. The dash pattern is
   the slice itself, so the sweep is the same length the slice will end at. */
.donut-ring svg circle{animation:donut-draw .8s cubic-bezier(.4,0,.2,1) both}
@keyframes donut-draw{from{stroke-dasharray:0 339}}

.alert-item,.recv-item{animation:row-in .35s ease both}
@keyframes row-in{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* Anyone who asked the system for less movement gets the end state and nothing else -
   the same courtesy the skeleton sweep and the bulk bar already extend. */
@media (prefers-reduced-motion:reduce){
  .kpi,.chart-card,.table-card,.alerts-card,.alert-item,.recv-item,
  .bar-col .bar-body,.donut-ring svg circle{animation:none}
}

/* ── the three cuts ──
   Horizontal bars, because the labels are words: brand and governorate names set
   sideways under a vertical column are unreadable, and in Arabic doubly so. */
/* Not stretched: the funnel carries six rows and a brand list may carry two, and an
   equal box makes a hole in the short one rather than filling it - the same call the
   offer grid settled on. */
.mini-charts{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;align-items:start}
.hbars,.funnel{padding:14px 16px 16px;display:flex;flex-direction:column;gap:11px}

.hbar{display:grid;grid-template-columns:1fr auto;grid-template-areas:"name val" "track track";
      gap:4px 8px;align-items:center;font-size:12px}
.hb-name{grid-area:name;color:var(--text2);font-weight:700;overflow:hidden;
         text-overflow:ellipsis;white-space:nowrap}
.hb-val{grid-area:val;font-size:11px;color:var(--muted);white-space:nowrap}
.hb-track{grid-area:track;height:8px;border-radius:20px;background:var(--bg);overflow:hidden}
.hb-fill{height:100%;border-radius:20px;background:var(--primary);transform-origin:right;
         animation:hbar-grow .55s cubic-bezier(.22,1,.36,1) both;
         animation-delay:calc(var(--i,0) * 70ms)}
/* Grown from the right, because that is where an RTL row starts reading. */
@keyframes hbar-grow{from{transform:scaleX(0)}to{transform:scaleX(1)}}

.fn-step{display:grid;grid-template-columns:88px 1fr auto;gap:10px;align-items:center;
         text-decoration:none;color:inherit;font-size:12px;border-radius:8px;padding:3px 4px}
.fn-step:hover{background:var(--bg)}
.fn-name{color:var(--text2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* --primary-ll is #EEF3FF, which against a white card is barely a shape - the stage
   with 48 orders in it was reading as an empty row. The fill is solid and the count
   sits outside it, so a stage holding two is a short bar rather than a faint one. */
.fn-bar{height:22px;border-radius:6px;background:var(--primary);
        transform-origin:right;animation:hbar-grow .55s cubic-bezier(.22,1,.36,1) both;
        animation-delay:calc(var(--i,0) * 70ms);min-width:6px}
.fn-count{font-weight:800;font-size:13px;min-width:26px;text-align:center}
/* An empty stage still gets its row: the gap in the cycle is the information. */
.fn-step.is-nil .fn-bar{background:var(--slate-l)}
.fn-step.is-nil .fn-count{color:var(--muted);font-weight:600}

@media (prefers-reduced-motion:reduce){
  .hb-fill,.fn-bar{animation:none}
}
