/* ===== Data Health (/data-health) =====================================================
   The register treatment for the tenant health score.

   The score block is RULED, not boxed: one 1px border, no elevation, no progress rings.
   Three elevated cards each holding a coloured ring used to carry this screen, which put
   saturated colour on a healthy tenant and let a decorative ring stand in for the number
   that is actually the point. Here the numerals carry the reading and a single status pill
   carries the state, so a healthy screen is quiet and a failing one is legible at a glance.

   Every colour resolves from --mud-palette-* or the shared --status-* tokens, so light,
   midnight and the red tenant-operator theme all fall out of one declaration.
   ===================================================================================== */

/* Three columns sharing four rows — eyebrow, numeral, state, caption — so "Health score",
   "Operations" and "Configuration" sit on one line, their three numerals sit on the next, and
   the pill sits level with the two meters. Stacked as independent flex columns the block had
   three different vertical rhythms in it and the numerals landed 6px apart, which on a screen
   whose whole argument is alignment reads as a fault rather than as a layout. */
.dh-score {
    display: grid;
    grid-template-columns: 1fr;
    gap: 16px;
    padding: 16px 24px;
}

.dh-score__headline,
.dh-sub {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}

/* Queried against the card's own width, not the window's: at 1000px with the drawer open the
   three tracks needed 660px and had 640, so they overflowed the card they sit in. The drawer is
   collapsible, so no viewport breakpoint answers this correctly. */
.dh-card {
    container-type: inline-size;
    container-name: dh-card;
}

@container dh-card (min-width: 680px) {
    .dh-score {
        /* The score column is narrower and carries the larger numeral, so it still leads; the
           two sub-scores share what is left rather than stopping 230px short of the card's
           right rule and leaving the block looking half-drawn. */
        grid-template-columns: minmax(160px, 0.7fr) minmax(210px, 1fr) minmax(210px, 1fr);
        grid-template-rows: auto auto auto auto;
        column-gap: 40px;
        row-gap: 6px;
    }

    /* Subgrid, not fixed heights: the rows size to whichever column's content is tallest and
       every column still lands on them. Without it the columns fall back to flex stacks in the
       same three tracks — misaligned across, but never broken. */
    @supports (grid-template-rows: subgrid) {
        .dh-score__headline,
        .dh-sub {
            display: grid;
            grid-row: 1 / -1;
            grid-template-rows: subgrid;
            row-gap: 0;
        }

        /* Per-row placement inside the shared tracks. These are grid properties and are scoped
           here deliberately: in the stacked flex fallback `align-self` reads on the cross axis,
           where `end` would right-align the eyebrows and `center` would collapse the meter to
           zero width. */
        .dh-score__label,
        .dh-sub__name {
            align-self: end;
        }

        .dh-score__value,
        .dh-sub__value {
            /* 34px beside two 20px figures: baseline, not box, is what makes them one line. */
            align-self: baseline;
        }

        /* Only `justify-self` — the pill is the tallest thing in row three, so its own
           cross-axis alignment is moot, and the base `align-self: flex-start` below is later in
           the file and would win anyway. */
        .dh-score__state {
            justify-self: start;
        }

        .dh-sub__desc {
            align-self: start;
        }

        /* Level with the pill in the score column beside it. */
        .dh-meter {
            align-self: center;
        }
    }
}

/* The three eyebrows share one role so row one reads as a single line of column headings. */
.dh-score__label,
.dh-sub__name {
    font-size: 0.8125rem;
    font-weight: 400;
    color: var(--mud-palette-text-secondary);
}

.dh-score__value {
    /* Headline role from DESIGN.md — the page's one big fact, not a new type step. */
    font-size: 2.125rem;
    font-weight: 600;
    line-height: 1.1;
    /* Ink, never a state colour: the pill beside it says whether 80 is good news, and a
       green numeral would spend saturation on a screen that has nothing wrong with it. */
    color: var(--mud-palette-text-primary);
    font-variant-numeric: tabular-nums;
}

/* The state read, level with the two meters rather than a row below the number. Held to its own
   width in both layouts: stretched, the pill runs the full column and stops reading as a label. */
.dh-score__state {
    align-self: flex-start;
}

