/* ============================================================================
   EGKits command-center dashboard
   ----------------------------------------------------------------------------
   Global (not CSS-isolated) on purpose: the dashboard is composed from widgets
   that live in several projects, and scoped styles would force every one of them
   to re-declare the same tokens.

   Three rules this file follows:

   1. Colour comes from --mud-palette-* via the --egk-* tokens, never from
      hard-coded hex. That is what makes Theme Studio and dark mode work without
      a second stylesheet.
   2. Layout uses logical properties (inline-start, margin-inline, padding-block)
      throughout, so Arabic and Hebrew mirror correctly with no RTL overrides.
   3. Breakpoints are container queries on .dash-shell, not viewport media
      queries. The dashboard's available width depends on whether the navigation
      drawer is open, which the viewport does not know.
   ========================================================================== */

/* ---------------------------------------------------------------- tokens --- */

.dash-shell {
    /* Density scale. One knob per surface so a "compact" variant is a token
       change rather than a hunt through every rule. */
    --dash-gap: var(--egk-space-4);
    --dash-card-pad: var(--egk-space-4);
    --dash-card-pad-tight: var(--egk-space-3);
    --dash-row-gap: var(--egk-space-3);
    --dash-radius: var(--egk-radius-lg);
    --dash-radius-sm: var(--egk-radius-sm);

    /* Severity. Named by meaning, not by colour, so a rule reads
       "this is critical" rather than "this is red". */
    --dash-critical: var(--egk-color-error);
    --dash-critical-rgb: var(--mud-palette-error-rgb, 211, 47, 47);
    --dash-warning: var(--egk-color-warning);
    --dash-warning-rgb: var(--mud-palette-warning-rgb, 237, 108, 2);
    --dash-attention: var(--egk-color-info);
    --dash-attention-rgb: var(--mud-palette-info-rgb, 2, 136, 209);
    --dash-ok: var(--egk-color-success);
    --dash-ok-rgb: var(--mud-palette-success-rgb, 46, 125, 50);
    --dash-neutral: var(--egk-color-muted);

    /* Tint strength for severity washes. Raised in dark mode below, because the
       same alpha over a dark surface is almost invisible. */
    --dash-tint: 0.07;
    --dash-tint-strong: 0.12;

    --dash-surface: var(--egk-color-surface);
    --dash-border: var(--egk-color-divider);

    /* Elevation. Two layers rather than one: a tight contact shadow that anchors
       the card to the page, plus a wide diffuse one that gives it height. A
       single shadow reads as either flat or muddy, never as a real object. */
    --dash-shadow:
        0 1px 2px rgba(15, 23, 42, 0.04),
        0 6px 16px -10px rgba(15, 23, 42, 0.12);
    --dash-shadow-hover:
        0 1px 2px rgba(15, 23, 42, 0.05),
        0 16px 34px -14px rgba(15, 23, 42, 0.20);

    /* The 1px top highlight that makes a surface look lit from above. This is
       most of the difference between a bordered rectangle and a physical card. */
    --dash-hairline: inset 0 1px 0 rgba(255, 255, 255, 0.75);

    /* Card fill stays essentially white. Fading towards the page background made
       every card look faintly stained over a saturated theme colour, which is
       the opposite of the intended effect. */
    --dash-fill: linear-gradient(
        180deg,
        rgba(var(--egk-color-surface-rgb), 1) 0%,
        rgba(var(--egk-color-surface-rgb), 0.97) 100%);

    /* Interactive surface fill for rows, tiles and pills inside a card. */
    --dash-fill-subtle: rgba(var(--egk-color-surface-rgb), 0.55);
    --dash-fill-hover: rgba(var(--egk-color-primary-rgb), 0.05);

    /* Border that appears on hover, so resting cards stay quiet. */
    --dash-border-hover: rgba(var(--egk-color-primary-rgb), 0.28);

    --dash-lift: -2px;

    container-type: inline-size;
    container-name: dash;

    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--dash-gap);
    padding-block: var(--egk-space-5);
    padding-inline: var(--egk-space-5);
    color: var(--egk-color-text);
}

/* Ambient canvas.
   Two soft brand-tinted pools of light behind the grid, confined to the top of
   the page. Kept very weak on purpose: the theme's primary is a saturated
   colour, and at any real strength this stops being "depth" and becomes a
   coloured cast over every white card on the page. The job is to keep the top of
   the page from being a flat sheet of grey, not to tint the content.
   Pointer-events off and z-index below the content so it is purely optical. */
.dash-shell::before {
    content: "";
    position: absolute;
    inset-block-start: 0;
    inset-inline: 0;
    /* Fades out well before the fold rather than washing the whole scroll. */
    block-size: 24rem;
    z-index: 0;
    pointer-events: none;
    /* Nothing in light mode. The theme's primary is a saturated green, and any
       tint of it spread behind a page of white cards reads as a dirty cast on the
       paper rather than as depth. A clean white page is the more expensive look;
       the dark theme below is where an ambient wash actually earns its place. */
    background: none;
}

/* Everything real sits above the wash. */
.dash-shell > * {
    position: relative;
    z-index: 1;
}

/* One visible focus ring for every custom control on the dashboard. The cards
   are keyboard-navigable surfaces, and the default ring disappears against the
   tinted backgrounds these controls use. Keyed to :focus-visible so it appears
   for keyboard users without ringing every mouse click. The soft outer halo is
   the themed --egk-focus-ring, which reads as designed rather than as a browser
   default while the solid outline guarantees the contrast. */
.dash-shell :is(button, [role="button"], a):focus-visible {
    outline: 2px solid var(--egk-color-primary);
    outline-offset: 2px;
    /* No border-radius here: the halo already follows whatever radius the
       control has, and forcing one would square off the pill-shaped rows. */
    box-shadow: var(--egk-focus-ring);
}

/* Dark mode is a deliberate palette, not an inversion. Surfaces lift slightly
   off the page background so cards read as objects, borders get brighter to
   survive the lower contrast, and severity tints get stronger. */
.mud-theme-dark .dash-shell {
    --dash-tint: 0.14;
    --dash-tint-strong: 0.22;
    --dash-surface: color-mix(in srgb, var(--egk-color-surface) 92%, #ffffff 8%);
    --dash-border: rgba(255, 255, 255, 0.10);

    --dash-shadow:
        0 1px 2px rgba(0, 0, 0, 0.5),
        0 8px 22px -12px rgba(0, 0, 0, 0.7);
    --dash-shadow-hover:
        0 1px 2px rgba(0, 0, 0, 0.55),
        0 20px 40px -16px rgba(0, 0, 0, 0.8);

    /* The lit-from-above highlight has to drop to a whisper: at light-mode
       strength a white inset line on a dark card looks like a rendering fault. */
    --dash-hairline: inset 0 1px 0 rgba(255, 255, 255, 0.06);

    /* Dark cards lift towards the viewer instead of sinking, so the wash runs
       the other way ÃÂ¢ÃÂÃÂ lighter at the top, settling into the page below. */
    --dash-fill: linear-gradient(
        180deg,
        rgba(255, 255, 255, 0.045) 0%,
        rgba(255, 255, 255, 0.012) 100%),
        var(--dash-surface);

    --dash-fill-subtle: rgba(255, 255, 255, 0.035);
    --dash-fill-hover: rgba(var(--egk-color-primary-rgb), 0.12);
    --dash-border-hover: rgba(var(--egk-color-primary-rgb), 0.45);
}

/* The ambient wash carries further in the dark, where there is no white page to
   compete with it. Radii stay inside the band's height on purpose: a gradient
   still mid-fade at the band's edge leaves a hard horizontal line across the
   page, which is far more noticeable than the wash itself. */
.mud-theme-dark .dash-shell::before {
    background:
        radial-gradient(
            56rem 20rem at 10% -20%,
            rgba(var(--egk-color-primary-rgb), 0.13),
            transparent 70%),
        radial-gradient(
            40rem 18rem at 100% -10%,
            rgba(var(--egk-color-secondary-rgb), 0.09),
            transparent 70%);
}

.mud-theme-dark .dash-header {
    background:
        linear-gradient(
            135deg,
            rgba(var(--egk-color-primary-rgb), 0.20) 0%,
            rgba(var(--egk-color-secondary-rgb), 0.10) 45%,
            rgba(255, 255, 255, 0) 100%),
        var(--dash-fill);
}

.mud-theme-dark .dash-pill,
.mud-theme-dark .dash-chip,
.mud-theme-dark .dash-header__key,
.mud-theme-dark .dash-action__key,
.mud-theme-dark .dash-palette__key,
.mud-theme-dark .dash-palette__hint {
    background: rgba(255, 255, 255, 0.07);
    box-shadow: var(--dash-hairline);
}

.mud-theme-dark .dash-pill--tenant {
    background: rgba(255, 255, 255, 0.10);
}

/* Keeps the gradient badge readable: it is white text on brand colour in both
   themes, so it must not inherit the translucent dark pill fill above. */
.mud-theme-dark .dash-pill--platform {
    background: var(--egk-gradient-brand);
}

/* ----------------------------------------------------------------- header --- */

/* The context bar is a panel, not a run of loose text. Giving it a surface of
   its own separates "where am I and who am I" from "what is wrong", which is
   the dashboard's central distinction ÃÂ¢ÃÂÃÂ and it is the first thing on screen, so
   it is where a premium impression is either made or lost. */
.dash-header {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--dash-gap);
    padding-block: var(--egk-space-4);
    padding-inline: var(--egk-space-5);
    border: 1px solid var(--dash-border);
    border-radius: var(--dash-radius);
    /* A whisper of brand in the leading corner, no more. At the strength this
       started out the panel read as a pale green card rather than a white one,
       and it set the tone for the whole page. The 2px gradient hairline below is
       what carries the brand here; the surface just has to stay clean. */
    background:
        linear-gradient(
            135deg,
            rgba(var(--egk-color-primary-rgb), 0.04) 0%,
            rgba(var(--egk-color-secondary-rgb), 0.02) 38%,
            rgba(var(--egk-color-surface-rgb), 0) 72%),
        var(--dash-fill);
    box-shadow: var(--dash-shadow), var(--dash-hairline);
    overflow: hidden;
}

/* A brand hairline along the top edge: the smallest possible amount of colour
   that still says the product has a designer. */
.dash-header::before {
    content: "";
    position: absolute;
    inset-block-start: 0;
    inset-inline: 0;
    block-size: 2px;
    background: var(--egk-gradient-brand);
    opacity: 0.85;
}

.dash-header__main {
    display: flex;
    flex-direction: column;
    gap: var(--egk-space-2);
    min-inline-size: 0;
}

.dash-header__pills {
    display: flex;
    flex-wrap: wrap;
    gap: var(--egk-space-2);
}

.dash-header__greeting {
    margin: 0;
    display: flex;
    align-items: center;
    gap: var(--egk-space-3);
    font-size: clamp(1.35rem, 2.8cqi, 1.9rem);
    font-weight: var(--egk-weight-bold);
    line-height: var(--egk-lh-snug);
    letter-spacing: var(--egk-tracking-tight);
}

.dash-header__icon-tile {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 2.75rem;
    block-size: 2.75rem;
    flex-shrink: 0;
    border-radius: calc(var(--dash-radius-sm) + 2px);
    color: var(--egk-color-primary);
    background:
        linear-gradient(
            145deg,
            rgba(var(--egk-color-primary-rgb), 0.14) 0%,
            rgba(var(--egk-color-secondary-rgb, var(--egk-color-primary-rgb)), 0.06) 100%);
    border: 1px solid rgba(var(--egk-color-primary-rgb), 0.16);
    box-shadow: var(--dash-hairline);
}

.dash-header__icon-tile .dash-header__title-icon,
.dash-header__icon-tile .mud-icon-root {
    margin: 0;
    font-size: 1.35rem;
    color: inherit;
}

.dash-header__title-text {
    min-inline-size: 0;
}

.dash-header__subtitle {
    margin: 0;
    font-size: 0.875rem;
    line-height: var(--egk-lh-normal);
    color: var(--egk-color-muted);
    max-inline-size: 68ch;
}

.dash-header__stamp {
    display: flex;
    align-items: center;
    gap: var(--egk-space-2);
    margin: 0;
    font-size: 0.75rem;
    font-weight: var(--egk-weight-medium);
    color: var(--egk-color-muted);
    white-space: nowrap;
}

/* Live dot. Solid, with a soft halo ÃÂ¢ÃÂÃÂ a full pulse animation on something that
   updates once a minute would be a distraction rather than a signal. */
.dash-header__pulse {
    inline-size: 0.4rem;
    block-size: 0.4rem;
    border-radius: var(--egk-radius-full);
    background: var(--dash-ok);
    box-shadow: 0 0 0 3px rgba(var(--dash-ok-rgb), 0.18);
    flex-shrink: 0;
}

.dash-header__actions {
    display: flex;
    align-items: center;
    gap: var(--egk-space-2);
    flex-wrap: wrap;
    row-gap: var(--egk-space-2);
    min-inline-size: 0;
    max-inline-size: 100%;
}

.dash-header__actions > * {
    min-inline-size: 0;
    max-inline-size: 100%;
}

.dash-header__actions .mud-select,
.dash-header__actions .mud-input-control,
.dash-header__actions .mud-autocomplete,
.dash-header__actions .mud-width-full {
    min-inline-size: 0 !important;
    max-inline-size: 100%;
    flex: 1 1 12rem;
}

/* Keycaps, drawn as keycaps: a hairline top highlight and a 1px bottom edge
   read as a physical key rather than a bordered box. */
.dash-header__key,
.dash-action__key,
.dash-palette__key,
.dash-palette__hint {
    font-family: var(--egk-font-mono);
    font-size: 0.6875rem;
    font-weight: var(--egk-weight-medium);
    padding-block: 0.15rem;
    padding-inline: 0.4rem;
    border: 1px solid var(--dash-border);
    border-radius: var(--dash-radius-sm);
    color: var(--egk-color-muted);
    background: rgba(var(--egk-color-surface-rgb), 0.85);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.6),
        0 1px 0 rgba(15, 23, 42, 0.06);
    white-space: nowrap;
}

/* The palette trigger should look like a place you can type, because that is
   what it opens. A plain outlined button hides the dashboard's best feature. */
.dash-header__palette {
    gap: var(--egk-space-2);
    min-inline-size: 15rem;
    justify-content: flex-start;
    border-radius: var(--egk-radius-full);
    border-color: var(--dash-border);
    background: rgba(var(--egk-color-surface-rgb), 0.75);
    box-shadow: var(--dash-shadow), var(--dash-hairline);
    text-transform: none;
    transition:
        border-color var(--egk-dur-fast) var(--egk-ease),
        box-shadow var(--egk-dur-fast) var(--egk-ease),
        background var(--egk-dur-fast) var(--egk-ease);
}

.dash-header__palette:hover {
    border-color: var(--dash-border-hover);
    background: rgba(var(--egk-color-surface-rgb), 0.95);
    box-shadow: var(--dash-shadow-hover), var(--dash-hairline);
}

.dash-header__palette-label {
    flex: 1 1 auto;
    text-align: start;
    color: var(--egk-color-muted);
    font-weight: var(--egk-weight-medium);
}

/* ------------------------------------------------------------------ pills --- */

.dash-pill,
.dash-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--egk-space-1);
    padding-block: 0.22rem;
    padding-inline: var(--egk-space-3);
    border-radius: var(--egk-radius-full);
    border: 1px solid var(--dash-border);
    background: rgba(var(--egk-color-surface-rgb), 0.72);
    /* Frosted against the header's gradient. Degrades to plain translucency
       where backdrop-filter is unsupported, which is visually fine. */
    backdrop-filter: blur(8px);
    box-shadow: var(--dash-hairline);
    font-size: 0.75rem;
    line-height: 1.45;
    font-weight: var(--egk-weight-medium);
    color: var(--egk-color-muted);
    max-inline-size: 22ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The tenant is the anchor of the whole page, so it is the one pill allowed to
   look like a title rather than metadata. */
.dash-pill--tenant {
    color: var(--egk-color-text);
    font-weight: var(--egk-weight-semibold);
    font-size: 0.8125rem;
    background: rgba(var(--egk-color-surface-rgb), 0.9);
    border-color: rgba(var(--egk-color-primary-rgb), 0.16);
}

/* Master-tenant badge. The only element on the dashboard that carries the full
   brand gradient, because "you are operating the platform itself" is exactly
   the sort of thing that should be unmistakable. */
.dash-pill--platform {
    color: var(--egk-on-brand);
    border-color: transparent;
    background: var(--egk-gradient-brand);
    box-shadow: 0 4px 14px -6px rgba(var(--egk-color-primary-rgb), 0.65);
    font-weight: var(--egk-weight-semibold);
    /* Exempt from the shared 22ch cap. "Platform control center" is 22 characters
       plus an icon, so the cap clipped it to "Platform control ceÃÂ¢ÃÂÃÂ¦" ÃÂ¢ÃÂÃÂ a badge
       announcing elevated privileges is the last thing that should look broken.
       It is a fixed phrase, not user data, so it cannot run away. */
    max-inline-size: none;
}

.dash-pill--warning {
    color: var(--dash-warning);
    border-color: rgba(var(--dash-warning-rgb), 0.4);
    background: rgba(var(--dash-warning-rgb), var(--dash-tint));
}

.dash-pill--critical {
    color: var(--dash-critical);
    border-color: rgba(var(--dash-critical-rgb), 0.45);
    background: rgba(var(--dash-critical-rgb), var(--dash-tint));
}

/* Quiet in-card note for a section with nothing to report, used where the rest
   of the widget still carries content worth showing. Deliberately not the full
   widget empty state, which would hide that remaining content. */
.dash-note {
    display: flex;
    align-items: center;
    gap: var(--egk-space-2);
    padding-block: var(--egk-space-3);
    color: var(--egk-color-muted);
    font-size: 0.8125rem;
}

/* Pills whose value is operator data manage truncation internally: the pill
   grows to fit its fixed metadata, and only the value ellipsizes. */
.dash-pill--fluid {
    max-inline-size: none;
    overflow: visible;
}

