/* Dashboard.

   Self-contained, like every other report page here (see the note at the top of SaleRegister.css):
   every selector below is scoped to .dash-* and nothing on this page is shared with another.

   Two things are deliberately NOT reinvented, because the landing page should not look like a
   different application from the one behind it:

     - the toolbar is the registers' own .top-btns-container.toolbar-stacked, so the title, the
       period dropdown and Refresh sit at exactly the heights they do on Sale Register;
     - a card is .master-table-container's recipe -- white, 1px #e5e9f0, 12px radius, the same soft
       shadow -- so the page reads as the same surface as a report table.

   What is different is the layout underneath. The registers pin one table with position:fixed and
   hand-computed top offsets; a dashboard is a dozen boxes whose heights change with the data, so
   here there is ONE fixed scroll region (.dash-scroll) holding a CSS grid. A card can be added,
   removed or reordered without any other card's offsets having to be worked out again.

   The 7rem top matches .master-table-container exactly: the shared toolbar starts at 3rem (48px)
   and a single row of it is 57px, ending at 105px, and 7rem (112px) leaves the same 7px gap the
   Account Master table leaves. */


/* ---- scroll region --------------------------------------------------------------------------- */

.dash-scroll {
    position: fixed; /* pin to viewport */
    top: 7rem;
    bottom: 1rem;
    left: 14.5rem; /* matches .top-btns-container so the toolbar and the cards line up */
    right: 1rem;
    overflow-y: auto;
    overflow-x: hidden;
    /* Transparent, unlike .master-table-container: the cards inside are the white surfaces and the
       page's own #eef0f3 (MainLayout2.razor.css) is the gutter between them. */
    padding: 0 4px 4px 0;
    font-size: 12px;
    color: #26303d;
    transition: left 0.2s ease;
    scrollbar-width: thin;
    scrollbar-color: #99c2ff #f1f1f1;
}

/* Sidebar collapsed to icon-only (4.5rem, see SidebarLayout.razor.css) -- reclaim the freed width
   instead of leaving it empty, the same as every table page does. */
.dash-scroll.sidebar-collapsed {
    left: 5.5rem;
}

/* The period the whole page is reading, printed next to the dropdown so the figures below can
   never be read against the wrong dates. */
.dash-period-range {
    font-size: 12px;
    font-weight: 600;
    color: #6b7280;
    white-space: nowrap;
}


/* ---- grid ------------------------------------------------------------------------------------

   One .dash-row per band. Each names its own column shape rather than inheriting a single grid,
   because the bands genuinely differ: four equal KPI tiles, then a wide chart beside a narrow one,
   then two halves. minmax(0, Nfr) rather than plain Nfr on every one of them -- a grid track's
   default min-width is auto, and an SVG or a long party name inside would otherwise push its
   column past its share and off the right edge. */

.dash-row {
    display: grid;
    gap: 14px;
    margin-bottom: 14px;
}

.dash-row.wide-narrow {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
}

.dash-row.halves {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.dash-row:last-child {
    margin-bottom: 0;
}


/* ---- card ------------------------------------------------------------------------------------ */

.dash-card {
    background: #ffffff;
    border: 1px solid #e5e9f0;
    border-radius: 12px;
    box-shadow: 0 6px 18px rgba(16, 24, 40, 0.06);
    padding: 14px 16px 16px;
    min-width: 0; /* see the minmax note above: without this a card refuses to shrink below its content */
    display: flex;
    flex-direction: column;
}

.dash-card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 12px;
}