.dh-score__value-suffix {
    font-size: 1.25rem;
    line-height: 1;
    font-weight: 400;
    color: var(--mud-palette-text-secondary);
    margin-left: 2px;
}

/* Keyboard focus. MudBlazor's default is a ripple overlay, which leaves a keyboard user with no
   idea which of eight Review buttons they are on. Resolved from --mud-palette-primary rather
   than frozen as Signal Blue so the ring turns red with the rest of the app when a platform
   operator is inside a customer tenant, and lifts to the dark action blue on midnight. */
.dh-card .mud-button-root:focus-visible,
.dh-panels .mud-button-root:focus-visible,
.dh-panels .mud-expand-panel-header:focus-visible,
.dh-panels .mud-icon-button:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
}

/* The timestamp and the control that refreshes it, ruled off from the numbers above. */
.dh-score__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px;
    padding: 8px 24px;
}

.dh-sub__value {
    font-size: 1.25rem;
    font-weight: 500;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
}

.dh-sub__desc {
    font-size: 0.875rem;
    color: var(--mud-palette-text-secondary);
}

/* A 3px rule that is partly filled — the register's own device rather than an imported
   progress bar. Square ends, like every other rule on the page. Healthy fills in ink; only
   a score that needs attention takes colour. */
.dh-meter {
    height: 3px;
    background-color: var(--mud-palette-table-lines);
    overflow: hidden;
    /* The column now runs to the card's rule, but the rule inside it does not: stretched across
       a wide desk it reads as a page divider rather than as a measurement, and 78% of 900px is
       indistinguishable from full. */
    width: 100%;
    max-width: 320px;
}

/* Laid out at full length and scaled down, rather than sized to the score: the box model
   animates on the layout thread and stutters, scaleX runs on the compositor. */
.dh-meter__fill {
    display: block;
    width: 100%;
    height: 100%;
    transform-origin: left center;
    background-color: color-mix(in srgb, var(--mud-palette-text-primary) 55%, transparent);
    transition: transform 480ms cubic-bezier(0.16, 1, 0.3, 1);
}

.dh-meter--watch .dh-meter__fill {
    background-color: var(--status-warning-fg);
}

.dh-meter--risk .dh-meter__fill {
    background-color: var(--status-error-fg);
}

@media (prefers-reduced-motion: reduce) {
    .dh-meter__fill {
        transition: none;
    }
}

/* ===== Check list =====
   Flat panels defined by the same 1px rule as every other card on the screen. */
.dh-panels .mud-expand-panel {
    border: 1px solid var(--mud-palette-table-lines);
    border-radius: 5px;
    margin-bottom: 8px;
    background-color: var(--mud-palette-surface);
}

.dh-panels .mud-expand-panel::before {
    /* MudBlazor draws a divider pseudo-element between stacked panels; the panels are
       already individually ruled, so it only doubles the line. */
    display: none;
}

/* 24px is the page's gutter — the score card above uses it, so the category name, the "Check"
   column heading and every check name below it all start on the same vertical. Before this the
   panel name sat at 321 and its own table's first column at 345, which is the one misalignment
   a ruled system cannot carry. */
.dh-panels .mud-expand-panel-header {
    padding: 8px 24px;
}

/* Rule the category header off from its checks, the same way the score card rules its footer
   off from its numbers. The table brings its own 24px cell gutter, so the content wrapper gives
   its up rather than insetting the table a second time.

   The gutter class is matched explicitly: MudBlazor sets its 24px as padding-left/right
   longhands on `.mud-expand-panel-content.mud-expand-panel-gutters`, which a `padding: 0`
   shorthand loses to. */
.dh-panels .mud-expand-panel-content,
.dh-panels .mud-expand-panel-content.mud-expand-panel-gutters {
    padding: 0;
    border-top: 1px solid var(--mud-palette-table-lines);
}

.dh-panel__title {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    min-width: 0;
}

.dh-panel__name {
    font-size: 0.875rem;
    font-weight: 600;
}

.dh-panel__count {
    font-size: 0.875rem;
    color: var(--mud-palette-text-secondary);
    margin-left: auto;
    white-space: nowrap;
}