.dash-pill__text {
    min-inline-size: 0;
    max-inline-size: 18ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Secondary fact inside a pill ÃÂ¢ÃÂÃÂ the plan's validity date after its name.
   Same line, quieter voice, separated by a soft dot. Never truncated: a date
   clipped to "Valid urÃÂ¢ÃÂÃÂ¦" is worse than no date at all. */
.dash-pill__meta {
    color: var(--egk-color-muted);
    font-weight: var(--egk-weight-regular, 400);
    flex-shrink: 0;
    white-space: nowrap;
}

.dash-pill strong {
    flex-shrink: 0;
    white-space: nowrap;
}

.dash-pill__meta::before {
    content: "\00B7"; /* middle dot */
    margin-inline-end: var(--egk-space-1);
    opacity: 0.6;
}

/* Wall-clock pill: tabular digits so the minute flip never shifts the row. */
.dash-pill--clock time {
    font-variant-numeric: tabular-nums;
}

.dash-chip--ok {
    color: var(--dash-ok);
    border-color: rgba(var(--dash-ok-rgb), 0.4);
    background: rgba(var(--dash-ok-rgb), var(--dash-tint));
}

.dash-chip--composite {
    color: var(--egk-color-primary);
    border-color: rgba(var(--egk-color-primary-rgb), 0.35);
    background: rgba(var(--egk-color-primary-rgb), var(--dash-tint));
}

.dash-chip--tentative {
    color: var(--egk-color-muted);
    border-style: dashed;
}

/* -------------------------------------------------------------------- wave --- */

/* One priority band. The wrapper exists so a band's heading and its grid travel
   together and disappear together. */
.dash-wave {
    display: flex;
    flex-direction: column;
    gap: var(--dash-row-gap);
    min-inline-size: 0;
}

.dash-wave__head {
    display: flex;
    align-items: center;
    gap: var(--egk-space-3);
}

.dash-wave__label {
    margin: 0;
    font-size: 0.6875rem;
    font-weight: var(--egk-weight-bold);
    text-transform: uppercase;
    letter-spacing: var(--egk-tracking-caps);
    color: var(--egk-color-muted);
    white-space: nowrap;
}

/* A rule that runs out from the label and fades. Cheaper on the eye than a full
   divider, and it makes the label read as a section marker rather than a title
   floating in space. */
.dash-wave__rule {
    flex: 1 1 auto;
    block-size: 1px;
    background: linear-gradient(
        to right,
        var(--dash-border) 0%,
        transparent 100%);
}

/* Mirrors the fade for right-to-left, where the rule must run the other way. */
.dash-shell--rtl .dash-wave__rule {
    background: linear-gradient(
        to left,
        var(--dash-border) 0%,
        transparent 100%);
}

/* -------------------------------------------------------------------- grid --- */

.dash-grid {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: var(--dash-gap);
    align-items: start;
}

/* Empty wave hosts must not contribute a gap. Without this, a hidden platform
   wave on a customer tenant leaves a phantom band of whitespace. */
.dash-grid:empty {
    display: none;
}

/* Cards arrive rather than appear, staggered a few frames apart so the eye
   travels down the page in priority order instead of being hit with everything
   at once.

   Fill mode is deliberately `backwards` and not `forwards`: it holds the
   pre-animation state through the delay, then hands control back to the normal
   cascade. With `forwards` the final keyframe would keep overriding the hover
   transform for the life of the page, and the cards would stop lifting. */
.dash-grid > * {
    animation: dash-rise var(--egk-dur) var(--egk-ease-out) backwards;
}

.dash-grid > *:nth-child(2) { animation-delay: 40ms; }
.dash-grid > *:nth-child(3) { animation-delay: 80ms; }
.dash-grid > *:nth-child(4) { animation-delay: 120ms; }
.dash-grid > *:nth-child(5) { animation-delay: 160ms; }
.dash-grid > *:nth-child(n + 6) { animation-delay: 200ms; }

@keyframes dash-rise {
    from {
        opacity: 0;
        transform: translateY(8px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

.dash-span-1 { grid-column: span 1; }
.dash-span-2 { grid-column: span 2; }
.dash-span-3 { grid-column: span 3; }
.dash-span-4 { grid-column: span 4; }
.dash-span-5 { grid-column: span 5; }
.dash-span-6 { grid-column: span 6; }
.dash-span-7 { grid-column: span 7; }
.dash-span-8 { grid-column: span 8; }
.dash-span-9 { grid-column: span 9; }
.dash-span-10 { grid-column: span 10; }
.dash-span-11 { grid-column: span 11; }
.dash-span-12 { grid-column: span 12; }

/* ------------------------------------------------------------------ card --- */

.dash-widget {
    position: relative;
    display: flex;
    flex-direction: column;
    min-inline-size: 0;
    background: var(--dash-fill);
    border: 1px solid var(--dash-border);
    border-radius: var(--dash-radius);
    box-shadow: var(--dash-shadow), var(--dash-hairline);
    overflow: hidden;
    transition:
        box-shadow var(--egk-dur) var(--egk-ease-out),
        border-color var(--egk-dur) var(--egk-ease-out),
        transform var(--egk-dur) var(--egk-ease-out);
}

/* Lifts towards the cursor. Small ÃÂ¢ÃÂÃÂ 2px ÃÂ¢ÃÂÃÂ because thirty cards that leap off
   the page is a toy, and one that acknowledges the pointer is a product. */
.dash-widget:hover {
    box-shadow: var(--dash-shadow-hover), var(--dash-hairline);
    border-color: var(--dash-border-hover);
    transform: translateY(var(--dash-lift));
}

/* Severity accent as a gradient bar rather than a flat border: it fades out
   down the card so the colour marks the card without striping it. Positioned
   with inset-inline-start so it still mirrors correctly in RTL. */
.dash-widget[class*="dash-widget--accent-"]::before {
    content: "";
    position: absolute;
    inset-block: 0;
    inset-inline-start: 0;
    inline-size: 3px;
    z-index: 2;
    background: linear-gradient(
        to bottom,
        var(--dash-accent-color, var(--egk-color-primary)) 0%,
        color-mix(in srgb, var(--dash-accent-color, var(--egk-color-primary)) 45%, transparent) 55%,
        transparent 100%);
}

/* An accented card stays a white card.
   Severity is announced by the leading bar, the tinted icon tile and the count
   badge ÃÂ¢ÃÂÃÂ three small, high-contrast marks. Filling the surface as well turned
   the most important card on the page into a large pale rectangle, which reads
   as washed-out rather than urgent: a colour covering four hundred square
   centimetres stops being a signal and becomes a background. */
.dash-widget--accent-critical {
    --dash-accent-color: var(--dash-critical);
    --dash-accent-rgb: var(--dash-critical-rgb);
    /* Barely warmer than the neutral border. Enough to relate the frame to the
       accent bar, not enough to outline the card in red. */
    border-color: rgba(var(--dash-critical-rgb), 0.16);
}

.dash-widget--accent-critical:hover {
    border-color: rgba(var(--dash-critical-rgb), 0.30);
}

.dash-widget--accent-warning {
    --dash-accent-color: var(--dash-warning);
    --dash-accent-rgb: var(--dash-warning-rgb);
    border-color: rgba(var(--dash-warning-rgb), 0.14);
}

.dash-widget--accent-attention {
    --dash-accent-color: var(--dash-attention);
    --dash-accent-rgb: var(--dash-attention-rgb);
}

.dash-widget--failed {
    border-color: rgba(var(--dash-critical-rgb), 0.35);
}

.dash-widget__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--egk-space-2);
    padding-block: var(--dash-card-pad-tight);
    padding-inline: var(--dash-card-pad);
    /* A rule that fades at both ends instead of a hard line across the whole
       card. Reads as a seam rather than a table border. Symmetric on purpose:
       a one-sided fade would need mirroring in RTL, and this needs none. */
    border-block-end: 1px solid transparent;
    border-image: linear-gradient(
        to right,
        transparent 0%,
        var(--dash-border) 12%,
        var(--dash-border) 88%,
        transparent 100%) 1;
}

.dash-widget__title {
    display: flex;
    align-items: center;
    gap: var(--egk-space-2);
    min-inline-size: 0;
}

/* Small caps with real tracking. At this size, letter-spacing is what separates
   a deliberate label from shrunken body text. */
.dash-widget__title-text {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--egk-color-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The icon becomes a tile. Applying the padding and radius directly to the
   MudBlazor <svg> avoids a wrapper element in every widget's markup. */
.dash-widget__icon {
    box-sizing: content-box;
    padding: 0.3rem;
    border-radius: var(--dash-radius-sm);
    color: var(--egk-color-primary);
    background: linear-gradient(
        140deg,
        rgba(var(--egk-color-primary-rgb), 0.16),
        rgba(var(--egk-color-secondary-rgb), 0.10));
    box-shadow: inset 0 0 0 1px rgba(var(--egk-color-primary-rgb), 0.12);
    flex-shrink: 0;
}

/* Severity-accented cards tint their own icon tile, so the card reads as one
   object instead of a red card with a blue badge on it. */
.dash-widget[class*="dash-widget--accent-"] .dash-widget__icon {
    color: var(--dash-accent-color);
    background: rgba(var(--dash-accent-rgb), var(--dash-tint-strong));
    box-shadow: inset 0 0 0 1px rgba(var(--dash-accent-rgb), 0.20);
}

.dash-widget__count {
    font-size: 0.6875rem;
    font-weight: 700;
    min-inline-size: 1.35rem;
    text-align: center;
    padding-inline: 0.4rem;
    padding-block: 0.05rem;
    border-radius: var(--egk-radius-full);
    background: rgba(var(--egk-color-primary-rgb), var(--dash-tint-strong));
    box-shadow: inset 0 0 0 1px rgba(var(--egk-color-primary-rgb), 0.18);
    color: var(--egk-color-primary);
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}

.dash-widget--accent-critical .dash-widget__count {
    background: var(--dash-critical);
    box-shadow: 0 2px 8px -2px rgba(var(--dash-critical-rgb), 0.6);
    color: var(--egk-on-brand);
}

.dash-widget--accent-warning .dash-widget__count {
    background: rgba(var(--dash-warning-rgb), var(--dash-tint-strong));
    box-shadow: inset 0 0 0 1px rgba(var(--dash-warning-rgb), 0.3);
    color: var(--dash-warning);
}

.dash-widget__actions {
    display: flex;
    align-items: center;
    gap: var(--egk-space-1);
    flex-shrink: 0;
    flex-wrap: wrap;
    justify-content: flex-end;
    max-inline-size: 100%;
}

.dash-widget__body {
    padding: var(--dash-card-pad);
    display: flex;
    flex-direction: column;
    gap: var(--dash-row-gap);
    min-inline-size: 0;
}

.dash-widget--strip .dash-widget__body {
    padding-block: var(--dash-card-pad-tight);
}

/* ------------------------------------------------------- states --- */

.dash-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: var(--egk-space-2);
    padding-block: var(--egk-space-6);
    padding-inline: var(--egk-space-4);
}

.dash-state__title {
    font-size: 0.9375rem;
    font-weight: var(--egk-weight-semibold);
}

.dash-state__hint {
    font-size: 0.8125rem;
    line-height: var(--egk-lh-normal);
    color: var(--egk-color-muted);
    max-inline-size: 44ch;
}

/* An empty state is a designed outcome, not an absence, so its glyph sits in a
   soft disc instead of floating loose in the middle of a blank card. */
.dash-state__glyph {
    box-sizing: content-box;
    padding: var(--egk-space-3);
    border-radius: var(--egk-radius-full);
    color: var(--egk-color-muted);
    background: rgba(var(--egk-color-primary-rgb), 0.07);
    box-shadow: inset 0 0 0 1px rgba(var(--egk-color-primary-rgb), 0.10);
    opacity: 0.9;
}

.dash-state--empty .dash-state__title {
    color: var(--egk-color-muted);
    font-weight: 500;
}

/* All clear. The only empty state on the dashboard that is an achievement, so it
   gets the healthy colour instead of the grey used for "no results". */
.dash-state--allclear .dash-state__glyph {
    color: var(--dash-ok);
    background: rgba(var(--dash-ok-rgb), var(--dash-tint-strong));
    box-shadow: inset 0 0 0 1px rgba(var(--dash-ok-rgb), 0.22);
    opacity: 1;
}

.dash-state--allclear .dash-state__title {
    color: var(--dash-ok);
    font-weight: var(--egk-weight-semibold);
}

.dash-state--error {
    color: var(--dash-critical);
}

.dash-state--error .dash-state__hint {
    color: var(--egk-color-muted);
}

.dash-state--loading {
    align-items: stretch;
    padding: 0;
    /* The same gap the real list uses, so the placeholder and the content it
       replaces are the same height. */
    gap: var(--dash-row-gap);
}

/* Mirrors .dash-signal's box so the placeholder occupies the space the real row
   will occupy. */
.dash-skeleton-row {
    display: flex;
    align-items: flex-start;
    gap: var(--egk-space-3);
    padding-block: var(--egk-space-3);
    padding-inline: var(--egk-space-3);
    border: 1px solid var(--dash-border);
    border-radius: var(--egk-radius-md);
}

.dash-skeleton-row__body {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    flex: 1 1 auto;
    min-inline-size: 0;
    /* Nudged down so the lines sit against the glyph the way real text does. */
    padding-block-start: 0.15rem;
}

.dash-skeleton {
    border-radius: var(--dash-radius-sm);
    background: linear-gradient(
        90deg,
        rgba(var(--egk-color-primary-rgb), 0.06) 25%,
        rgba(var(--egk-color-primary-rgb), 0.14) 37%,
        rgba(var(--egk-color-primary-rgb), 0.06) 63%
    );
    background-size: 400% 100%;
    animation: dash-shimmer 1.4s ease-in-out infinite;
}

.dash-skeleton--dot {
    inline-size: 1.25rem;
    block-size: 1.25rem;
    border-radius: var(--egk-radius-full);
    flex-shrink: 0;
}

.dash-skeleton--title {
    block-size: 0.7rem;
    inline-size: 62%;
}

.dash-skeleton--detail {
    block-size: 0.6rem;
    inline-size: 38%;
    opacity: 0.7;
}

.dash-skeleton--action {
    block-size: 1.7rem;
    inline-size: 6.5rem;
    border-radius: var(--egk-radius-full);
    flex-shrink: 0;
}

/* Uneven line lengths. Identical rows read as a loading graphic; ragged ones read
   as text that has not arrived yet, which is what is actually being promised. */
.dash-skeleton-row:nth-child(2) .dash-skeleton--title { inline-size: 48%; }
.dash-skeleton-row:nth-child(2) .dash-skeleton--detail { inline-size: 30%; }
.dash-skeleton-row:nth-child(3) .dash-skeleton--title { inline-size: 71%; }
.dash-skeleton-row:nth-child(3) .dash-skeleton--detail { inline-size: 44%; }
.dash-skeleton-row:nth-child(4) .dash-skeleton--title { inline-size: 55%; }
.dash-skeleton-row:nth-child(4) .dash-skeleton--detail { inline-size: 25%; }

/* Strips are a single dense line of services, so the tall two-line placeholder
   would promise a card shape that never arrives. */
.dash-widget--strip .dash-skeleton-row {
    align-items: center;
    padding-block: var(--egk-space-2);
    border-color: transparent;
}

.dash-widget--strip .dash-skeleton--detail,
.dash-widget--strip .dash-skeleton--action {
    display: none;
}

@keyframes dash-shimmer {
    0% { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}

/* Respect the user's motion preference: a dashboard full of shimmering
   placeholders is exactly the kind of thing that triggers vestibular symptoms.

   Everything here is decoration, so it all goes ÃÂ¢ÃÂÃÂ the shimmer, the staggered
   entrance, the critical-status pulse, and every hover lift. Colour and
   elevation still carry the same meaning without a single pixel moving. */
@media (prefers-reduced-motion: reduce) {
    .dash-skeleton {
        animation: none;
        background: rgba(var(--egk-color-primary-rgb), 0.08);
    }

    .dash-grid > *,
    .dash-glance__tile,
    .dash-health-ring,
    .dash-storage-detail__used,
    .dash-meter__fill,
    .dash-status--critical .mud-icon-root,
    .dash-shell .dash-spin .mud-icon-root {
        animation: none;
    }

    .dash-shell *,
    .dash-shell *::before,
    .dash-shell *::after {
        transition-duration: 1ms;
    }

    .dash-widget:hover,
    .dash-action:hover,
    .dash-fav__link:hover,
    button.dash-status:hover {
        transform: none;
    }
}

/* On a touch screen there is no pointer to acknowledge, and :hover latches
   after a tap ÃÂ¢ÃÂÃÂ leaving a card raised until the user touches something else.
   The colour and shadow changes stay; only the movement goes. */
@media (hover: none) {
    .dash-widget:hover,
    .dash-action:hover,
    .dash-fav__link:hover,
    button.dash-status:hover {
        transform: none;
    }
}

.dash-sr-only {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* ---------------------------------------------------- severity counters --- */

.dash-sev-counts {
    display: flex;
    align-items: center;
    gap: var(--egk-space-1);
}

/* These are the headline numbers of the most important card on the page, so they
   are sized to be read rather than squinted at. */
.dash-sev-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-inline-size: 1.6rem;
    block-size: 1.6rem;
    padding-inline: 0.4rem;
    border-radius: var(--egk-radius-full);
    font-size: 0.8125rem;
    font-weight: var(--egk-weight-bold);
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

/* Critical is the one that gets a solid fill. A tinted wash reads as another
   piece of furniture; filled reads as a count of things that are broken. */
.dash-sev-count--critical {
    color: var(--egk-on-brand);
    background: var(--dash-critical);
    box-shadow: 0 2px 8px -2px rgba(var(--dash-critical-rgb), 0.55);
}

.dash-sev-count--warning {
    color: var(--dash-warning);
    background: rgba(var(--dash-warning-rgb), var(--dash-tint-strong));
    box-shadow: inset 0 0 0 1px rgba(var(--dash-warning-rgb), 0.35);
}

.dash-sev-count--attention {
    color: var(--dash-attention);
    background: rgba(var(--dash-attention-rgb), var(--dash-tint-strong));
    box-shadow: inset 0 0 0 1px rgba(var(--dash-attention-rgb), 0.35);
}

/* -------------------------------------------------------- signal list --- */

.dash-signal-list,
.dash-work-list,
.dash-service-rows,
.dash-tenant-list,
.dash-notify-list,
.dash-activity-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--egk-space-2);
    min-inline-size: 0;
}

.dash-signal,
.dash-work,
.dash-service,
.dash-tenant,
.dash-notify,
.dash-activity {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: var(--egk-space-3);
    padding-block: var(--egk-space-3);
    padding-inline: var(--egk-space-3);
    border-radius: var(--egk-radius-md);
    border: 1px solid transparent;
    min-inline-size: 0;
    transition:
        background var(--egk-dur-fast) var(--egk-ease),
        border-color var(--egk-dur-fast) var(--egk-ease),
        box-shadow var(--egk-dur-fast) var(--egk-ease);
}

/* Rows respond to the pointer. Without this a list of exceptions feels like a
   printed report; with it, it feels like something you can act on. */
.dash-signal:hover,
.dash-work:hover,
.dash-service:hover,
.dash-tenant:hover,
.dash-notify:hover,
.dash-activity:hover {
    box-shadow: var(--dash-shadow);
}

/* Severity marks the row, it does not fill it.
   A coloured wash behind every row produced a card of solid pink: with four rows
   tinted there was no neutral left for the colour to contrast against, so nothing
   stood out and the whole thing read as washed out. The signal is now a 3px
   leading bar plus the coloured glyph, against a white row ÃÂ¢ÃÂÃÂ the same amount of
   information in a tenth of the ink, and the text sits on white where it is
   easiest to read. */
.dash-signal--critical,
.dash-signal--warning,
.dash-work--overdue,
.dash-service--critical,
.dash-service--warning,
.dash-tenant--critical,
.dash-tenant--warning,
.dash-notify--critical,
.dash-notify--warning {
    /* The same neutral fill the unstyled rows use, so every row in a list sits on
       one surface and the accent bar is the only thing that differs. */
    background: var(--dash-fill-subtle);
    border-color: var(--dash-border);
}

.dash-signal--critical::before,
.dash-signal--warning::before,
.dash-work--overdue::before,
.dash-service--critical::before,
.dash-service--warning::before,
.dash-tenant--critical::before,
.dash-tenant--warning::before,
.dash-notify--critical::before,
.dash-notify--warning::before {
    content: "";
    position: absolute;
    inset-block: 0;
    inset-inline-start: 0;
    inline-size: 3px;
    border-start-start-radius: var(--egk-radius-md);
    border-end-start-radius: var(--egk-radius-md);
    background: var(--dash-row-accent);
}

.dash-work--overdue,
.dash-service--critical,
.dash-tenant--critical,
.dash-notify--critical {
    --dash-row-accent: var(--dash-critical);
    border-color: rgba(var(--dash-critical-rgb), 0.20);
}

.dash-service--warning,
.dash-tenant--warning,
.dash-notify--warning {
    --dash-row-accent: var(--dash-warning);
}

/* Critical keeps a trace of fill, fading out from the accent bar. It is the one
   row that has to win before the eye has finished travelling down the list, and
   at these strengths it tints without colouring. */
.dash-signal--critical {
    --dash-row-accent: var(--dash-critical);
    background:
        linear-gradient(
            90deg,
            rgba(var(--dash-critical-rgb), 0.055) 0%,
            rgba(var(--dash-critical-rgb), 0.02) 40%,
            transparent 100%),
        var(--dash-fill-subtle);
    border-color: rgba(var(--dash-critical-rgb), 0.20);
}

.dash-signal--warning {
    --dash-row-accent: var(--dash-warning);
}

.dash-signal--critical:hover {
    background:
        linear-gradient(
            90deg,
            rgba(var(--dash-critical-rgb), 0.09) 0%,
            rgba(var(--dash-critical-rgb), 0.035) 40%,
            transparent 100%),
        var(--dash-fill-subtle);
    border-color: rgba(var(--dash-critical-rgb), 0.34);
}

.dash-signal--warning:hover {
    background:
        linear-gradient(
            90deg,
            rgba(var(--dash-warning-rgb), 0.05) 0%,
            transparent 60%),
        var(--dash-fill-subtle);
    border-color: rgba(var(--dash-warning-rgb), 0.28);
}

.dash-signal--attention,
.dash-signal--info {
    background: var(--dash-fill-subtle);
    border-color: var(--dash-border);
}

.dash-signal--attention:hover,
.dash-signal--info:hover {
    background: var(--dash-fill-hover);
    border-color: var(--dash-border-hover);
}

/* A correlated situation gets a brand-gradient edge: it is the dashboard's own
   inference rather than a raw event, and it should not look like one. */
.dash-signal--composite::before {
    content: "";
    position: absolute;
    inset-block: 0;
    inset-inline-start: 0;
    inline-size: 3px;
    border-start-start-radius: var(--egk-radius-md);
    border-end-start-radius: var(--egk-radius-md);
    background: var(--egk-gradient-brand-vivid);
}

.dash-signal__glyph,
.dash-work__glyph {
    margin-block-start: 0.1rem;
    flex-shrink: 0;
}

.dash-signal__body,
.dash-work__body,
.dash-service__body,
.dash-tenant__body,
.dash-notify__body,
.dash-activity__body {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    flex: 1 1 auto;
    min-inline-size: 0;
}

.dash-signal__title,
.dash-work__title,
.dash-tenant__name,
.dash-notify__title,
.dash-activity__title {
    font-size: 0.9375rem;
    font-weight: var(--egk-weight-semibold);
    line-height: var(--egk-lh-snug);
    letter-spacing: -0.005em;
    overflow-wrap: anywhere;
}

.dash-signal__detail,
.dash-work__subtitle,
.dash-service__detail,
.dash-notify__message {
    font-size: 0.8125rem;
    color: var(--egk-color-muted);
    line-height: 1.4;
    overflow-wrap: anywhere;
}

.dash-signal__meta,
.dash-tenant__meta,
.dash-tenant__issues,
.dash-activity__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--egk-space-2);
    font-size: 0.75rem;
    color: var(--egk-color-muted);
    margin-block-start: 0.15rem;
}