.dash-card-title {
    font-size: 13px;
    font-weight: 700;
    color: #1f2937;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Every card says which window it is reading. The page mixes three of them on purpose -- the KPIs
   and the breakdowns follow the period dropdown, the trends are always the last twelve months, and
   the outstanding figures are as on today -- and a card without this line would be guesswork. */
.dash-card-scope {
    font-size: 9px;
    font-weight: 700;
    color: #6b7280;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
}


/* ---- KPI cards --------------------------------------------------------------------------------

   Four across in one row, on the same white surface as every other card here. What they borrow is
   the shape: a label, the figure, one supporting line, and an area chart bled to the card's left,
   right and bottom edges rather than sat inside a plot with axes around it.

   overflow:hidden is what clips that chart to the rounded corners -- the svg is a plain rectangle
   and knows nothing about them. The radius is 16 rather than .dash-card's 12 because a chart that
   runs into the corner shows the curve off, and 12 looked clipped rather than rounded.

   --accent comes in from the markup and is the one colour a card carries: the line and the fill
   under it. It is the same value the page uses for that figure everywhere else, so a Sale sparkline
   matches a Sale tag in the table below and a Sale bar in the chart beside it. */

.dash-row.kpis {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

.dash-kpi {
    position: relative;
    overflow: hidden;
    min-height: 168px;

    /* Overrides .dash-card's padded flex column; the chart is placed against the edges instead. */
    display: block;
    padding: 14px 16px 0;
    border-radius: 16px;
}

.dash-kpi-label {
    display: block;
    font-size: 12px;
    font-weight: 600;
    color: #6b7280;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The odometer sets its own size through Odometer.razor's FontSize parameter and inherits this
   colour. nowrap because the rolling digits are absolutely positioned inside their own ribbons and
   a wrap would leave the currency mark stranded on a line of its own. */
.dash-kpi-value {
    display: flex;
    align-items: center;

    /* The figure itself never wraps -- the rolling digits are absolutely positioned inside their own
       ribbons and a break would strand the currency mark on a line of its own -- but the chip beside
       it may drop under a long one rather than being clipped by the card's overflow:hidden. */
    flex-wrap: wrap;
    gap: 2px 8px;
    margin-top: 4px;
    color: #111827;
    white-space: nowrap;
}

.dash-kpi-note {
    display: block;
    margin-top: 3px;
    font-size: 11px;
    color: #9aa3af;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Which window the chart underneath covers. The figure above it follows the period dropdown and this
   never does, and a card that did not say so would be guesswork -- so it is stated, quietly, in the
   one corner of the chart nothing else uses.

   It sits on the chart, and how dark the fill is there depends entirely on the data -- an outstanding
   balance that never approaches zero fills that corner solid. Hence the translucent backing: grey on
   an unknown ground is not a contrast anyone can promise, and this makes it one that holds whatever
   the series does. */
.dash-kpi-scope {
    position: absolute;
    left: 12px;
    bottom: 8px;
    padding: 2px 5px;
    border-radius: 4px;
    background: rgba(255, 255, 255, 0.74);
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: #6b7280;
    pointer-events: none;
}

.dash-kpi-chart {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 92px;
}

.dash-kpi-chart svg {
    display: block;
    width: 100%;
    height: 100%;
}


/* ---- the chart's entrance ----------------------------------------------------------------------

   The chart draws itself left to right, from the first month to the last, finishing on the same clock
   as the odometer beside it. That direction is the one the chart is already read in -- oldest month
   at x 0, newest at the right edge -- so all four sweep the same way whichever way their figure is
   counting; the up/down distinction belongs to the digits, not to time.

   A clip-path wipe rather than a transform: the line and the fill under it arrive at their final
   position immediately and are simply uncovered, so nothing is squashed or stretched on the way in.
   And not a stroke-dashoffset draw either -- the line carries vector-effect="non-scaling-stroke", so
   its dash lengths resolve in screen space, and a path length measured there is not something to
   rely on across browsers. An inset() is exact everywhere.

   The animation runs on insertion, and the markup re-keys the element when the figures change, which
   is what makes it replay on a refresh rather than only on first paint. */

.dash-kpi-chart svg {
    animation: dash-spark-draw 900ms cubic-bezier(0.33, 1, 0.68, 1) both;
}

@keyframes dash-spark-draw {
    from {
        clip-path: inset(0 100% 0 0);
    }

    to {
        clip-path: inset(0 0 0 0);
    }
}

/* Nothing here carries meaning that the still chart does not, so it is safe to simply not move. */
@media (prefers-reduced-motion: reduce) {
    .dash-kpi-chart svg {
        animation: none;
    }
}

.dash-kpi-blank {
    position: absolute;
    left: 16px;
    bottom: 24px;
    font-size: 11px;
    color: #b6bcc7;
}


/* ---- delta chip -------------------------------------------------------------------------------

   No tinted capsule: beside a figure this size the arrow and the colour carry it on their own, and
   a pill next to the number is one shape too many. */

.dash-delta {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 12px;
    font-weight: 700;
    white-space: nowrap;
}

/* Up is not automatically good -- a rise in Payable is not the same news as a rise in Sales -- so
   the card picks .good / .bad itself and the arrow only says which way the number moved. */
.dash-delta.good {
    color: #157347;
}

.dash-delta.bad {
    color: #b02a37;
}

.dash-delta.flat {
    color: #9aa3af;
}


/* ---- charts ----------------------------------------------------------------------------------

   Every chart is inline SVG drawn in the razor: no chart library, so nothing new is downloaded and
   the marks use the same palette as the rest of the page. Each one has a fixed viewBox and scales
   with its card, which is why the font sizes inside an SVG below look large next to the CSS ones
   here -- they are user units, not pixels.

   Coordinates are whole numbers everywhere on purpose. Blazor WebAssembly formats a double with the
   browser's culture, so a computed x would arrive as "12,5" wherever the decimal mark is a comma
   and the attribute would be silently dropped. Integers carry no separator in any culture. */

/* max-width, not just width:100%. An SVG with a viewBox scales its type along with everything else,
   so a 340-unit chart handed a 900px card renders its axis labels at two and a half times the size
   they were drawn at — on a wide monitor, or whenever the row collapses to one column, the smallest
   chart on the page ended up with the largest text on it. Capping the width caps the scale, and the
   chart centres in whatever is left. */
.dash-chart {
    display: block;
    width: 100%;
    max-width: 900px;
    height: auto;
    margin: 0 auto;
}

/* The chart drawn on a 340-unit canvas rather than a 760-unit one. */
.dash-chart.narrow {
    max-width: 430px;
}


.dash-chart text {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

.dash-grid-line {
    stroke: #eef0f3;
    stroke-width: 1;
}

.dash-axis-label {
    fill: #9aa3af;
    font-size: 11px;
}

/* A mark is not a link -- the pointer stays default -- but it does answer on hover, through a
   <title> child. That is the whole tooltip: no script, and it works on touch too. */
.dash-mark {
    transition: opacity .12s ease;
}

.dash-mark:hover {
    opacity: 0.75;
}

.dash-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 14px;
    margin-top: 10px;
    font-size: 11px;
    color: #4b5563;
}

.dash-legend span {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    white-space: nowrap;
}

.dash-legend-dot {
    width: 9px;
    height: 9px;
    border-radius: 3px;
    flex: 0 0 auto;
}


/* ---- donut ----------------------------------------------------------------------------------- */

.dash-donut-wrap {
    display: flex;
    flex-direction: column;
    align-items: center;
    flex: 1;
    justify-content: center;
}

.dash-donut {
    width: 100%;
    max-width: 220px;
    height: auto;
}

.dash-donut-total {
    fill: #111827;
    font-size: 19px;
    font-weight: 700;
    text-anchor: middle;
}

.dash-donut-caption {
    fill: #9aa3af;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-anchor: middle;
}


/* ---- ranked bars ------------------------------------------------------------------------------

   Top parties and top products are HTML rows rather than SVG: the label is the long part and it has
   to wrap, ellipsise and stay selectable, none of which an SVG <text> does well. */

.dash-rank {
    display: flex;
    flex-direction: column;
    gap: 9px;
}

.dash-rank-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 2px 10px;
    align-items: baseline;
}

.dash-rank-name {
    font-size: 12px;
    color: #26303d;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dash-rank-value {
    font-size: 12px;
    font-weight: 700;
    color: #1f2937;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum";
}

.dash-rank-track {
    grid-column: 1 / -1;
    height: 7px;
    border-radius: 4px;
    background: #eef0f3;
    overflow: hidden;
}

.dash-rank-fill {
    height: 100%;
    border-radius: 4px;
    background: var(--accent, #2563eb);
}


/* ---- recent documents -------------------------------------------------------------------------

   Not .master-content-table1: that sheet brings sticky columns, 300px cells and a horizontal
   scroller, all of which are wrong inside a card. Five columns that fit are simpler than a shared
   table with four of its features switched back off. */

.dash-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 12px;
}

.dash-table th {
    text-align: left;
    padding: 0 10px 7px;
    border-bottom: 1px solid #e5e9f0;
    color: #6b7280;
    font-size: 9px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
}

.dash-table td {
    padding: 7px 10px;
    border-bottom: 1px solid #f2f4f7;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dash-table tr:last-child td {
    border-bottom: none;
}

.dash-table tbody tr:hover td {
    background: #f7f9fc;
}

.dash-table .dash-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum";
}

/* The party is the column worth the leftover width; everything else is a date, a tag or a figure. */
.dash-table .dash-party {
    width: 100%;
    max-width: 0; /* with table-layout:auto this is what makes the ellipsis above take effect */
}

/* A document's register, as a tag rather than a word in a sentence -- the tint is set inline from
   the same palette the charts use, so a Sale row is the same blue as the Sale bars. */
.dash-tag {
    display: inline-block;
    padding: 2px 7px;
    border-radius: 5px;
    font-size: 10px;
    font-weight: 700;
    white-space: nowrap;
    background: var(--tag-bg, #eef0f3);
    color: var(--tag-fg, #4b5563);
}


/* ---- empty and loading states ---------------------------------------------------------------- */

.dash-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 120px;
    padding: 20px;
    color: #9aa3af;
    font-size: 12px;
    text-align: center;
}

/* A skeleton rather than a spinner: the cards are already laid out, so the page does not jump when
   the figures arrive -- only the grey blocks turn into content. */
.dash-skeleton {
    border-radius: 6px;
    background: linear-gradient(90deg, #eef0f3 25%, #f6f8fa 37%, #eef0f3 63%);
    background-size: 400% 100%;
    animation: dash-shimmer 1.3s ease-in-out infinite;
}

.dash-skeleton.line {
    height: 12px;
    width: 45%;
    margin-bottom: 9px;
}

.dash-skeleton.value {
    height: 30px;
    width: 70%;
    margin-bottom: 9px;
}

.dash-skeleton.block {
    height: 190px;
}

@keyframes dash-shimmer {
    0% {
        background-position: 100% 50%;
    }

    100% {
        background-position: 0 50%;
    }
}


/* ======================================== Responsive ==========================================

   Same deal the register pages strike (see the note at the bottom of SaleAccount.css): below 700px
   the sidebar goes off-canvas and the shared toolbar drops out of position:fixed into normal flow,
   so the scroll region has to follow it rather than stay pinned at a top offset that no longer
   holds. .content1's own overflow-y:auto scrolls the whole page instead.

   The two multi-column bands collapse earlier, at 1100px: a grouped-column chart squeezed into a
   third of a tablet is unreadable long before the sidebar goes away. */

@media (max-width: 1100px) {
    .dash-row.wide-narrow,
    .dash-row.halves {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Four figures across stop fitting before the rest of the page does: below this a card is narrower
   than the largest amount it has to print, and the figure would be clipped. Four, two, one -- never
   three with one stranded underneath. */
@media (max-width: 1250px) {
    .dash-row.kpis {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 620px) {
    .dash-row.kpis {
        grid-template-columns: minmax(0, 1fr);
    }
}


@media (max-width: 700px) {
    .dash-scroll,
    .dash-scroll.sidebar-collapsed {
        position: static;
        left: auto;
        right: auto;
        top: auto;
        bottom: auto;
        margin: 1rem 1rem;
        overflow: visible;
        padding: 0;
    }

    .dash-card {
        padding: 12px 12px 14px;
    }

    /* The range beside the dropdown is the first thing to go: the toolbar is already wrapping to
       two or three lines here, and every card repeats its own window on its scope line anyway. */
    .dash-period-range {
        display: none;
    }
}