/* House grid density: tight vertically, generous horizontally so the columns stay
   scannable when a category holds a dozen checks. */
.dh-checks td,
.dh-checks th {
    padding: 4px 24px;
    /* Descriptions run to three lines while severity, pass rate and the action are one. Centred,
       those three floated to the middle of a tall row and stopped belonging to the check name
       they describe; topped, each row reads as a single line with a note under it. */
    vertical-align: top;
}

.dh-checks td:first-child,
.dh-checks th:first-child {
    padding-left: 24px;
}

.dh-checks td:last-child,
.dh-checks th:last-child {
    padding-right: 24px;
}

/* The action is a control, not a value: it keeps the row's first line rather than the top of
   the description block, and never wraps its count onto a second line. */
.dh-checks td:last-child .mud-button-root {
    white-space: nowrap;
}

.dh-check__name {
    font-size: 0.875rem;
    font-weight: 500;
}

.dh-check__desc {
    font-size: 0.875rem;
    color: var(--mud-palette-text-secondary);
    /* Descriptions run to ~150 characters; unbounded they stretch to the full table width
       and lose their line. */
    max-width: 62ch;
}

.dh-num {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* A check with nothing in its population. "0 / 0" reads as a total failure; it is the opposite —
   there is nothing here to be wrong. */
.dh-num--none {
    color: var(--mud-palette-text-secondary);
}

/* ===== Findings dialog (the Review list) =====
   Same density and stacking as the check list, but the columns are weighted differently: here
   the record summary IS the content, and the date and the action are fixed-width furniture.
   Left to the browser's auto layout the summary took ~150px and broke over five lines while a
   repeated "Review blocking defects" label held 180px on all fifteen rows. */
.dh-issues th:first-child,
.dh-issues td:first-child {
    width: 100%;
}

.dh-issues th:not(:first-child),
.dh-issues td:not(:first-child) {
    width: 1%;
    white-space: nowrap;
}

.dh-num__share {
    color: var(--mud-palette-text-secondary);
    margin-left: 6px;
}

.dh-fail {
    color: var(--status-error-fg);
    font-weight: 500;
}

/* ===== Below the stacking breakpoint =====
   MudBlazor turns each row into a flex label/value card. Left alone that put the check's name
   and its own description into two ~90px gutters side by side — "Property has open
   certification-blocking defects" broke across five lines beside a description broken across
   seven. The check is the record here, so it gets the full width and its label suppressed;
   severity and pass rate keep the label/value form beneath it. */
@media (max-width: 600px) {
    .dh-checks td,
    .dh-checks th {
        padding: 4px 16px;
        vertical-align: baseline;
    }

    .dh-checks td:first-child {
        flex-direction: column;
        align-items: stretch;
        text-align: left;
        padding-top: 12px;
    }

    .dh-checks td:first-child::before {
        /* The name is the heading of its own card; "Check" above it is a second label for the
           thing the reader is already looking at. */
        display: none;
    }

    .dh-check__desc {
        /* The 62ch cap exists to stop a description running the width of a desk. On a phone
           there is no width to run. */
        max-width: none;
    }

    /* The action cell has no header, so its stacked label is empty and reads as a blank row. */
    .dh-checks td:last-child::before {
        display: none;
    }

    .dh-checks td:last-child {
        justify-content: flex-end;
        padding-bottom: 12px;
    }

    .dh-checks td:last-child:empty {
        display: none;
    }

    /* House density is built for a mouse on a desk. A 31px row action under a thumb is not, so
       the controls — and only the controls — take a touch-sized box on a phone. */
    .dh-checks td:last-child .mud-button-root,
    .dh-score__footer .mud-button-root,
    .dh-issues .mud-icon-button {
        min-height: 40px;
        min-width: 40px;
    }

    .dh-panels .mud-expand-panel-header {
        padding: 8px 16px;
    }

    .dh-checks td:first-child,
    .dh-checks th:first-child {
        padding-left: 16px;
    }

    .dh-checks td:last-child,
    .dh-checks th:last-child {
        padding-right: 16px;
    }

    .dh-score {
        padding: 16px;
    }

    .dh-score__footer {
        padding: 8px 16px;
    }
}