.dash-signal__age,
.dash-insight__age,
.dash-notify__age {
    font-size: 0.71875rem;
    color: var(--egk-color-muted);
    white-space: nowrap;
}

.dash-signal__actions {
    display: flex;
    align-items: center;
    gap: var(--egk-space-2);
    flex-shrink: 0;
    /* Aligned with the title rather than the row's centre, so the action sits on
       the same line as the thing it acts on however tall the row grows. */
    align-self: flex-start;
}

/* The row action. Sits on a tinted row, so it needs its own surface to read as a
   control rather than as a rectangle drawn on the tint. Inherited colour gives it
   the body text colour, which passes contrast on every severity fill. */
.dash-shell .dash-signal .mud-button-outlined {
    background: rgba(var(--egk-color-surface-rgb), 0.72);
    /* Derived from the inherited text colour so it holds up in both themes
       without needing a separate dark-mode override. */
    border-color: color-mix(in srgb, currentColor 20%, transparent);
    box-shadow: var(--dash-hairline);
    white-space: nowrap;
}

.dash-shell .dash-signal .mud-button-outlined:hover {
    background: rgba(var(--egk-color-surface-rgb), 0.95);
    border-color: color-mix(in srgb, currentColor 38%, transparent);
    box-shadow: var(--dash-shadow), var(--dash-hairline);
}

/* Caps the readable measure. On a twelve-column card a title was free to stretch
   across the better part of a thousand pixels, which is past the point where a
   line is comfortable to read. The auto margin keeps the actions pinned to the
   trailing edge so they still form one tidy column down the list rather than a
   ragged edge that follows each title's length. */
.dash-signal__body {
    max-inline-size: 78ch;
    margin-inline-end: auto;
}

/* ------------------------------------------------------------- my work --- */

/* Fill and border are set with the other severity rows above, where the shared
   accent-bar treatment lives. */

/* Task rows edit in place, so the whole text block is a real button; the reset
   keeps it visually identical to the static rows around it. */
.dash-work__body--edit {
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    color: inherit;
    text-align: start;
    cursor: pointer;
}

.dash-work__body--edit:hover .dash-work__title {
    color: var(--egk-color-primary);
}

.dash-work__due {
    display: flex;
    align-items: center;
    gap: var(--egk-space-1);
    flex-shrink: 0;
}

.dash-due {
    font-size: 0.75rem;
    color: var(--egk-color-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.dash-due--overdue {
    color: var(--dash-critical);
    font-weight: 650;
}

/* -------------------------------------------------------- status strip --- */

.dash-status-strip {
    display: flex;
    flex-wrap: wrap;
    gap: var(--egk-space-2);
}

.dash-status {
    display: inline-flex;
    align-items: center;
    gap: var(--egk-space-2);
    padding-block: var(--egk-space-2);
    padding-inline: var(--egk-space-3);
    border-radius: var(--egk-radius-full);
    border: 1px solid var(--dash-border);
    background: rgba(var(--egk-color-surface-rgb), 0.72);
    box-shadow: var(--dash-hairline);
    font-size: 0.8125rem;
    transition:
        border-color var(--egk-dur-fast) var(--egk-ease),
        box-shadow var(--egk-dur-fast) var(--egk-ease),
        transform var(--egk-dur-fast) var(--egk-ease);
}

button.dash-status:hover {
    border-color: var(--dash-border-hover);
    box-shadow: var(--dash-shadow), var(--dash-hairline);
    transform: translateY(-1px);
}

button.dash-status:active {
    transform: none;
}

/* Rows that navigate are real buttons, so they need the same reset as the other
   custom controls here: a button does not inherit type or colour by default. */
button.dash-status {
    color: inherit;
    font: inherit;
    font-size: 0.8125rem;
    text-align: start;
    cursor: pointer;
}

.dash-status--critical {
    border-color: rgba(var(--dash-critical-rgb), 0.4);
    background: rgba(var(--dash-critical-rgb), var(--dash-tint));
    box-shadow:
        var(--dash-hairline),
        0 0 0 3px rgba(var(--dash-critical-rgb), 0.08);
}

.dash-status--warning {
    border-color: rgba(var(--dash-warning-rgb), 0.4);
    background: rgba(var(--dash-warning-rgb), var(--dash-tint));
}

.dash-status__name {
    font-weight: var(--egk-weight-medium);
}

/* A failing service earns a slow pulse on its own icon. Scoped to critical
   only: if everything blinks, nothing is urgent. Suppressed under
   prefers-reduced-motion with the rest of the animation below. */
.dash-status--critical .mud-icon-root {
    animation: dash-pulse 2.4s var(--egk-ease) infinite;
}

@keyframes dash-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.45; }
}

.dash-status__latency,
.dash-status__detail,
.dash-service__latency {
    font-size: 0.75rem;
    color: var(--egk-color-muted);
    font-variant-numeric: tabular-nums;
}

.dash-overall {
    display: inline-flex;
    align-items: center;
    gap: var(--egk-space-1);
    font-size: 0.75rem;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.dash-overall--critical { color: var(--dash-critical); }
.dash-overall--warning { color: var(--dash-warning); }
.dash-overall--attention { color: var(--dash-attention); }
.dash-overall--info { color: var(--dash-ok); }

.dash-resource-line {
    display: flex;
    flex-wrap: wrap;
    gap: var(--egk-space-4);
    font-size: 0.75rem;
    color: var(--egk-color-muted);
    padding-block-start: var(--egk-space-2);
    border-block-start: 1px dashed var(--dash-border);
}

.dash-resource-line strong {
    color: var(--egk-color-text);
    font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------------ meters --- */

/* A percentage is a quantity, and a quantity deserves a shape. "Disk 91%" as
   plain text reads the same as "Disk 12%" until you actually parse the digits;
   a bar that is nearly full is understood before it is read. */
.dash-meters {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: var(--egk-space-3) var(--egk-space-4);
    padding-block-start: var(--egk-space-3);
    border-block-start: 1px dashed var(--dash-border);
}

.dash-meter {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    min-inline-size: 0;
}

.dash-meter__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--egk-space-2);
}

.dash-meter__label {
    font-size: 0.6875rem;
    font-weight: var(--egk-weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--egk-color-muted);
}

.dash-meter__value {
    font-size: 0.9375rem;
    font-weight: var(--egk-weight-bold);
    line-height: 1;
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--egk-tracking-tight);
}

.dash-meter__track {
    position: relative;
    block-size: 0.4rem;
    border-radius: var(--egk-radius-full);
    background: rgba(var(--egk-color-primary-rgb), 0.10);
    box-shadow: inset 0 1px 2px rgba(15, 23, 42, 0.10);
    overflow: hidden;
}

/* The fill carries a gradient along its own length, so a full bar looks
   different from a short one beyond simply being longer. */
.dash-meter__fill {
    display: block;
    block-size: 100%;
    border-radius: var(--egk-radius-full);
    background: linear-gradient(
        to right,
        color-mix(in srgb, var(--dash-meter-color) 65%, transparent) 0%,
        var(--dash-meter-color) 100%);
    box-shadow: 0 0 8px -2px var(--dash-meter-color);
    transition: inline-size var(--egk-dur) var(--egk-ease-out);
    animation: dash-grow-inline 700ms var(--egk-ease-out) backwards;
}

.dash-meter--ok {
    --dash-meter-color: var(--dash-ok);
}

.dash-meter--warning {
    --dash-meter-color: var(--dash-warning);
}

.dash-meter--critical {
    --dash-meter-color: var(--dash-critical);
}

.dash-meter--warning .dash-meter__value { color: var(--dash-warning); }
.dash-meter--critical .dash-meter__value { color: var(--dash-critical); }

/* Non-percentage companion figure ÃÂ¢ÃÂÃÂ uptime, counts ÃÂ¢ÃÂÃÂ so it can sit in the same
   row as the meters without pretending to be one. */
.dash-stat {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    min-inline-size: 0;
}

.dash-stat__label {
    font-size: 0.6875rem;
    font-weight: var(--egk-weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--egk-color-muted);
}

.dash-stat__value {
    font-size: 0.9375rem;
    font-weight: var(--egk-weight-bold);
    line-height: 1;
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--egk-tracking-tight);
}

/* Inline variant for list rows, where a full meter block would dominate. */
.dash-meter--inline {
    flex-direction: row;
    align-items: center;
    gap: var(--egk-space-2);
    font-size: 0.75rem;
    color: var(--egk-color-muted);
    /* Label, bar and figure are one unit: wrap as a whole inside the row's
       flex-wrap meta line, never between the pieces. */
    flex-wrap: nowrap;
    white-space: nowrap;
}

.dash-meter--inline .dash-meter__track {
    inline-size: 3.5rem;
    block-size: 0.3rem;
    flex-shrink: 0;
}

.dash-meter--inline .dash-meter__value {
    font-size: 0.75rem;
    font-weight: var(--egk-weight-semibold);
}

.mud-theme-dark .dash-meter__track {
    background: rgba(255, 255, 255, 0.10);
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.4);
}

@media (prefers-reduced-motion: reduce) {
    .dash-meter__fill {
        transition: none;
    }
}

/* --------------------------------------------------------- health summary --- */

/* The platform health card's "glance" band: a ring for the one number that
   matters most, and a compact list for the rest. Sits above the service rows,
   which stay the detail an operator drills into once the ring says something
   is wrong. */

/* Card-scoped container, so the band below can ask how wide *this card* is.
   The shell-level `dash` container cannot answer that: this same card is a
   third of a wide cockpit in one layout and a full-width column in another,
   and the shell measures identically in both. */
.w-platform-health .dash-widget__body {
    container-type: inline-size;
    container-name: dash-card;
}

.dash-health-summary {
    display: flex;
    /* Stacked is the default because it is the only arrangement that is right at
       every width: gauge first, then the metric list across the full card. The
       side-by-side variant is opt-in once the card is provably wide enough for
       both. This used to be decided by flex wrapping instead, which made the
       arrangement depend on how wide the translated labels happened to be ÃÂ¢ÃÂÃÂ the
       same card rendered stacked in English and cramped side-by-side in Arabic. */
    flex-direction: column;
    align-items: center;
    gap: var(--egk-space-4);
    padding-block-end: var(--egk-space-4);
    border-block-end: 1px dashed var(--dash-border);
}

.dash-health-ring-block {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--egk-space-3);
    flex-shrink: 0;
}

/* A donut built from one conic-gradient rather than an SVG or a chart library:
   the percentage is the only moving part, and a CSS custom property is enough
   to drive it. conic-gradient's 0deg already points to twelve o'clock, so no
   rotation is needed to start the fill at the top like a real gauge. */

/* Registered so the sweep below can interpolate it. In engines without
   @property the ring simply paints at its final value ÃÂ¢ÃÂÃÂ no fallback needed. */
@property --dash-ring-pct {
    syntax: "<number>";
    inherits: true;
    initial-value: 0;
}

.dash-health-ring {
    --dash-ring-size: 7rem;
    --dash-ring-thickness: 0.6rem;
    position: relative;
    inline-size: var(--dash-ring-size);
    block-size: var(--dash-ring-size);
    border-radius: 50%;
    background: conic-gradient(
        var(--dash-ring-color) calc(var(--dash-ring-pct) * 1%),
        rgba(var(--egk-color-primary-rgb), 0.12) calc(var(--dash-ring-pct) * 1% + 0.4%));
    /* A quiet halo in the verdict's own colour: the gauge reads as the card's
       light source rather than a flat disc pasted onto it. */
    box-shadow: 0 0 26px -8px color-mix(in srgb, var(--dash-ring-color) 55%, transparent);
    flex-shrink: 0;
    animation: dash-ring-sweep 900ms var(--egk-ease-out) backwards;
}

/* Sweeps from empty to the reported share on arrival. `from` only: the end
   state is whatever the inline style says, so the animation never disagrees
   with the data. */
@keyframes dash-ring-sweep {
    from { --dash-ring-pct: 0; }
}

.dash-health-ring__inner {
    position: absolute;
    inset: var(--dash-ring-thickness);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--dash-fill);
    box-shadow: inset 0 0 0 1px var(--dash-border);
    text-align: center;
}

.dash-health-ring__value {
    font-size: 1.5rem;
    font-weight: var(--egk-weight-bold);
    line-height: 1;
    letter-spacing: var(--egk-tracking-tight);
    font-variant-numeric: tabular-nums;
    color: var(--dash-ring-color);
}

.dash-health-ring__label {
    margin-block-start: 0.2rem;
    font-size: 0.6875rem;
    font-weight: var(--egk-weight-medium);
    color: var(--egk-color-muted);
}

.dash-health-ring--ok { --dash-ring-color: var(--dash-ok); }
.dash-health-ring--warning { --dash-ring-color: var(--dash-warning); }
.dash-health-ring--critical { --dash-ring-color: var(--dash-critical); }
.dash-health-ring--attention { --dash-ring-color: var(--dash-attention); }

.mud-theme-dark .dash-health-ring {
    background: conic-gradient(
        var(--dash-ring-color) calc(var(--dash-ring-pct) * 1%),
        rgba(255, 255, 255, 0.10) calc(var(--dash-ring-pct) * 1% + 0.4%));
}

.dash-health-legend {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--egk-space-2) var(--egk-space-3);
}

.dash-health-legend__item {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.75rem;
    font-weight: var(--egk-weight-medium);
    color: var(--egk-color-muted);
    font-variant-numeric: tabular-nums;
}

.dash-health-legend__dot {
    inline-size: 0.45rem;
    block-size: 0.45rem;
    border-radius: var(--egk-radius-full);
    flex-shrink: 0;
}

.dash-health-legend__dot--ok { background: var(--dash-ok); }
.dash-health-legend__dot--warning { background: var(--dash-warning); }
.dash-health-legend__dot--critical { background: var(--dash-critical); }
.dash-health-legend__dot--attention { background: var(--dash-attention); }

.dash-health-metrics {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-inline-size: 0;
    /* Full card width in the stacked default; the row variant releases this. */
    align-self: stretch;
}

.dash-health-metric {
    display: flex;
    align-items: center;
    gap: var(--egk-space-3);
    padding-block: 0.55rem;
    border-block-end: 1px solid var(--dash-border);
    font-size: 0.8125rem;
}

.dash-health-metric:last-child {
    border-block-end: 0;
    padding-block-end: 0;
}

.dash-health-metric:first-child {
    padding-block-start: 0;
}

/* A small tinted tile per metric type ÃÂ¢ÃÂÃÂ decorative, not a status colour, which
   is what the trailing dot is for. It is the difference between a list of grey
   rows and one that looks considered, at the cost of nothing but a background. */
.dash-health-metric__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 1.75rem;
    block-size: 1.75rem;
    border-radius: var(--dash-radius-sm);
    flex-shrink: 0;
}

.dash-health-metric__icon--secondary {
    color: var(--egk-color-secondary);
    background: rgba(var(--egk-color-secondary-rgb), 0.14);
}

.dash-health-metric__icon--warning {
    color: var(--dash-warning);
    background: rgba(var(--dash-warning-rgb), 0.14);
}

.dash-health-metric__icon--critical {
    color: var(--dash-critical);
    background: rgba(var(--dash-critical-rgb), 0.14);
}

.dash-health-metric__icon--info {
    color: var(--dash-attention);
    background: rgba(var(--dash-attention-rgb), 0.14);
}

.dash-health-metric__icon--ok {
    color: var(--dash-ok);
    background: rgba(var(--dash-ok-rgb), 0.14);
}

.dash-health-metric__label {
    flex: 1 1 auto;
    min-inline-size: 0;
    color: var(--egk-color-muted);
    font-weight: var(--egk-weight-medium);
}

.dash-health-metric__value {
    font-weight: var(--egk-weight-semibold);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.dash-health-metric__dot {
    inline-size: 0.4rem;
    block-size: 0.4rem;
    border-radius: var(--egk-radius-full);
    flex-shrink: 0;
}

.dash-health-metric__dot--ok { background: var(--dash-ok); }
.dash-health-metric__dot--warning { background: var(--dash-warning); }
.dash-health-metric__dot--critical { background: var(--dash-critical); }

/* The storage row borrows the shared inline meter rather than a bespoke bar, so
   fixing or restyling the meter once fixes it everywhere it appears. It just
   needs room to grow within the row instead of the meter's usual fixed width. */
.dash-health-metric__meter {
    flex: 1 1 auto;
    min-inline-size: 0;
}

.dash-health-metric__meter.dash-meter--inline .dash-meter__track {
    flex: 1 1 auto;
    inline-size: auto;
}

/* Storage is the only health metric with a composition row. It deliberately
   occupies the same metric column as the simple label/value rows, but adds the
   quota badge, category facts and a segmented physical-capacity bar requested
   by platform operators. */
.dash-storage-detail {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    flex: 1 1 auto;
    min-inline-size: 0;
}

.dash-storage-detail__head,
.dash-storage-detail__facts {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--egk-space-2);
    min-inline-size: 0;
}

.dash-storage-detail__quota {
    display: inline-flex;
    align-items: center;
    padding-block: 0.15rem;
    padding-inline: 0.45rem;
    border: 1px solid rgba(var(--dash-ok-rgb), 0.24);
    border-radius: var(--dash-radius-sm);
    background: rgba(var(--dash-ok-rgb), 0.10);
    color: var(--dash-ok);
    font-size: 0.6875rem;
    font-weight: var(--egk-weight-bold);
    line-height: 1.2;
    white-space: nowrap;
}

.dash-storage-detail__policy {
    color: var(--egk-color-muted);
    font-size: 0.71875rem;
    white-space: nowrap;
}

.dash-storage-detail__facts {
    color: var(--egk-color-muted);
    font-size: 0.71875rem;
    line-height: 1.25;
}

.dash-storage-detail__facts strong {
    display: inline-flex;
    align-items: center;
    color: var(--egk-color-text);
    font-weight: var(--egk-weight-medium);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.dash-storage-detail__facts > span {
    opacity: 0.45;
}

.dash-storage-detail__bar {
    display: flex;
    inline-size: 100%;
    block-size: 0.5rem;
    border-radius: var(--egk-radius-full);
    background: rgba(var(--egk-color-primary-rgb), 0.08);
    box-shadow: inset 0 1px 2px rgba(15, 23, 42, 0.10);
    overflow: hidden;
}

.dash-storage-detail__segment {
    display: block;
    block-size: 100%;
    /* Zero-byte categories never render, so every segment here holds real
       bytes and earns a visible floor: 1 GB of tenant data next to 480 GB of
       system files is proportionally sub-pixel, yet "your data exists and is
       this colour" is exactly what the bar is for. Proportion still governs
       everything above the floor. */
    min-inline-size: 0.5rem;
    flex: var(--dash-segment-weight, 0) 1 0;
}

/* Adjacent tones need a seam or a mostly-one-colour bar reads as a gradient
   artifact instead of two categories meeting. */
.dash-storage-detail__segment + .dash-storage-detail__segment {
    border-inline-start: 1px solid rgba(var(--egk-color-surface-rgb), 0.9);
}

/* The whole group occupies exactly the host-used percentage. The categories
   then divide that occupied part proportionally, so the coloured bar cannot
   claim more physical capacity than the disk sampler reports even when a
   persisted tenant counter points at external storage. */
.dash-storage-detail__used {
    display: flex;
    block-size: 100%;
    min-inline-size: 0;
    overflow: hidden;
    animation: dash-grow-inline 700ms var(--egk-ease-out) backwards;
}

/* `from` only, like the ring sweep: the destination width is the inline style,
   so the settle can never land on a different figure than the data. Animating
   inline-size rather than a transform keeps it honest under RTL for free. */
@keyframes dash-grow-inline {
    from { inline-size: 0; }
}

/*
   One tone per storage category, shared by the bar segment and its legend
   swatch. Tenant data is the figure a reader owns, so it takes the brand
   colour; backups are the reassuring green of "protected"; system is a
   deliberate neutral ÃÂ¢ÃÂÃÂ bulk the operator cannot act on from here.
*/
.dash-storage-detail__segment--tenant,
.dash-storage-detail__swatch--tenant {
    background: var(--egk-color-primary);
}

.dash-storage-detail__segment--backup,
.dash-storage-detail__swatch--backup {
    background: var(--dash-ok);
}

.dash-storage-detail__segment--system,
.dash-storage-detail__swatch--system {
    background: color-mix(in srgb, var(--egk-color-muted) 60%, transparent);
}

.dash-storage-detail__swatch {
    display: inline-block;
    inline-size: 0.5rem;
    block-size: 0.5rem;
    border-radius: 2px;
    margin-inline-end: 0.3rem;
    vertical-align: baseline;
    flex: none;
}

.mud-theme-dark .dash-storage-detail__bar {
    background: rgba(255, 255, 255, 0.10);
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.4);
}

.mud-theme-dark .dash-storage-detail__segment + .dash-storage-detail__segment {
    border-inline-start-color: rgba(0, 0, 0, 0.55);
}

/* Section label between the glance band and the operational row list, the same
   quiet caps treatment as the wave labels above the grid, but scoped to sit
   inside a single card instead of over a whole row of them. */
.dash-widget__subhead {
    margin: 0;
    padding-block-start: var(--egk-space-1);
    font-size: 0.6875rem;
    font-weight: var(--egk-weight-bold);
    text-transform: uppercase;
    letter-spacing: var(--egk-tracking-caps);
    color: var(--egk-color-muted);
}

/* Gauge beside the metric list, but only once this card can seat both without
   squeezing the storage row ÃÂ¢ÃÂÃÂ its three-part legend needs the width to stay on
   one line. Narrower than this and the stacked default wins, which is what
   keeps the card identical across languages regardless of label lengths. */
@container dash-card (min-width: 32rem) {
    .dash-health-summary {
        flex-direction: row;
        gap: var(--egk-space-5);
    }

    .dash-health-metrics {
        align-self: auto;
    }
}

/* --------------------------------------------------------- service rows --- */

.dash-service {
    align-items: center;
    border: 1px solid var(--dash-border);
    background: rgba(var(--egk-color-surface-rgb), 0.4);
}

/* Severity fills and borders for these rows are set with the shared accent-bar
   treatment above. */

.dash-service__name {
    font-size: 0.875rem;
    font-weight: 550;
}

.dash-service__trailing {
    display: flex;
    align-items: center;
    gap: var(--egk-space-2);
    flex-shrink: 0;
}

.dash-service__status {
    font-size: 0.71875rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--egk-color-muted);
}

/* --------------------------------------------------------------- tenants --- */

.dash-tenant {
    align-items: center;
    border: 1px solid var(--dash-border);
}

/* Severity fills and borders for these rows are set with the shared accent-bar
   treatment above. */

.dash-tenant__status {
    font-size: 0.6875rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--egk-color-muted);
    margin-inline-start: var(--egk-space-2);
}

.dash-chip--issue {
    max-inline-size: none;
    color: var(--egk-color-text);
}

/* ------------------------------------------------------------------ KPIs --- */

.dash-kpi-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
    gap: var(--egk-space-3);
}

.dash-kpi {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding-block: var(--egk-space-3);
    padding-inline: var(--egk-space-3);
    border-radius: var(--egk-radius-md);
    border: 1px solid var(--dash-border);
    background: linear-gradient(
        160deg,
        rgba(var(--egk-color-surface-rgb), 0.9) 0%,
        rgba(var(--egk-color-primary-rgb), 0.045) 100%);
    box-shadow: var(--dash-hairline);
    overflow: hidden;
    transition:
        border-color var(--egk-dur-fast) var(--egk-ease),
        box-shadow var(--egk-dur-fast) var(--egk-ease);
}

.dash-kpi:hover {
    border-color: var(--dash-border-hover);
    box-shadow: var(--dash-shadow), var(--dash-hairline);
}

/* A number is the most-read element on the card, so it gets the display
   treatment: larger, tighter, tabular so digits do not jitter on refresh. */
.dash-kpi__value {
    font-size: 1.75rem;
    font-weight: var(--egk-weight-bold);
    line-height: var(--egk-lh-tight);
    letter-spacing: var(--egk-tracking-tight);
    font-variant-numeric: tabular-nums;
}

.dash-kpi__label {
    font-size: 0.71875rem;
    font-weight: var(--egk-weight-medium);
    letter-spacing: 0.02em;
    color: var(--egk-color-muted);
}

/* Optional corner glyph: gives a tile an identity without occupying a row.
   Kept faint so the number stays the loudest element on the card. */
.dash-kpi__glyph {
    position: absolute;
    inset-block-start: var(--egk-space-2);
    inset-inline-end: var(--egk-space-2);
    color: var(--egk-color-muted);
    opacity: 0.45;
}

.dash-kpi--warning .dash-kpi__glyph {
    color: var(--dash-warning);
    opacity: 0.75;
}

.dash-kpi--critical .dash-kpi__glyph {
    color: var(--dash-critical);
    opacity: 0.75;
}

/* The coloured value and the border already say "this one is bad" twice. A full
   tinted fill on top of that is a third telling of the same fact, and across a
   row of tiles it turns the KPI band into a block of colour. */
.dash-kpi--critical {
    border-color: rgba(var(--dash-critical-rgb), 0.32);
    background: linear-gradient(
        160deg,
        rgba(var(--dash-critical-rgb), 0.06) 0%,
        transparent 70%),
        var(--dash-fill-subtle);
}

.dash-kpi--critical .dash-kpi__value { color: var(--dash-critical); }

.dash-kpi--warning {
    border-color: rgba(var(--dash-warning-rgb), 0.28);
    background: linear-gradient(
        160deg,
        rgba(var(--dash-warning-rgb), 0.05) 0%,
        transparent 70%),
        var(--dash-fill-subtle);
}

.dash-kpi--warning .dash-kpi__value { color: var(--dash-warning); }

.dash-kpi-footnote {
    display: flex;
    flex-wrap: wrap;
    gap: var(--egk-space-3);
    font-size: 0.75rem;
    color: var(--egk-color-muted);
}

.dash-kpi-footnote > span {
    display: inline-flex;
    align-items: center;
    gap: var(--egk-space-1);
}

.dash-kpi-footnote__strong {
    color: var(--dash-critical);
    font-weight: 600;
}

/* ----------------------------------------------------------- plan catalog --- */

/* The sellable lineup at the foot of the subscription card: label, count, then
   the plan names clipped to one quiet line. The whole strip is one button into
   plan administration, mirroring the queued-campaigns strip's grammar. */
.dash-plan-catalog {
    display: flex;
    align-items: center;
    gap: var(--egk-space-2);
    inline-size: 100%;
    min-inline-size: 0;
    margin-block-start: var(--egk-space-3);
    padding-block: var(--egk-space-2);
    padding-inline: var(--egk-space-3);
    border: 1px solid var(--dash-border);
    border-radius: var(--egk-radius-md);
    background: var(--dash-fill-subtle);
    font: inherit;
    font-size: 0.75rem;
    color: var(--egk-color-muted);
    text-align: start;
    cursor: pointer;
    transition:
        border-color var(--egk-dur-fast) var(--egk-ease),
        box-shadow var(--egk-dur-fast) var(--egk-ease);
}

.dash-plan-catalog:hover {
    border-color: var(--dash-border-hover);
    box-shadow: var(--dash-hairline);
}

.dash-plan-catalog__label {
    font-size: 0.65625rem;
    font-weight: var(--egk-weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    white-space: nowrap;
}

.dash-plan-catalog__count {
    font-weight: var(--egk-weight-bold);
    color: var(--egk-color-text);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.dash-plan-catalog__names {
    flex: 1;
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Overflow count for the plan lineup. Never shrinks: "+3 more" losing its own
   digits to an ellipsis would defeat the point of counting. */
.dash-plan-catalog__more {
    flex-shrink: 0;
    white-space: nowrap;
    font-weight: var(--egk-weight-medium);
    color: var(--egk-color-primary);
}

.dash-plan-catalog__arrow {
    color: var(--egk-color-primary);
    flex-shrink: 0;
}

[dir="rtl"] .dash-plan-catalog__arrow {
    transform: scaleX(-1);
}

/* ---------------------------------------------------------- communications --- */

/* Four centered stat tiles: icon over value over label, the classic
   mail-overview silhouette. Color lives in the icon only so the counts stay
   calm; zero tiles are muted by .dash-zero. */
.dash-comms__tiles {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--egk-space-2);
}

.dash-comms__tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.1875rem;
    padding-block: var(--egk-space-2);
    padding-inline: var(--egk-space-1);
    border: 1px solid var(--dash-border);
    border-radius: var(--egk-radius-md);
    background: var(--dash-fill-subtle);
    text-align: center;
    min-inline-size: 0;
}

.dash-comms__tile--unread > .mud-icon-root { color: var(--dash-warning); }
.dash-comms__tile--sent > .mud-icon-root { color: var(--dash-ok); }
.dash-comms__tile--drafts > .mud-icon-root { color: var(--egk-color-info); }
.dash-comms__tile--failed > .mud-icon-root { color: var(--dash-critical); }

.dash-comms__tile-value {
    font-size: 1.0625rem;
    font-weight: var(--egk-weight-semibold);
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.dash-comms__tile-label {
    font-size: 0.625rem;
    font-weight: var(--egk-weight-medium);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--egk-color-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-inline-size: 100%;
}

/* Mailbox-less state: a quiet actionable prompt under the tiles. Inbox and
   Compose live in the card header, so this line is the section's only extra
   row and only when there is genuinely nothing connected. */
.dash-comms__connect-hint {
    margin-block-start: var(--egk-space-2);
    display: inline-flex;
    align-items: center;
    gap: var(--egk-space-1);
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    font-size: 0.78125rem;
    color: var(--egk-color-muted);
    cursor: pointer;
    text-align: start;
}

.dash-comms__connect-hint:hover {
    color: var(--egk-color-primary);
}

.dash-comms__news {
    display: flex;
    flex-direction: column;
    gap: var(--egk-space-2);
    margin-block-start: var(--egk-space-3);
    padding-block-start: var(--egk-space-3);
    border-block-start: 1px solid var(--dash-border);
}

.dash-comms__news-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--egk-space-2);
}

.dash-comms__news-title {
    display: inline-flex;
    align-items: center;
    gap: var(--egk-space-2);
    font-size: 0.8125rem;
    font-weight: var(--egk-weight-medium);
    min-inline-size: 0;
}

.dash-comms__news-name {
    display: flex;
    flex-direction: column;
    line-height: 1.25;
    min-inline-size: 0;
}

.dash-comms__news-name > small {
    font-size: 0.6875rem;
    font-weight: var(--egk-weight-regular);
    color: var(--egk-color-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dash-comms__news-actions {
    display: inline-flex;
    align-items: center;
    gap: var(--egk-space-2);
    flex-shrink: 0;
}

/* Scheduled-campaign count as a compact pill badge beside the CTA. */
.dash-comms__sched {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding-block: 0.125rem;
    padding-inline: 0.5rem;
    border: 1px solid color-mix(in srgb, var(--egk-color-info) 35%, transparent);
    border-radius: 999px;
    background: color-mix(in srgb, var(--egk-color-info) 12%, transparent);
    color: var(--egk-color-info);
    font: inherit;
    font-size: 0.75rem;
    font-weight: var(--egk-weight-semibold);
    font-variant-numeric: tabular-nums;
    cursor: pointer;
    transition: background var(--egk-dur-fast) var(--egk-ease);
}

.dash-comms__sched:hover {
    background: color-mix(in srgb, var(--egk-color-info) 20%, transparent);
}

/* Subscribers headline row: count first, engagement share at the reading end. */
.dash-comms__subs {
    display: flex;
    align-items: center;
    gap: var(--egk-space-1);
    font-size: 0.8125rem;
}

.dash-comms__subs > .mud-icon-root {
    color: var(--egk-color-muted);
}

.dash-comms__subs-count {
    font-weight: var(--egk-weight-semibold);
    font-variant-numeric: tabular-nums;
}

.dash-comms__subs-active {
    margin-inline-start: auto;
    font-size: 0.71875rem;
    font-weight: var(--egk-weight-medium);
    color: var(--dash-ok);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Open-rate / bounce chips: outlined stat boxes, alert tint when bounce is
   worth a look. */
.dash-comms__rates {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--egk-space-2);
}

.dash-comms__rate {
    display: flex;
    align-items: center;
    gap: var(--egk-space-2);
    padding-block: var(--egk-space-2);
    padding-inline: var(--egk-space-3);
    border: 1px solid var(--dash-border);
    border-radius: var(--egk-radius-md);
    background: var(--dash-fill-subtle);
    min-inline-size: 0;
}

.dash-comms__rate > .mud-icon-root {
    color: var(--dash-ok);
}

.dash-comms__rate-value {
    font-size: 0.9375rem;
    font-weight: var(--egk-weight-semibold);
    font-variant-numeric: tabular-nums;
}

.dash-comms__rate-label {
    font-size: 0.625rem;
    font-weight: var(--egk-weight-medium);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--egk-color-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dash-comms__rate--alert {
    border-color: color-mix(in srgb, var(--dash-critical) 35%, transparent);
    background: rgba(var(--dash-critical-rgb), 0.06);
}

.dash-comms__rate--alert > .mud-icon-root,
.dash-comms__rate--alert .dash-comms__rate-value {
    color: var(--dash-critical);
}

.dash-comms__bar {
    block-size: 0.375rem;
    border-radius: 999px;
    background: rgba(var(--dash-ok-rgb), 0.14);
    overflow: hidden;
}

.dash-comms__bar-fill {
    block-size: 100%;
    border-radius: inherit;
    background: var(--dash-ok);
    transition: inline-size var(--egk-dur-fast) var(--egk-ease);
}

.dash-comms__queued {
    display: flex;
    align-items: center;
    gap: var(--egk-space-2);
    padding-block: var(--egk-space-2);
    padding-inline: var(--egk-space-3);
    border: 1px solid var(--dash-border);
    border-radius: var(--egk-radius-md);
    background: var(--dash-fill-subtle);
    font: inherit;
    font-size: 0.8125rem;
    color: inherit;
    text-align: start;
    cursor: pointer;
    transition:
        border-color var(--egk-dur-fast) var(--egk-ease),
        box-shadow var(--egk-dur-fast) var(--egk-ease);
}

.dash-comms__queued:hover {
    border-color: var(--dash-border-hover);
    box-shadow: var(--dash-hairline);
}

.dash-comms__queued > span:first-of-type {
    flex: 1;
}

.dash-comms__queued-cta {
    display: inline-flex;
    align-items: center;
    gap: var(--egk-space-1);
    font-weight: var(--egk-weight-medium);
    color: var(--egk-color-primary);
    white-space: nowrap;
}

/* RTL: the forward arrow must point with the reading direction. */
[dir="rtl"] .dash-comms__queued-cta .mud-icon-root {
    transform: scaleX(-1);
}

/* --------------------------------------------------------------- insights --- */

.dash-insight-list {
    display: flex;
    flex-direction: column;
    gap: var(--egk-space-3);
}

.dash-insight {
    position: relative;
    border: 1px solid var(--dash-border);
    border-radius: var(--egk-radius-md);
    padding: var(--egk-space-4);
    display: flex;
    flex-direction: column;
    gap: var(--egk-space-2);
    background: linear-gradient(
        150deg,
        rgba(var(--egk-color-primary-rgb), 0.05) 0%,
        rgba(var(--egk-color-surface-rgb), 0.6) 55%);
    box-shadow: var(--dash-hairline);
    overflow: hidden;
    transition:
        border-color var(--egk-dur-fast) var(--egk-ease),
        box-shadow var(--egk-dur-fast) var(--egk-ease);
}

.dash-insight:hover {
    border-color: var(--dash-border-hover);
    box-shadow: var(--dash-shadow), var(--dash-hairline);
}

/* Accent bars as pseudo-elements rather than borders, so the gradient fade and
   the rounded corner survive together. */
.dash-insight[class*="dash-insight--"]::before {
    content: "";
    position: absolute;
    inset-block: 0;
    inset-inline-start: 0;
    inline-size: 3px;
    background: linear-gradient(
        to bottom,
        var(--dash-accent-color, var(--egk-color-primary)) 0%,
        color-mix(in srgb, var(--dash-accent-color, var(--egk-color-primary)) 40%, transparent) 100%);
}

/* Same restraint as the signal rows: the bar carries the severity, the surface
   stays close to neutral. An insight is several lines of prose, and prose on a
   coloured panel is harder to read for no gain in urgency. */
.dash-insight--critical {
    --dash-accent-color: var(--dash-critical);
    border-color: rgba(var(--dash-critical-rgb), 0.22);
    background: linear-gradient(
        100deg,
        rgba(var(--dash-critical-rgb), 0.05) 0%,
        transparent 55%),
        var(--dash-fill-subtle);
}

.dash-insight--warning {
    --dash-accent-color: var(--dash-warning);
    border-color: rgba(var(--dash-warning-rgb), 0.20);
    background: linear-gradient(
        100deg,
        rgba(var(--dash-warning-rgb), 0.04) 0%,
        transparent 55%),
        var(--dash-fill-subtle);
}

.dash-insight--attention {
    --dash-accent-color: var(--dash-attention);
}

.dash-insight__head {
    display: flex;
    align-items: center;
    gap: var(--egk-space-2);
}

.dash-insight__headline {
    flex: 1 1 auto;
    min-inline-size: 0;
    font-size: 0.9375rem;
    font-weight: var(--egk-weight-semibold);
    line-height: var(--egk-lh-snug);
    letter-spacing: -0.005em;
}

/* The recommendation is the deliverable of an insight, so it renders as a
   permanent, quietly branded strip ÃÂ¢ÃÂÃÂ advice, not another alarm. Severity stays
   on the accent bar; this line keeps the primary tone in every variant. */
.dash-insight__reco {
    display: flex;
    align-items: flex-start;
    gap: var(--egk-space-2);
    padding-block: 0.45rem;
    padding-inline: var(--egk-space-2);
    border-radius: var(--dash-radius-sm);
    background: rgba(var(--egk-color-primary-rgb), 0.06);
    box-shadow: inset 0 0 0 1px rgba(var(--egk-color-primary-rgb), 0.10);
    font-size: 0.8125rem;
    line-height: var(--egk-lh-snug);
}

.dash-insight__reco .mud-icon-root {
    color: var(--egk-color-primary);
    flex-shrink: 0;
    margin-block-start: 0.05rem;
}

.dash-insight__detail {
    display: flex;
    flex-direction: column;
    gap: var(--egk-space-2);
    padding-block-start: var(--egk-space-2);
    font-size: 0.8125rem;
}

.dash-insight__row {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.dash-insight__label {
    font-size: 0.625rem;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    color: var(--egk-color-muted);
    font-weight: var(--egk-weight-bold);
}

.dash-insight__detail {
    border-block-start: 1px dashed var(--dash-border);
}

.dash-insight__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--egk-space-2);
}

/* ---------------------------------------------------------- notifications --- */

.dash-notify--read {
    opacity: 0.62;
}

/* Severity fills for these rows are set with the shared accent-bar treatment
   above. */

/* --------------------------------------------------------------- activity --- */

.dash-activity-list {
    counter-reset: none;
}

.dash-activity {
    align-items: center;
    padding-block: var(--egk-space-1);
}

.dash-activity__actor {
    font-weight: var(--egk-weight-semibold);
    color: var(--egk-color-text);
}

/* ------------------------------------------------------------------ avatar --- */

/* Identity disc. The hue arrives as a custom property from the component, which
   derives it from a stable hash of the actor's name ÃÂ¢ÃÂÃÂ so the colour is personal
   and consistent without anyone maintaining a palette per user.

   Fixed saturation and lightness keep every generated colour inside a range
   that stays legible against white text and does not clash with the brand. */
.dash-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 1.85rem;
    block-size: 1.85rem;
    flex-shrink: 0;
    border-radius: var(--egk-radius-full);
    background: linear-gradient(
        140deg,
        hsl(var(--dash-avatar-hue, 210) 62% 52%) 0%,
        hsl(calc(var(--dash-avatar-hue, 210) + 24) 58% 42%) 100%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.25),
        0 2px 6px -2px rgba(15, 23, 42, 0.35);
    color: #fff;
    font-size: 0.75rem;
    font-weight: var(--egk-weight-bold);
    line-height: 1;
    /* Initials are glyphs, not language: never let them wrap or be selected. */
    user-select: none;
}

/* ---------------------------------------------------------- quick actions --- */

.dash-action-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
    gap: var(--egk-space-2);
}

.dash-action {
    display: flex;
    align-items: center;
    gap: var(--egk-space-3);
    padding-block: var(--egk-space-3);
    padding-inline: var(--egk-space-3);
    border: 1px solid var(--dash-border);
    border-radius: var(--egk-radius-md);
    background: var(--dash-fill-subtle);
    box-shadow: var(--dash-hairline);
    color: inherit;
    font: inherit;
    font-size: 0.8125rem;
    font-weight: var(--egk-weight-medium);
    text-align: start;
    cursor: pointer;
    transition:
        border-color var(--egk-dur-fast) var(--egk-ease),
        background var(--egk-dur-fast) var(--egk-ease),
        box-shadow var(--egk-dur-fast) var(--egk-ease),
        transform var(--egk-dur-fast) var(--egk-ease);
}

.dash-action:hover {
    border-color: var(--dash-border-hover);
    background: var(--dash-fill-hover);
    box-shadow: var(--dash-shadow), var(--dash-hairline);
    transform: translateY(-1px);
}

/* Presses down rather than just changing colour. Cheap, and it is the
   difference between a link and a control. */
.dash-action:active {
    transform: translateY(0);
    box-shadow: var(--dash-hairline);
}

.dash-action__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 2rem;
    block-size: 2rem;
    border-radius: var(--dash-radius-sm);
    background: linear-gradient(
        140deg,
        rgba(var(--egk-color-primary-rgb), 0.18),
        rgba(var(--egk-color-secondary-rgb), 0.10));
    box-shadow: inset 0 0 0 1px rgba(var(--egk-color-primary-rgb), 0.14);
    color: var(--egk-color-primary);
    flex-shrink: 0;
    transition: background var(--egk-dur-fast) var(--egk-ease);
}

/* The tile fills with brand colour on hover, which reads as the action arming
   itself. */
.dash-action:hover .dash-action__icon {
    background: var(--egk-gradient-brand-vivid);
    box-shadow: 0 4px 12px -4px rgba(var(--egk-color-primary-rgb), 0.55);
    color: var(--egk-on-brand);
}

.dash-action__label {
    flex: 1 1 auto;
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* -------------------------------------------------------------- favorites --- */

.dash-fav-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(4.5rem, 1fr));
    gap: var(--egk-space-2);
}

.dash-fav {
    position: relative;
}

.dash-fav__link {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--egk-space-1);
    inline-size: 100%;
    padding-block: var(--egk-space-3);
    padding-inline: var(--egk-space-1);
    border: 1px solid transparent;
    border-radius: var(--egk-radius-md);
    background: transparent;
    color: inherit;
    font: inherit;
    cursor: pointer;
    transition:
        background var(--egk-dur-fast) var(--egk-ease),
        border-color var(--egk-dur-fast) var(--egk-ease),
        transform var(--egk-dur-fast) var(--egk-ease);
}

.dash-fav__link:hover {
    background: var(--dash-fill-hover);
    border-color: var(--dash-border-hover);
    transform: translateY(-1px);
}

.dash-fav__link:hover .mud-icon-root {
    color: var(--egk-color-primary);
}

.dash-fav__label {
    font-size: 0.6875rem;
    text-align: center;
    max-inline-size: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dash-fav--editing .dash-fav__link {
    border-style: dashed;
    border-color: var(--dash-border);
}

.dash-fav__remove {
    position: absolute;
    inset-block-start: -0.25rem;
    inset-inline-end: -0.25rem;
    z-index: 2;
}

/* ------------------------------------------------------- command palette --- */

/* The palette is the most "product" moment in the whole app ÃÂ¢ÃÂÃÂ it is what people
   demo ÃÂ¢ÃÂÃÂ so it gets the largest radius, the deepest shadow and a brand edge. */
.dash-palette .mud-dialog {
    /* Explicitly positioned so the brand bar below anchors to the dialog and
       not to whatever ancestor MudBlazor happens to have positioned. */
    position: relative;
    border-radius: var(--egk-radius-xl);
    overflow: hidden;
    border: 1px solid var(--dash-border);
    box-shadow: var(--egk-shadow-xl), var(--dash-hairline);
}

.dash-palette .mud-dialog::before {
    content: "";
    position: absolute;
    inset-block-start: 0;
    inset-inline: 0;
    block-size: 2px;
    background: var(--egk-gradient-brand);
    z-index: 1;
}

.dash-palette__search {
    display: flex;
    align-items: center;
    gap: var(--egk-space-3);
    inline-size: 100%;
}

.dash-palette__input {
    flex: 1 1 auto;
    min-inline-size: 0;
    border: 0;
    background: transparent;
    color: var(--egk-color-text);
    font: inherit;
    font-size: 1.0625rem;
    font-weight: var(--egk-weight-medium);
    padding-block: var(--egk-space-3);
}

.dash-palette__input::placeholder {
    color: var(--egk-color-muted);
    font-weight: 400;
}

.dash-palette__input:focus {
    outline: none;
}

.dash-palette__list {
    list-style: none;
    margin: 0;
    padding: var(--egk-space-2);
    max-block-size: 55vh;
    overflow-y: auto;
    /* Thin themed scrollbar. The default chrome scrollbar inside a rounded
       floating panel is the detail that gives away an unstyled component. */
    scrollbar-width: thin;
    scrollbar-color: rgba(var(--egk-color-primary-rgb), 0.35) transparent;
}

.dash-palette__list::-webkit-scrollbar {
    inline-size: 8px;
}

.dash-palette__list::-webkit-scrollbar-thumb {
    background: rgba(var(--egk-color-primary-rgb), 0.28);
    border-radius: var(--egk-radius-full);
}

.dash-palette__list::-webkit-scrollbar-thumb:hover {
    background: rgba(var(--egk-color-primary-rgb), 0.45);
}

.dash-palette__group {
    font-size: 0.625rem;
    font-weight: var(--egk-weight-bold);
    text-transform: uppercase;
    letter-spacing: 0.09em;
    color: var(--egk-color-muted);
    padding-block: var(--egk-space-3) var(--egk-space-1);
    padding-inline: var(--egk-space-3);
    position: sticky;
    inset-block-start: 0;
    z-index: 1;
    background: var(--dash-surface);
}

.dash-palette__item {
    display: flex;
    align-items: center;
    gap: var(--egk-space-3);
    padding-block: var(--egk-space-3);
    padding-inline: var(--egk-space-3);
    border-radius: var(--egk-radius-md);
    cursor: pointer;
    border: 1px solid transparent;
    transition:
        background var(--egk-dur-fast) var(--egk-ease),
        border-color var(--egk-dur-fast) var(--egk-ease);
}

.dash-palette__item:hover {
    background: var(--dash-fill-hover);
}

/* Keyboard selection has to out-shout hover, because in a palette the pointer
   and the arrow keys are often both in play. */
.dash-palette__item--active {
    background: linear-gradient(
        135deg,
        rgba(var(--egk-color-primary-rgb), var(--dash-tint-strong)) 0%,
        rgba(var(--egk-color-secondary-rgb), var(--dash-tint)) 100%);
    border-color: rgba(var(--egk-color-primary-rgb), 0.28);
}

.dash-palette__item--active .dash-palette__label {
    font-weight: var(--egk-weight-semibold);
}

.dash-palette__label {
    flex: 1 1 auto;
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dash-palette__kind {
    color: var(--egk-color-muted);
    opacity: 0.6;
}

/* ------------------------------------------------- mudblazor harmonization --- */

/* The row-level icon buttons are stock MudBlazor, which is fine in isolation but
   reads as a different product next to the surfaces above. These rules keep them
   in the same visual language without touching the component library globally ÃÂ¢ÃÂÃÂ
   everything here is scoped to .dash-shell. */

/* Recessed at rest, full strength on hover or focus. Not hidden: a control the
   user cannot see is a control they do not know exists, so 0.55 rather than 0.
   Row hover raises every button in that row, which is how the affordance is
   discovered. */
.dash-shell .dash-signal .mud-icon-button,
.dash-shell .dash-work .mud-icon-button,
.dash-shell .dash-service .mud-icon-button,
.dash-shell .dash-tenant .mud-icon-button,
.dash-shell .dash-notify .mud-icon-button,
.dash-shell .dash-activity .mud-icon-button {
    opacity: 0.55;
    transition:
        opacity var(--egk-dur-fast) var(--egk-ease),
        background var(--egk-dur-fast) var(--egk-ease),
        transform var(--egk-dur-fast) var(--egk-ease);
}

.dash-shell .dash-signal:hover .mud-icon-button,
.dash-shell .dash-work:hover .mud-icon-button,
.dash-shell .dash-service:hover .mud-icon-button,
.dash-shell .dash-tenant:hover .mud-icon-button,
.dash-shell .dash-notify:hover .mud-icon-button,
.dash-shell .dash-activity:hover .mud-icon-button,
.dash-shell .dash-signal .mud-icon-button:focus-visible,
.dash-shell .dash-work .mud-icon-button:focus-visible,
.dash-shell .dash-service .mud-icon-button:focus-visible,
.dash-shell .dash-tenant .mud-icon-button:focus-visible,
.dash-shell .dash-notify .mud-icon-button:focus-visible,
.dash-shell .dash-activity .mud-icon-button:focus-visible {
    opacity: 1;
}

/* Touch has no hover, so the resting state is the only state. */
@media (hover: none) {
    .dash-shell .dash-signal .mud-icon-button,
    .dash-shell .dash-work .mud-icon-button,
    .dash-shell .dash-service .mud-icon-button,
    .dash-shell .dash-tenant .mud-icon-button,
    .dash-shell .dash-notify .mud-icon-button,
    .dash-shell .dash-activity .mud-icon-button {
        opacity: 1;
    }
}

/* Small filled buttons inside cards pick up the brand gradient and a coloured
   shadow, so a primary action looks like the most important thing on the card. */
.dash-shell .dash-widget .mud-button-filled.mud-button-filled-primary {
    background: var(--egk-gradient-brand-vivid);
    box-shadow: 0 4px 14px -6px rgba(var(--egk-color-primary-rgb), 0.6);
}

.dash-shell .dash-widget .mud-button-root {
    border-radius: var(--egk-radius-full);
    text-transform: none;
    letter-spacing: 0;
    font-weight: var(--egk-weight-semibold);
}

/* Header action cluster: the icon buttons read as one segmented control rather
   than three loose glyphs floating beside the palette field. */
.dash-header__tools {
    display: inline-flex;
    align-items: center;
    gap: var(--egk-space-1);
    padding: 0.2rem;
    border: 1px solid var(--dash-border);
    border-radius: var(--egk-radius-full);
    background: rgba(var(--egk-color-surface-rgb), 0.75);
    box-shadow: var(--dash-hairline);
}

.mud-theme-dark .dash-header__tools {
    background: rgba(255, 255, 255, 0.07);
}

/* Rotates the glyph, not the button, so the ripple and hit area stay put. */
.dash-shell .dash-spin .mud-icon-root {
    animation: dash-rotate 900ms linear infinite;
}

@keyframes dash-rotate {
    to { transform: rotate(360deg); }
}

/* The AI card is the dashboard's flagship, so its badge gets the full gradient
   treatment that the other widget icons only hint at. */
.dash-shell .w-ai-insights .dash-widget__icon {
    background: var(--egk-gradient-brand-vivid);
    box-shadow: 0 3px 10px -3px rgba(var(--egk-color-primary-rgb), 0.55);
    color: var(--egk-on-brand);
}

/* Themed scrollbars for any list that grows past its card. */
.dash-shell .dash-widget__body {
    scrollbar-width: thin;
    scrollbar-color: rgba(var(--egk-color-primary-rgb), 0.30) transparent;
}

/* --------------------------------------------------------- customize drawer --- */

.dash-customize__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--egk-space-2);
}

.dash-customize__body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding-inline: var(--egk-space-4);
    padding-block-end: var(--egk-space-4);
    display: flex;
    flex-direction: column;
    gap: var(--egk-space-5);
}

.dash-customize__group {
    display: flex;
    flex-direction: column;
    gap: var(--egk-space-1);
}

.dash-customize__group-title {
    font-size: 0.6875rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--egk-color-muted);
    font-weight: 650;
}

.dash-customize__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--egk-space-2);
}

.dash-customize__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--egk-space-2);
    padding: var(--egk-space-4);
    border-block-start: 1px solid var(--dash-border);
}

/* =========================================================== glance rail === */

/* Narrow-screen fallback keeps the original wave stack and its spacing. The
   wide-screen rule below changes this wrapper into the unified cockpit grid. */
.dash-cockpit {
    display: flex;
    flex-direction: column;
    gap: var(--dash-gap);
    min-inline-size: 0;
}

.dash-glance {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: var(--egk-space-2);
    min-inline-size: 0;
}

/* Tiles are buttons ÃÂ¢ÃÂÃÂ each figure is also a shortcut to the card that owns
   it ÃÂ¢ÃÂÃÂ so the tile resets button chrome and inherits the card language. */
.dash-glance__tile {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--egk-space-3);
    min-inline-size: 0;
    min-block-size: 4.5rem;
    padding-block: var(--egk-space-2);
    padding-inline: var(--egk-space-3);
    border: 1px solid var(--dash-border);
    border-radius: var(--dash-radius);
    background: var(--dash-fill);
    box-shadow: var(--dash-shadow), var(--dash-hairline);
    overflow: hidden;
    appearance: none;
    font: inherit;
    color: inherit;
    text-align: start;
    cursor: pointer;
    transition:
        border-color var(--egk-motion-fast, 120ms) ease,
        box-shadow var(--egk-motion-fast, 120ms) ease,
        transform var(--egk-motion-fast, 120ms) ease;
}

.dash-glance__tile:hover {
    border-color: color-mix(in srgb, var(--dash-glance-color, var(--egk-color-primary)) 45%, var(--dash-border));
    box-shadow: var(--dash-shadow-hover), var(--dash-hairline);
    transform: translateY(-1px);
}

.dash-glance__tile:hover .dash-glance__icon {
    transform: scale(1.08);
}

.dash-glance__tile:active {
    transform: translateY(0);
}

/* The strip is the first content on the page, so it leads the same entrance
   choreography the card grid already performs ÃÂ¢ÃÂÃÂ arriving a beat ahead of the
   widgets it summarizes, in reading order. */
.dash-glance__tile {
    animation: dash-rise var(--egk-dur) var(--egk-ease-out) backwards;
}

.dash-glance__tile:nth-child(2) { animation-delay: 30ms; }
.dash-glance__tile:nth-child(3) { animation-delay: 60ms; }
.dash-glance__tile:nth-child(4) { animation-delay: 90ms; }
.dash-glance__tile:nth-child(5) { animation-delay: 120ms; }
.dash-glance__tile:nth-child(n + 6) { animation-delay: 150ms; }

/* A restrained top line gives the compact tiles the crisp segmented rhythm of
   an analytics cockpit without painting their entire surfaces by severity. */
.dash-glance__tile::before {
    content: "";
    position: absolute;
    inset-block-start: 0;
    inset-inline: 0;
    block-size: 2px;
    background: var(--dash-glance-color, var(--dash-border));
}

.dash-glance__tile--critical { --dash-glance-color: var(--dash-critical); }
.dash-glance__tile--warning { --dash-glance-color: var(--dash-warning); }
.dash-glance__tile--attention { --dash-glance-color: var(--dash-attention); }
.dash-glance__tile--ok { --dash-glance-color: var(--dash-ok); }

.dash-glance__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 2rem;
    block-size: 2rem;
    border-radius: var(--dash-radius-sm);
    color: var(--dash-glance-color, var(--egk-color-muted));
    background: color-mix(
        in srgb,
        var(--dash-glance-color, var(--egk-color-muted)) 10%,
        transparent);
    flex-shrink: 0;
    transition: transform var(--egk-dur-fast) var(--egk-ease);
}

.dash-glance__copy {
    display: flex;
    flex-direction: column;
    min-inline-size: 0;
}

.dash-glance__value {
    font-size: 1.25rem;
    font-weight: var(--egk-weight-bold);
    line-height: 1;
    letter-spacing: var(--egk-tracking-tight);
    font-variant-numeric: tabular-nums;
}

.dash-glance__label {
    margin-block-start: 0.3rem;
    color: var(--egk-color-muted);
    font-size: 0.6875rem;
    font-weight: var(--egk-weight-medium);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Optional context line ÃÂ¢ÃÂÃÂ trend and "why this number" ÃÂ¢ÃÂÃÂ rendered only when the
   underlying data is real, never as decoration. */
.dash-glance__meta {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    margin-block-start: 0.2rem;
    color: var(--egk-color-muted);
    font-size: 0.6875rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dash-glance__meta .mud-icon-root {
    font-size: 0.875rem;
    color: var(--dash-glance-color, var(--egk-color-muted));
}

@container dash (max-width: 900px) {
    .dash-glance {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@container dash (max-width: 520px) {
    .dash-glance {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .dash-glance__tile {
        min-block-size: 4rem;
    }
}

/* ============================================================ zero values === */

/* A zero in an exception-oriented dashboard is reassurance, not a finding.
   Muting it keeps the figures that are actually non-zero as the loudest thing
   on the card ÃÂ¢ÃÂÃÂ the difference between a wall of numbers and a scan. The value
   stays fully legible; only its visual priority drops. */
.dash-zero {
    opacity: 0.55;
}

.dash-zero .dash-kpi__value,
.dash-zero .dash-comms__tile-value,
.dash-zero .dash-comms__rate-value,
.dash-zero strong {
    color: var(--egk-color-muted);
    font-weight: var(--egk-weight-medium);
}

.dash-glance__tile--zero .dash-glance__value {
    color: var(--egk-color-muted);
    font-weight: var(--egk-weight-medium);
}

.dash-glance__tile--zero .dash-glance__icon {
    opacity: 0.6;
}

/* ====================================================== estate overview === */

/* The platform cockpit's primary intelligence area: one hero figure, a status
   distribution the eye reads as a single shape, and the lifecycle exceptions.
   Micro-visualization instead of a chart ÃÂ¢ÃÂÃÂ the estate rarely needs more. */
.dash-estate {
    display: flex;
    align-items: stretch;
    gap: var(--egk-space-4);
    min-inline-size: 0;
}

.dash-estate__hero {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 0.35rem;
    min-inline-size: 11rem;
    padding-inline-end: var(--egk-space-4);
    border-inline-end: 1px solid var(--dash-border);
    flex-shrink: 0;
}

.dash-estate__value {
    font-size: 2.4rem;
    font-weight: var(--egk-weight-bold);
    line-height: 1;
    letter-spacing: var(--egk-tracking-tight);
    font-variant-numeric: tabular-nums;
}

/* Gradient ink for the one display-size numeral on the page. Subtle ÃÂ¢ÃÂÃÂ full
   strength at the top fading a quarter toward the surface ÃÂ¢ÃÂÃÂ so it reads as
   depth, not decoration, and only where clipping text is actually supported. */
@supports (-webkit-background-clip: text) or (background-clip: text) {
    .dash-estate__value {
        background: linear-gradient(
            180deg,
            var(--egk-color-text) 30%,
            color-mix(in srgb, var(--egk-color-text) 72%, transparent) 100%);
        -webkit-background-clip: text;
        background-clip: text;
        -webkit-text-fill-color: transparent;
        color: var(--egk-color-text);
    }
}

.dash-estate__label {
    color: var(--egk-color-muted);
    font-size: 0.75rem;
    font-weight: var(--egk-weight-medium);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.dash-estate__trend {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-block-start: 0.25rem;
    color: var(--egk-color-muted);
    font-size: 0.75rem;
}

.dash-estate__trend .mud-icon-root {
    font-size: 1rem;
}

.dash-estate__trend--up { color: var(--dash-ok); }
.dash-estate__trend--down { color: var(--dash-critical); }

.dash-estate__trend-pct {
    font-weight: var(--egk-weight-semibold, 600);
    font-variant-numeric: tabular-nums;
}

.dash-estate__board {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: var(--egk-space-3);
    flex: 1;
    min-inline-size: 0;
}

.dash-distribution {
    display: flex;
    flex-direction: column;
    gap: var(--egk-space-2);
    min-inline-size: 0;
}

.dash-distribution__bar {
    display: flex;
    gap: 2px;
    block-size: 0.625rem;
    border-radius: 999px;
    overflow: hidden;
    background: color-mix(in srgb, var(--dash-border) 55%, transparent);
}

.dash-distribution__segment {
    flex: var(--dash-segment-weight, 0) 1 0;
    min-inline-size: 3px;
}

.dash-distribution__segment--ok { background: var(--dash-ok); }
.dash-distribution__segment--attention { background: var(--dash-attention); }
.dash-distribution__segment--critical { background: var(--dash-critical); }
.dash-distribution__segment--rest {
    background: color-mix(in srgb, var(--egk-color-muted) 35%, transparent);
}

.dash-distribution__legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--egk-space-3);
    color: var(--egk-color-muted);
    font-size: 0.75rem;
}

.dash-distribution__key {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    white-space: nowrap;
}

.dash-distribution__key strong {
    color: var(--egk-color-text-primary, inherit);
    font-variant-numeric: tabular-nums;
}

.dash-distribution__swatch {
    inline-size: 0.5rem;
    block-size: 0.5rem;
    border-radius: 2px;
    flex-shrink: 0;
}

.dash-distribution__swatch--ok { background: var(--dash-ok); }
.dash-distribution__swatch--attention { background: var(--dash-attention); }
.dash-distribution__swatch--critical { background: var(--dash-critical); }
.dash-distribution__swatch--rest {
    background: color-mix(in srgb, var(--egk-color-muted) 35%, transparent);
}

.dash-estate__facts {
    display: flex;
    flex-wrap: wrap;
    gap: var(--egk-space-2);
}

.dash-estate__fact {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding-block: 0.35rem;
    padding-inline: var(--egk-space-2);
    border: 1px solid var(--dash-border);
    border-radius: var(--dash-radius-sm);
    background: var(--dash-fill);
    font-size: 0.75rem;
    color: var(--egk-color-muted);
}

.dash-estate__fact .mud-icon-root {
    font-size: 1rem;
    color: var(--dash-estate-fact-color, var(--egk-color-muted));
}

.dash-estate__fact strong {
    color: var(--dash-estate-fact-color, inherit);
    font-size: 0.875rem;
    font-variant-numeric: tabular-nums;
}

.dash-estate__fact--ok { --dash-estate-fact-color: var(--dash-ok); }
.dash-estate__fact--warning { --dash-estate-fact-color: var(--dash-warning); }
.dash-estate__fact--critical { --dash-estate-fact-color: var(--dash-critical); }

/* Narrow containers stack the hero above the board; the divider rotates from a
   vertical rule into a horizontal one. */
@container dash (max-width: 700px) {
    .dash-estate {
        flex-direction: column;
        gap: var(--egk-space-3);
    }

    .dash-estate__hero {
        min-inline-size: 0;
        padding-inline-end: 0;
        padding-block-end: var(--egk-space-3);
        border-inline-end: none;
        border-block-end: 1px solid var(--dash-border);
    }
}

/* ======================================================= desktop cockpit === */

/*
   Wide screens are a command canvas, not a stack of reports.

   The Razor tree intentionally keeps the four waves because they still define
   loading priority, permissions and the narrow-screen reading order. `contents`
   removes only their layout boxes, allowing every visible widget to participate
   in one twelve-column grid. This is what makes the page behave like a compact
   cockpit while preserving the dashboard architecture underneath it.
*/
@container dash (min-width: 1101px) {
    .dash-shell {
        --dash-gap: var(--egk-space-3);
        --dash-card-pad: var(--egk-space-3);
        --dash-card-pad-tight: var(--egk-space-2);
        --dash-row-gap: var(--egk-space-2);
        --dash-radius: var(--egk-radius-md);
        gap: var(--egk-space-3);
        padding-block: var(--egk-space-3);
        padding-inline: var(--egk-space-4);
    }

    /* The reference dashboard treats the greeting as a compact toolbar rather
       than a large hero. Keep all context and controls, but spend much less of
       the viewport on framing before the operational content begins. */
    .dash-header {
        gap: var(--egk-space-3);
        padding-block: var(--egk-space-3);
        padding-inline: var(--egk-space-4);
    }

    .dash-header__main {
        gap: var(--egk-space-1);
    }

    .dash-header__pills {
        gap: var(--egk-space-1);
    }

    .dash-header__greeting {
        font-size: clamp(1.25rem, 2cqi, 1.6rem);
    }

    /* At cockpit density the header is a toolbar. The mission-statement line is
       orientation for first-time and narrow-screen readers; on a wide desktop
       the pills and the glance strip already say the same thing in less space. */
    .dash-header__subtitle {
        display: none;
    }

    .dash-cockpit {
        display: grid;
        grid-template-columns: repeat(12, minmax(0, 1fr));
        gap: var(--dash-gap);
        align-items: stretch;
        grid-auto-flow: dense;
        min-inline-size: 0;
    }

    .dash-cockpit > .dash-glance {
        grid-column: 1 / -1;
    }

    /* Non-widget children (alerts, toolbars, legacy markup) must span the full
       cockpit width or they collapse into single grid tracks and overlap. */
    .dash-cockpit > :not(.dash-glance):not(.dash-wave):not(.dash-widget) {
        grid-column: 1 / -1;
        min-inline-size: 0;
    }

    .dash-cockpit > .dash-wave,
    .dash-cockpit > .dash-wave > .dash-grid {
        display: contents;
    }

    /* Widget headers already identify every card. Repeating Operations,
       Intelligence and Productivity between rows spends vertical space without
       adding orientation once all waves share one visual canvas. */
    .dash-cockpit > .dash-wave > .dash-wave__head {
        display: none;
    }

    .dash-cockpit .dash-widget {
        align-self: stretch;
    }

    /*
       Tenant cockpit ÃÂ¢ÃÂÃÂ zone composition:
       ÃÂ¢ÃÂÃÂ glance strip ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ
       ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ attention: primary intelligence (8, tall) ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ¬ system ÃÂ¢ÃÂÃÂ¤
       ÃÂ¢ÃÂÃÂ                                                    ÃÂ¢ÃÂÃÂ my workÃÂ¢ÃÂÃÂ¤
       ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ AI insights (8) ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ¼ quick  ÃÂ¢ÃÂÃÂ¤
       ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ notifications (4) ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ activity (4) ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ favorites (4) ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ
       The exception feed is this tenant's operational overview, so it owns
       the primary zone; the personal rail sits beside it.
    */
    .dash-cockpit--tenant .w-attention-center { grid-column: 1 / 9; grid-row: span 2; }
    .dash-cockpit--tenant .w-system-status { grid-column: 9 / -1; }
    .dash-cockpit--tenant .w-my-work { grid-column: 9 / -1; }
    .dash-cockpit--tenant .w-ai-insights { grid-column: 1 / 9; }
    .dash-cockpit--tenant .w-quick-actions { grid-column: 9 / -1; }
    .dash-cockpit--tenant :is(
        .w-notifications,
        .w-recent-activity,
        .w-communications,
        .w-favorites) {
        grid-column: span 4;
    }

    /* Collapsed cards render nothing at all, so :has() can read the footer's
       composition: with both communications and favorites present the row
       holds four cards and tightens to quarters; with three it stays thirds. */
    .dash-cockpit--tenant:has(.w-communications):has(.w-favorites) :is(
        .w-notifications,
        .w-recent-activity,
        .w-communications,
        .w-favorites) {
        grid-column: span 3;
    }

    /*
       Platform cockpit ÃÂ¢ÃÂÃÂ zone composition:
       ÃÂ¢ÃÂÃÂ glance strip ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ
       ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ tenant estate overview (8) ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ¬ platform health  ÃÂ¢ÃÂÃÂ
       ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ communications (4) ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ¬ÃÂ¢ÃÂÃÂ my work (4) ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ¤    (4, tall) ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ¤
       ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ tenant health (4) ÃÂ¢ÃÂÃÂ subscriptions (4) ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ´ÃÂ¢ÃÂÃÂ AI (4) ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ¤
       ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ notifications ÃÂ¢ÃÂÃÂ activity ÃÂ¢ÃÂÃÂ quick ÃÂ¢ÃÂÃÂ attention ÃÂ¢ÃÂÃÂ favorites ÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂÃÂ¢ÃÂÃÂ
       Platform health owns the tall rail. Communications and the attention
       feed swap homes by operator preference: the mailbox/newsletter pulse
       rides in the operational row, the exception feed compacts into the
       footer. Auto-placement follows order-modified document order, so the
       ordinals below are the layout.
    */
    .dash-cockpit--platform .w-tenant-operations { grid-column: 1 / 9; grid-row: 2; }
    .dash-cockpit--platform .w-platform-health { grid-column: 9 / -1; grid-row: 2 / span 2; }
    .dash-cockpit--platform .w-communications { grid-column: span 4; order: 1; }
    .dash-cockpit--platform .w-my-work { grid-column: span 4; order: 2; }
    .dash-cockpit--platform .w-tenant-health { grid-column: span 4; order: 3; }
    .dash-cockpit--platform .w-subscription-intelligence { grid-column: span 4; order: 4; }
    .dash-cockpit--platform .w-ai-insights { grid-column: span 4; order: 5; }
    .dash-cockpit--platform .w-notifications { order: 6; }
    .dash-cockpit--platform .w-recent-activity { order: 7; }
    .dash-cockpit--platform .w-quick-actions { order: 8; }
    .dash-cockpit--platform .w-attention-center { order: 9; }
    .dash-cockpit--platform .w-favorites { order: 10; }
    .dash-cockpit--platform :is(
        .w-notifications,
        .w-recent-activity,
        .w-quick-actions,
        .w-attention-center,
        .w-favorites) {
        grid-column: span 3;
    }

    /*
       Collapsed cards render nothing, which silently breaks the 12-column
       accounting above: a missing intelligence card leaves a 4-column hole
       that auto-placement fills by pulling a footer card up, and the footer
       then trails off short of the page edge. The :has() corrections below
       re-total each band to 12 for the compositions that actually occur.
    */

    /* Intelligence band (tenant health / subscriptions / AI): one card gone,
       the survivors split the row in halves; two gone, the last owns it. */
    .dash-cockpit--platform:not(:has(.w-tenant-health)) :is(
        .w-subscription-intelligence,
        .w-ai-insights),
    .dash-cockpit--platform:not(:has(.w-subscription-intelligence)) :is(
        .w-tenant-health,
        .w-ai-insights),
    .dash-cockpit--platform:not(:has(.w-ai-insights)) :is(
        .w-tenant-health,
        .w-subscription-intelligence) {
        grid-column: span 6;
    }

    .dash-cockpit--platform:not(:has(.w-tenant-health)):not(:has(.w-subscription-intelligence)) .w-ai-insights,
    .dash-cockpit--platform:not(:has(.w-tenant-health)):not(:has(.w-ai-insights)) .w-subscription-intelligence,
    .dash-cockpit--platform:not(:has(.w-subscription-intelligence)):not(:has(.w-ai-insights)) .w-tenant-health {
        grid-column: 1 / -1;
    }

    /* Footer band: quarters assume four cards. With all five visible the
       favorites chip strip takes a full-width row of its own; with only
       three (attention hidden, favorites empty) the row opens up to thirds. */
    .dash-cockpit--platform:has(.w-notifications):has(.w-recent-activity):has(.w-quick-actions):has(.w-attention-center) .w-favorites {
        grid-column: 1 / -1;
    }

    .dash-cockpit--platform:not(:has(.w-attention-center)):not(:has(.w-favorites)) :is(
        .w-notifications,
        .w-recent-activity,
        .w-quick-actions) {
        grid-column: span 4;
    }

    /* Compact cards behave like dashboard panels: the page itself stays short
       and long feeds scroll inside their own bounded region. The scrollbar is
       already themed by the shared widget-body rules.

       Scroll chaining stays ON (`overscroll-behavior: auto`): once a feed hits
       its top/bottom edge the same wheel/touch gesture must continue scrolling
       the page. `contain` here made the page feel stuck whenever the pointer
       rested on a widget. dashboard.js adds the instant hand-off Chromium's
       wheel latching would otherwise delay until the gesture ends. */
    .dash-cockpit :is(
        .w-my-work,
        .w-ai-insights,
        .w-notifications,
        .w-recent-activity,
        .w-communications,
        .w-tenant-health) .dash-widget__body {
        max-block-size: 15.5rem;
        overflow-y: auto;
        overscroll-behavior: auto;
    }

    /* The tenant cockpit's attention feed is the tall primary zone, so it gets
       extra depth before scrolling internally; in the platform cockpit the
       feed is a standard card and matches the shared panel height. */
    .dash-cockpit .w-attention-center .dash-widget__body {
        max-block-size: 26rem;
        overflow-y: auto;
        overscroll-behavior: auto;
    }

    .dash-cockpit--platform .w-attention-center .dash-widget__body {
        max-block-size: 15.5rem;
    }

    /* Platform health owns the platform cockpit's tall rail. */
    .dash-cockpit .w-platform-health .dash-widget__body {
        max-block-size: 26rem;
        overflow-y: auto;
        overscroll-behavior: auto;
    }

    .dash-cockpit .dash-widget__head {
        padding-block: var(--egk-space-2);
        padding-inline: var(--egk-space-3);
    }

    .dash-cockpit .dash-widget__body {
        padding: var(--egk-space-3);
    }

    .dash-cockpit :is(
        .dash-signal,
        .dash-work,
        .dash-service,
        .dash-tenant,
        .dash-notify,
        .dash-activity) {
        padding-block: 0.55rem;
        padding-inline: var(--egk-space-3);
    }

    /* One-third-width KPI cards must not try to retain a four-up tile grid.
       Two columns keeps the figures large enough to scan while preserving
       density. */
    .dash-cockpit--platform .w-subscription-intelligence .dash-kpi-row {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .dash-cockpit--platform .w-subscription-intelligence .dash-kpi {
        min-block-size: 4.25rem;
        padding: var(--egk-space-2);
    }

    .dash-cockpit--platform .w-subscription-intelligence .dash-kpi__value {
        font-size: 1.2rem;
    }

    .dash-cockpit--platform .w-subscription-intelligence .dash-kpi__glyph {
        font-size: 1rem;
        inset-block-start: var(--egk-space-1);
        inset-inline-end: var(--egk-space-1);
    }

    /* The communications card sits in a narrow cockpit slot; the four stat
       tiles stay on one row (matching the classic mail-overview silhouette)
       and simply compress: tighter padding, smaller numerals, and labels that
       ellipsize rather than wrap. */
    .dash-cockpit .w-communications .dash-comms__tiles {
        gap: var(--egk-space-1);
    }

    .dash-cockpit .w-communications .dash-comms__tile {
        gap: 0.125rem;
        padding-block: var(--egk-space-1);
        padding-inline: 0.125rem;
    }

    .dash-cockpit .w-communications .dash-comms__tile-value {
        font-size: 0.9375rem;
    }

    .dash-cockpit .w-communications .dash-comms__tile-label {
        font-size: 0.5625rem;
        letter-spacing: 0.04em;
    }

    .dash-cockpit .w-communications .dash-comms__news {
        margin-block-start: var(--egk-space-2);
        padding-block-start: var(--egk-space-2);
        gap: var(--egk-space-1);
    }

    .dash-cockpit .w-communications .dash-comms__rate {
        padding-block: var(--egk-space-1);
        padding-inline: var(--egk-space-2);
    }

    .dash-cockpit .w-communications .dash-comms__queued {
        padding-block: var(--egk-space-1);
    }

    .dash-cockpit--platform .w-subscription-intelligence .dash-kpi-footnote {
        gap: var(--egk-space-2);
    }

    /* The estate hero anchors the primary zone; give the card breathing room
       vertically so the distribution reads as the row's centrepiece. */
    .dash-cockpit--platform .w-tenant-operations .dash-widget__body {
        justify-content: center;
    }

    /* Signal rows were composed for a wide card. In the platform's one-third
       attention rail the title keeps the full width and the age + action
       cluster drops to its own line, ends-aligned ÃÂ¢ÃÂÃÂ the same fold the phone
       layout uses, applied for the same reason. */
    .dash-cockpit--platform .w-attention-center .dash-signal {
        flex-wrap: wrap;
    }

    .dash-cockpit--platform .w-attention-center .dash-signal__actions {
        inline-size: 100%;
        justify-content: space-between;
    }

    /* Insight panels and shortcut chips give back a step of padding at cockpit
       density; their internal hierarchy carries the structure. */
    .dash-cockpit .dash-insight {
        padding: var(--egk-space-3);
    }

    .dash-cockpit .dash-action {
        padding-block: var(--egk-space-2);
    }

    /* The health gauge was sized for a half-width card; in the one-third rail it
       stacks above the metric list, so a smaller ring keeps the glance band from
       eating the rows' vertical space. */
    .dash-cockpit--platform .w-platform-health .dash-health-ring {
        --dash-ring-size: 5.5rem;
        --dash-ring-thickness: 0.5rem;
    }

    .dash-cockpit--platform .w-platform-health .dash-health-ring__value {
        font-size: 1.2rem;
    }

    .dash-cockpit--platform .w-platform-health .dash-health-summary {
        gap: var(--egk-space-3);
        padding-block-end: var(--egk-space-3);
    }

    /* Glance tiles read as one instrument row: slightly shallower, with the
       figure scaled to match the tightened rhythm. */
    .dash-glance__tile {
        min-block-size: 4.125rem;
    }

    .dash-glance__value {
        font-size: 1.35rem;
    }
}

/* =========================================================== responsive === */

/* Tablet: honour each widget's declared tablet width. */
@container dash (max-width: 1100px) {
    .dash-span-md-1 { grid-column: span 1; }
    .dash-span-md-2 { grid-column: span 2; }
    .dash-span-md-3 { grid-column: span 3; }
    .dash-span-md-4 { grid-column: span 4; }
    .dash-span-md-5 { grid-column: span 5; }
    .dash-span-md-6 { grid-column: span 6; }
    .dash-span-md-7 { grid-column: span 7; }
    .dash-span-md-8 { grid-column: span 8; }
    .dash-span-md-9 { grid-column: span 9; }
    .dash-span-md-10 { grid-column: span 10; }
    .dash-span-md-11 { grid-column: span 11; }
    .dash-span-md-12 { grid-column: span 12; }
}

/* Phone: single column, tighter density, and a different priority order.
   On a small screen the user is checking rather than working, so what is broken
   and what they personally owe come first; ambient context that is useful on a
   desk is noise on a phone and drops to the bottom. */
@container dash (max-width: 700px) {
    .dash-shell {
        --dash-gap: var(--egk-space-3);
        --dash-card-pad: var(--egk-space-3);
        --dash-card-pad-tight: var(--egk-space-2);
        padding-inline: var(--egk-space-3);
    }

    .dash-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .dash-grid > * {
        grid-column: span 1 !important;
    }

    .dash-widget__body {
        gap: var(--egk-space-2);
    }

    /* The hero panel keeps its identity but stops eating the fold. */
    .dash-header {
        padding-block: var(--egk-space-3);
        padding-inline: var(--egk-space-4);
    }

    .dash-header__greeting {
        font-size: 1.25rem;
    }

    .dash-header__actions {
        inline-size: 100%;
        justify-content: flex-start;
    }

    .dash-header__actions .mud-button-root.dash-btn--responsive-label .mud-button-label,
    .dash-header__actions .mud-button.dash-btn--responsive-label .mud-button-label {
        display: none;
    }

    .dash-header__actions .mud-button-root.dash-btn--responsive-label,
    .dash-header__actions .mud-button.dash-btn--responsive-label {
        min-inline-size: 2.75rem;
        padding-inline: 0.65rem;
    }

    .dash-header__actions > .mud-select,
    .dash-header__actions > .mud-input-control,
    .dash-header__actions > div {
        flex: 1 1 100%;
        max-inline-size: 100%;
    }

    .dash-header__palette {
        min-inline-size: 0;
    }

    .dash-header__palette-label {
        display: none;
    }

    .dash-widget--scroll .dash-widget__body,
    .dash-widget.dash-widget--scroll .dash-widget__body {
        max-block-size: min(22rem, 55vh);
        overflow-y: auto;
        overscroll-behavior: auto;
    }

    .dash-grid > .w-attention-center { order: 0; }
    .dash-grid > .w-my-work { order: 1; }
    .dash-grid > .w-tenant-health { order: 2; }
    .dash-grid > .w-tenant-operations { order: 3; }
    .dash-grid > .w-system-status { order: 4; }
    .dash-grid > .w-platform-health { order: 5; }
    .dash-grid > .w-subscription-intelligence { order: 6; }
    .dash-grid > .w-ai-insights { order: 7; }
    .dash-grid > .w-notifications { order: 8; }
    .dash-grid > .w-quick-actions { order: 9; }
    .dash-grid > .w-recent-activity { order: 10; }
    .dash-grid > .w-communications { order: 11; }
    .dash-grid > .w-favorites { order: 12; }

    /* Signal rows stack: on a phone the action button beside a two-line title
       leaves about eight characters for the title. */
    .dash-signal {
        flex-wrap: wrap;
    }

    .dash-signal__actions {
        inline-size: 100%;
        justify-content: flex-end;
    }

    .dash-kpi-row {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .dash-resource-line {
        gap: var(--egk-space-3);
    }
}

/* Fallback for browsers without container queries: same intent, viewport-based.
   Slightly wrong when the nav drawer is open, which is preferable to a
   twelve-column grid crushed into a phone. */
@supports not (container-type: inline-size) {
    @media (max-width: 1100px) {
        .dash-grid > * { grid-column: span 6; }
    }

    @media (max-width: 700px) {
        .dash-grid { grid-template-columns: minmax(0, 1fr); }
        .dash-grid > * { grid-column: span 1; }
    }
}

/* ==========================================================================
   Module cockpit ÃÂ shared KPI dashboards (Mail, To-Do, EI, ÃÂ)
   ========================================================================== */

.dash-header__kicker {
    margin: 0 0 var(--egk-space-1);
    font-size: var(--egk-fs-xs);
    font-weight: var(--egk-weight-semibold);
    letter-spacing: var(--egk-tracking-caps);
    text-transform: uppercase;
    color: var(--egk-color-muted);
}

.dash-header__title-icon {
    margin-inline-end: 0;
    vertical-align: middle;
    color: var(--egk-color-primary);
}

.dash-glance__tile--static {
    cursor: default;
    pointer-events: none;
}

.dash-cockpit--module {
    display: flex;
    flex-direction: column;
    gap: var(--dash-gap, var(--egk-space-4));
}

.dash-cockpit--module > .dash-glance {
    width: 100%;
}

@container dash (min-width: 1101px) {
    .dash-cockpit--module {
        display: grid;
        grid-template-columns: repeat(12, minmax(0, 1fr));
        grid-auto-flow: dense;
        gap: var(--dash-gap, var(--egk-space-3));
        align-items: start;
    }

    .dash-cockpit--module > .dash-glance {
        grid-column: 1 / -1;
    }

    .dash-cockpit--module > .dash-wave {
        display: contents;
    }

    .dash-cockpit--module > .dash-wave > .dash-wave__head {
        display: none;
    }

    .dash-cockpit--module > .dash-wave > .dash-grid {
        display: contents;
    }

    .dash-cockpit--module > :not(.dash-glance):not(.dash-wave):not(.dash-widget) {
        grid-column: 1 / -1;
        min-inline-size: 0;
    }
}

/* ==========================================================================
   Shared responsive utilities (module + Home)
   ========================================================================== */

.dash-truncate {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-inline-size: 0;
}

.dash-min-w-0 {
    min-inline-size: 0 !important;
    max-inline-size: 100%;
}

.dash-arrow-forward {
    display: inline-flex;
}

[dir="rtl"] .dash-arrow-forward,
.dash-shell--rtl .dash-arrow-forward {
    transform: scaleX(-1);
}

/* Filter toolbar â wrap on tablet, stack on phone */
.dash-filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--egk-space-2);
    min-inline-size: 0;
    width: 100%;
    padding-block: var(--egk-space-2);
    padding-inline: var(--egk-space-3);
    border: 1px solid var(--dash-border);
    border-radius: var(--dash-radius);
    background: var(--dash-fill);
    box-shadow: var(--dash-shadow), var(--dash-hairline);
}

.dash-filter-bar--sticky {
    position: sticky;
    inset-block-start: 0;
    z-index: 20;
    backdrop-filter: blur(10px);
    background: color-mix(in srgb, var(--dash-surface, var(--mud-palette-surface)) 88%, transparent);
}

.dash-filter-bar > * {
    min-inline-size: 0;
    flex: 1 1 10rem;
    max-inline-size: 100%;
}

.dash-filter-bar > .mud-button-root,
.dash-filter-bar > .mud-button {
    flex: 0 0 auto;
}

@container dash (max-width: 700px) {
    .dash-filter-bar {
        flex-direction: column;
        align-items: stretch;
    }

    .dash-filter-bar > * {
        flex: 1 1 auto;
        width: 100%;
        max-inline-size: 100%;
    }
}

/* Tables: scroll inside the widget, never the page */
.dash-table-scroll {
    width: 100%;
    min-inline-size: 0;
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    -webkit-overflow-scrolling: touch;
}

.dash-table-scroll .mud-table,
.dash-table-scroll table {
    min-inline-size: 28rem;
}

/* Charts: responsive height via container, ignore rigid inline heights */
.dash-widget .mud-chart,
.dash-widget .mud-chart-container {
    inline-size: 100% !important;
    max-inline-size: 100%;
    block-size: clamp(160px, 28cqi, 300px) !important;
    min-block-size: 160px;
}

.dash-widget .mud-chart svg,
.dash-widget .mud-chart-svg {
    max-inline-size: 100%;
}

/* Nested body grid â container-aware, not viewport MudGrid */
.dash-body-grid {
    display: grid;
    gap: var(--egk-space-3);
    grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
    min-inline-size: 0;
}

.dash-body-grid--halves {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.dash-body-grid--thirds {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.dash-widget__body {
    container-type: inline-size;
    container-name: dash-card;
}

@container dash-card (max-width: 32rem) {
    .dash-body-grid--halves,
    .dash-body-grid--thirds {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Glance scroll for strips with many tiles */
.dash-glance--scroll {
    display: flex;
    flex-wrap: nowrap;
    gap: var(--egk-space-2);
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    scroll-snap-type: inline mandatory;
    -webkit-overflow-scrolling: touch;
    padding-block-end: var(--egk-space-1);
    scrollbar-width: thin;
}

.dash-glance--scroll .dash-glance__tile {
    flex: 0 0 min(11.5rem, 72vw);
    scroll-snap-align: start;
    min-inline-size: 9.5rem;
}

.dash-glance--scroll::-webkit-scrollbar {
    block-size: 4px;
}

.dash-glance--scroll::-webkit-scrollbar-thumb {
    background: var(--dash-border);
    border-radius: var(--egk-radius-full);
}

/* Opt-in scrollable widget body (lists/feeds). Chaining stays enabled so the
   page takes over when the list reaches its edge (see .dash-cockpit rules). */
.dash-widget--scroll .dash-widget__body {
    max-block-size: min(24rem, 50vh);
    overflow-y: auto;
    overscroll-behavior: auto;
}

@container dash (min-width: 701px) and (max-width: 1100px) {
    .dash-widget--scroll .dash-widget__body {
        max-block-size: min(20rem, 45vh);
    }
}

/* Touch: larger hit targets for compact chrome */
@media (hover: none) {
    .dash-header__pills .mud-chip,
    .dash-header__actions .mud-icon-button {
        min-block-size: 2.75rem;
        min-inline-size: 2.75rem;
    }

    .dash-glance__tile {
        min-block-size: 4.25rem;
    }

    .dash-filter-bar .mud-input-control,
    .dash-filter-bar .mud-button-root {
        min-block-size: 2.75rem;
    }
}

/* ==========================================================================
   Ultra-premium production polish (module + Home)
   ========================================================================== */

/* Glance tile: icon + stacked value/label copy */
.dash-glance__tile {
    align-items: center;
}

.dash-glance__copy {
    flex: 1 1 auto;
    gap: 0.15rem;
}

.dash-glance__value {
    font-size: clamp(1.15rem, 2.4cqi, 1.4rem);
    font-feature-settings: "tnum" 1;
}

.dash-glance__trend {
    margin-inline-start: auto;
    color: var(--dash-glance-color, var(--egk-color-muted));
    opacity: 0.9;
}

.dash-glance__tile--zero .dash-glance__value {
    color: var(--egk-color-muted);
    font-weight: var(--egk-weight-semibold);
}

.dash-glance__tile:focus-visible {
    outline: 2px solid rgba(var(--egk-color-primary-rgb), 0.55);
    outline-offset: 2px;
}

/* Module header actions: denser, more intentional chrome */
.dash-shell .dash-header__actions .mud-button-root {
    border-radius: calc(var(--dash-radius-sm) + 2px);
    font-weight: var(--egk-weight-semibold);
    letter-spacing: 0.01em;
    text-transform: none;
}

.dash-shell .dash-header__actions .mud-button-filled {
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.08);
}

.dash-shell .dash-header__actions .mud-chip {
    font-weight: var(--egk-weight-semibold);
}

/* Filter bar: quieter resting state, clearer focus */
.dash-filter-bar {
    transition: border-color var(--egk-motion-fast, 120ms) ease, box-shadow var(--egk-motion-fast, 120ms) ease;
}

.dash-filter-bar:focus-within {
    border-color: rgba(var(--egk-color-primary-rgb), 0.35);
    box-shadow: var(--dash-shadow), 0 0 0 3px rgba(var(--egk-color-primary-rgb), 0.08);
}

/* Nested filter bars inside widgets drop the second card chrome */
.dash-widget__body > .dash-filter-bar {
    border: none;
    background: transparent;
    box-shadow: none;
    padding-inline: 0;
    padding-block: 0;
}

.dash-widget__body > .dash-filter-bar:focus-within {
    box-shadow: none;
}

/* Widget head: tighter premium toolbar rhythm */
.dash-widget__head {
    border-block-end: 1px solid color-mix(in srgb, var(--dash-border) 70%, transparent);
}

.dash-widget__title-text {
    letter-spacing: var(--egk-tracking-tight);
}

/* Loading: avoid layout thrash */
.dash-widget--loading {
    pointer-events: none;
}

.dash-widget--loading:hover {
    transform: none;
    box-shadow: var(--dash-shadow), var(--dash-hairline);
}

/* Charts: keep SVG crisp inside clamped height */
.dash-widget .mud-chart {
    display: block;
}

/* Tables inside widgets: denser enterprise density */
.dash-widget .mud-table {
    background: transparent;
}

.dash-widget .mud-table .mud-table-cell {
    border-color: color-mix(in srgb, var(--dash-border) 80%, transparent);
}

.dash-table-scroll {
    border-radius: var(--dash-radius-sm);
}

/* Module cockpit: slightly tighter desktop gap for denser KPI boards */
@container dash (min-width: 1101px) {
    .dash-cockpit--module {
        gap: var(--egk-space-3);
    }

    .dash-cockpit--module .dash-glance {
        margin-block-end: 0;
    }
}

/* Phone: icon tile scales with title */
@container dash (max-width: 700px) {
    .dash-header__icon-tile {
        inline-size: 2.35rem;
        block-size: 2.35rem;
    }

    .dash-header__icon-tile .mud-icon-root {
        font-size: 1.15rem;
    }

    .dash-header__greeting {
        gap: var(--egk-space-2);
    }
}

/* Print: ink-friendly enterprise reports */
@media print {
    .dash-shell {
        padding: 0 !important;
        background: none !important;
        box-shadow: none !important;
    }

    .dash-shell::before {
        display: none !important;
    }

    .dash-header,
    .dash-widget,
    .dash-glance__tile,
    .dash-filter-bar {
        box-shadow: none !important;
        break-inside: avoid;
    }

    .dash-header__actions,
    .dash-filter-bar,
    .dash-widget__actions,
    .pt-fab {
        display: none !important;
    }

    .dash-widget:hover,
    .dash-glance__tile:hover {
        transform: none !important;
    }
}

/* Dark theme: icon tile stays luminous */
.mud-theme-dark .dash-header__icon-tile {
    background:
        linear-gradient(
            145deg,
            rgba(var(--egk-color-primary-rgb), 0.22) 0%,
            rgba(255, 255, 255, 0.04) 100%);
    border-color: rgba(var(--egk-color-primary-rgb), 0.28);
}

/* ==========================================================================
   Ultra-premium production v2  efficiency, density, surface system
   ========================================================================== */

/* Nested interactive surfaces share one language with widgets/tiles */
.dash-surface-card,
.dash-shell .todo-insight-card,
.dash-shell .entity-card {
    display: block;
    min-inline-size: 0;
    padding: var(--egk-space-3);
    border: 1px solid var(--dash-border);
    border-radius: var(--dash-radius-sm);
    background: var(--dash-fill-subtle);
    box-shadow: var(--dash-hairline);
    transition:
        border-color var(--egk-motion-fast, 120ms) ease,
        box-shadow var(--egk-motion-fast, 120ms) ease,
        transform var(--egk-motion-fast, 120ms) ease,
        background var(--egk-motion-fast, 120ms) ease;
}

.dash-surface-card--interactive,
.dash-shell .entity-card {
    cursor: pointer;
}

.dash-surface-card--interactive:hover,
.dash-shell .entity-card:hover,
.dash-shell .todo-insight-card:hover {
    border-color: var(--dash-border-hover);
    background: var(--dash-fill-hover);
    box-shadow: var(--dash-shadow), var(--dash-hairline);
    transform: translateY(-1px);
}

.dash-shell .entity-card .mud-typography-h4,
.dash-shell .entity-card .mud-typography-h5 {
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--egk-tracking-tight);
    font-weight: var(--egk-weight-bold);
}

/* Priority / meter bars  tokenized, no inline-only chrome */
/* Deliberately NOT applied to .dash-meter: that is the composite label / track /
   value component defined above, not a bare bar. Matching it here squeezed the
   whole meter into a 0.4rem clipped strip and painted its "Storage" label and
   "100%" value as gradient bars, so the text vanished in the tenant rows. */
.dash-shell .todo-priority-bar {
    position: relative;
    block-size: 0.4rem;
    border-radius: var(--egk-radius-full);
    background: rgba(var(--egk-color-primary-rgb), 0.08);
    overflow: hidden;
}

.dash-shell .todo-priority-bar > span {
    display: block;
    block-size: 100%;
    border-radius: inherit;
    background: linear-gradient(
        90deg,
        rgba(var(--egk-color-primary-rgb), 0.85),
        rgba(var(--egk-color-secondary-rgb, var(--egk-color-primary-rgb)), 0.7));
}

/* Widget production containment + scroll targets */
.dash-widget {
    scroll-margin-block-start: 1.25rem;
    contain: layout style;
}

.dash-cockpit--module > .dash-widget,
.dash-cockpit--module .dash-grid > .dash-widget {
    content-visibility: auto;
    contain-intrinsic-size: auto 18rem;
}

.dash-widget--flash {
    animation: dash-widget-flash 1.1s var(--egk-ease-out, ease-out);
}

@keyframes dash-widget-flash {
    0% {
        box-shadow: var(--dash-shadow), 0 0 0 0 rgba(var(--egk-color-primary-rgb), 0.35);
        border-color: rgba(var(--egk-color-primary-rgb), 0.45);
    }
    100% {
        box-shadow: var(--dash-shadow), var(--dash-hairline);
        border-color: var(--dash-border);
    }
}

/* Restore faded head seam (previous polish overwrote border-image) */
.dash-widget__head {
    border-block-end: 1px solid transparent;
    border-image: linear-gradient(
        to right,
        transparent 0%,
        color-mix(in srgb, var(--dash-border) 85%, transparent) 12%,
        color-mix(in srgb, var(--dash-border) 85%, transparent) 88%,
        transparent 100%) 1;
}

/* Static glance tiles: present but quiet */
.dash-glance__tile--static {
    cursor: default;
    pointer-events: auto;
    opacity: 0.92;
}

.dash-glance__tile--static:hover {
    transform: none;
    border-color: var(--dash-border);
    box-shadow: var(--dash-shadow), var(--dash-hairline);
}

.dash-glance__tile--static:hover .dash-glance__icon {
    transform: none;
}

.dash-glance__tile:disabled,
.dash-glance__tile[aria-disabled="true"] {
    cursor: default;
    opacity: 0.9;
}

/* Glance severity wash  whisper under the top hairline */
.dash-glance__tile[class*="dash-glance__tile--"]:not(.dash-glance__tile--zero)::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(
        180deg,
        color-mix(in srgb, var(--dash-glance-color, transparent) 8%, transparent) 0%,
        transparent 55%);
    opacity: 0.9;
}

.dash-glance__tile--info {
    --dash-glance-color: var(--dash-attention);
}

/* Header kicker: brand accent mark */
.dash-header__kicker {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    color: color-mix(in srgb, var(--egk-color-primary) 72%, var(--egk-color-muted));
}

.dash-header__kicker::before {
    content: "";
    inline-size: 0.55rem;
    block-size: 0.55rem;
    border-radius: 2px;
    background: var(--egk-gradient-brand, var(--egk-color-primary));
    box-shadow: 0 0 0 2px rgba(var(--egk-color-primary-rgb), 0.12);
    flex-shrink: 0;
}

.dash-header {
    animation: dash-rise var(--egk-dur, 220ms) var(--egk-ease-out, ease-out) backwards;
}

.dash-header__stamp {
    padding-inline: 0.55rem;
    padding-block: 0.2rem;
    border-radius: var(--egk-radius-full);
    background: rgba(var(--dash-ok-rgb), 0.08);
    border: 1px solid rgba(var(--dash-ok-rgb), 0.16);
    width: fit-content;
}

/* Sticky filter: durable glass + safe area */
.dash-filter-bar--sticky {
    inset-block-start: env(safe-area-inset-top, 0px);
    backdrop-filter: saturate(1.15) blur(12px);
    -webkit-backdrop-filter: saturate(1.15) blur(12px);
    border-color: color-mix(in srgb, var(--dash-border) 80%, transparent);
}

.dash-filter-bar .mud-input-control,
.dash-filter-bar .mud-select,
.dash-filter-bar .mud-autocomplete {
    margin-block: 0;
}

.dash-filter-bar .mud-input > input,
.dash-filter-bar .mud-select-input {
    font-variant-numeric: tabular-nums;
}

/* Inline alerts inherit shell radius */
.dash-shell > .mud-alert {
    border-radius: var(--dash-radius);
    border: 1px solid var(--dash-border);
    box-shadow: var(--dash-shadow), var(--dash-hairline);
}

/* Selection inside dashboards */
.dash-shell ::selection {
    background: rgba(var(--egk-color-primary-rgb), 0.18);
    color: inherit;
}

/* Dense metric rows inside widgets */
.dash-metric-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--egk-space-2);
    min-inline-size: 0;
    padding-block: 0.35rem;
}

.dash-metric-row + .dash-metric-row {
    border-block-start: 1px solid color-mix(in srgb, var(--dash-border) 70%, transparent);
}

.dash-metric-row__value {
    font-variant-numeric: tabular-nums;
    font-weight: var(--egk-weight-semibold);
    flex-shrink: 0;
}

/* Action stacks: premium filled primary, quieter outlines */
.dash-widget__body > .mud-stack .mud-button-outlined {
    border-color: color-mix(in srgb, var(--dash-border) 90%, var(--egk-color-primary));
}

.dash-widget__body > .mud-stack .mud-button-filled {
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.08);
}

/* Wave labels: slightly stronger presence on module boards */
.dash-cockpit--module .dash-wave__label {
    letter-spacing: 0.08em;
}

@container dash (max-width: 700px) {
    .dash-surface-card,
    .dash-shell .todo-insight-card,
    .dash-shell .entity-card {
        padding: var(--egk-space-2) var(--egk-space-3);
    }

    .dash-header__stamp {
        max-inline-size: 100%;
        white-space: normal;
    }
}

@media (hover: none) {
    .dash-surface-card--interactive:hover,
    .dash-shell .entity-card:hover,
    .dash-shell .todo-insight-card:hover {
        transform: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .dash-header,
    .dash-widget--flash {
        animation: none !important;
    }

    .dash-surface-card--interactive:hover,
    .dash-shell .entity-card:hover,
    .dash-shell .todo-insight-card:hover,
    .dash-glance__tile:hover {
        transform: none;
    }
}

@media print {
    .dash-widget {
        content-visibility: visible;
        contain: none;
    }

    .dash-header__kicker::before,
    .dash-glance__tile::after {
        display: none !important;
    }
}

.mud-theme-dark .dash-surface-card,
.mud-theme-dark .dash-shell .todo-insight-card,
.mud-theme-dark .dash-shell .entity-card {
    background: rgba(255, 255, 255, 0.03);
}

.mud-theme-dark .dash-header__stamp {
    background: rgba(var(--dash-ok-rgb), 0.14);
    border-color: rgba(var(--dash-ok-rgb), 0.28);
}
