﻿/*
 * ELOVIZ design system - "Eloviz Redesign" (claude.ai/design project d6dd7061).
 *
 * This file is the single source of the visual language: tokens first, then the
 * component classes the rewritten shell and pages are built from, then the
 * MudBlazor bridge that pulls the ~200 pages we did not hand-rewrite onto the
 * same palette and typography.
 *
 * Conventions
 *  - every colour, radius and font in here comes from a token; no literals in
 *    component rules, so a theme swap is a token swap
 *  - class prefix `e-`; a component owns its block and nothing outside it
 *  - numbers (process values) are always IBM Plex Mono + tabular-nums, so a
 *    changing live value never shifts its neighbours
 */

/* ============================================================ FONTS ======= */
/* self-hosted: a plant network is often air-gapped, and an HMI must not wait
   on fonts.googleapis.com. Latin + latin-ext only - cyrillic (ru) and CJK
   (jp/zh) fall back to the system UI font, which is what carries them anyway. */
@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 400 700; /* variable file, one per subset */
    font-display: swap;
    src: url('fonts/ibm-plex-sans-var-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('fonts/ibm-plex-sans-var-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/ibm-plex-mono-400-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/ibm-plex-mono-400-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('fonts/ibm-plex-mono-500-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('fonts/ibm-plex-mono-500-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('fonts/ibm-plex-mono-600-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('fonts/ibm-plex-mono-600-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* =========================================================== TOKENS ======= */
/*
 * Theme owns colour, the design owns form.
 *
 * Every colour token derives from the MudBlazor palette the selected ELOVIZ
 * theme produced, with the design's own value as the fallback. That keeps the
 * theme selector meaningful (all 25 themes, light and dark, still work and still
 * reach every design surface) while the design decides typography, spacing,
 * radii and the shape of every component.
 *
 * The tinted "wash" surfaces have no palette equivalent, so they are mixed from
 * the semantic colour and the current surface - which is what makes them come
 * out dark on a dark theme instead of staying pastel.
 *
 * Ship-default palette: installers/themes/Eloviz.scss (and Eloviz-dark.scss),
 * which carry exactly the values in the fallbacks below.
 */
:root {
    /* -- brand ------------------------------------------------------------ */
    --e-brand: var(--mud-palette-primary, #a51482);
    --e-brand-hover: var(--mud-palette-primary-darken, #7d0f62);
    --e-brand-on: var(--mud-palette-primary-text, #fff);
    --e-brand-wash: color-mix(in srgb, var(--e-brand) 8%, var(--e-surface));
    --e-brand-wash-2: color-mix(in srgb, var(--e-brand) 14%, var(--e-surface));
    --e-brand-select: color-mix(in srgb, var(--e-brand) 22%, var(--e-surface));
    /* -- neutrals --------------------------------------------------------- */
    --e-bg: var(--mud-palette-background-gray, #f4f5f7);
    --e-surface: var(--mud-palette-surface, #fff);
    --e-surface-sunken: color-mix(in srgb, var(--e-bg) 55%, var(--e-surface));
    --e-surface-inset: color-mix(in srgb, var(--e-bg) 35%, var(--e-surface));
    --e-surface-field: color-mix(in srgb, var(--e-bg) 70%, var(--e-surface));
    --e-surface-row: color-mix(in srgb, var(--e-bg) 80%, var(--e-surface));
    --e-border: var(--mud-palette-lines-default, #e3e5ea);
    --e-border-subtle: var(--mud-palette-table-lines, #eef0f3);
    --e-border-faint: color-mix(in srgb, var(--e-border) 45%, var(--e-surface));
    --e-border-input: var(--mud-palette-lines-inputs, #cfd3da);
    --e-text: var(--mud-palette-text-primary, #1d2129);
    --e-text-2: color-mix(in srgb, var(--e-text) 82%, var(--e-surface));
    --e-text-3: var(--mud-palette-text-secondary, #5b616e);
    --e-text-muted: color-mix(in srgb, var(--e-text-3) 78%, var(--e-surface));
    --e-text-faint: var(--mud-palette-text-disabled, #b3b8c2);
    /* -- semantic: normal / warning / alarm -------------------------------
       the "strong" variants are the readable-on-wash text colour, so they are
       mixed toward the text colour rather than being separate constants */
    --e-ok: var(--mud-palette-success, #73A839);
    --e-ok-strong: color-mix(in srgb, var(--e-ok) 70%, var(--e-text));
    --e-ok-wash: color-mix(in srgb, var(--e-ok) 12%, var(--e-surface));
    --e-ok-spark: color-mix(in srgb, var(--e-ok) 32%, var(--e-surface));
    --e-warn: var(--mud-palette-warning, #DD5600);
    --e-warn-strong: color-mix(in srgb, var(--e-warn) 62%, var(--e-text));
    --e-warn-text: color-mix(in srgb, var(--e-warn) 78%, var(--e-text));
    --e-warn-wash: color-mix(in srgb, var(--e-warn) 10%, var(--e-surface));
    --e-warn-line: color-mix(in srgb, var(--e-warn) 26%, var(--e-surface));
    --e-alarm: var(--mud-palette-error, #C71C22);
    --e-alarm-strong: color-mix(in srgb, var(--e-alarm) 66%, var(--e-text));
    --e-alarm-hover: color-mix(in srgb, var(--e-alarm) 82%, var(--e-text));
    --e-alarm-wash: color-mix(in srgb, var(--e-alarm) 10%, var(--e-surface));
    --e-alarm-wash-hover: color-mix(in srgb, var(--e-alarm) 18%, var(--e-surface));
    --e-alarm-line: color-mix(in srgb, var(--e-alarm) 24%, var(--e-surface));
    --e-alarm-line-2: color-mix(in srgb, var(--e-alarm) 34%, var(--e-surface));
    --e-alarm-row: color-mix(in srgb, var(--e-alarm) 4%, var(--e-surface));
    --e-info: var(--mud-palette-info, #2757a5);
    --e-info-strong: color-mix(in srgb, var(--e-info) 66%, var(--e-text));
    --e-info-wash: color-mix(in srgb, var(--e-info) 10%, var(--e-surface));
    --e-live: var(--mud-palette-tertiary, #20c997);
    --e-live-strong: color-mix(in srgb, var(--e-live) 60%, var(--e-text));
    --e-live-wash: color-mix(in srgb, var(--e-live) 10%, var(--e-surface));
    --e-live-line: color-mix(in srgb, var(--e-live) 26%, var(--e-surface));
    /* the header's translucent backdrop has to follow the surface, not be white */
    --e-header-bg: color-mix(in srgb, var(--e-surface) 92%, transparent);
}

/*
 * Typography and geometry are the design, not the theme. MudThemeProvider emits
 * its own `:root` block after this file, so these need to out-specify a bare
 * `:root` - `html:root` does that without !important and without touching the
 * palette above.
 */
html:root {
    --e-font: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    --e-font-mono: 'IBM Plex Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;
    --e-radius-sm: 4px;
    --e-radius: 6px;
    --e-radius-card: 8px;
    --e-sidebar-w: 258px;
    --e-header-h: 56px;
    --e-control-h: 34px; /* every toolbar control lines up on this */
    --e-shadow-pop: 0 4px 14px rgba(20, 20, 40, .08);
    /* MudBlazor's own form tokens, so the components we did not rewrite match */
    --mud-typography-default-family: var(--e-font);
    --mud-typography-h1-family: var(--e-font);
    --mud-typography-h2-family: var(--e-font);
    --mud-typography-h3-family: var(--e-font);
    --mud-typography-h4-family: var(--e-font);
    --mud-typography-h5-family: var(--e-font);
    --mud-typography-h6-family: var(--e-font);
    --mud-typography-subtitle1-family: var(--e-font);
    --mud-typography-subtitle2-family: var(--e-font);
    --mud-typography-body1-family: var(--e-font);
    --mud-typography-body2-family: var(--e-font);
    --mud-typography-button-family: var(--e-font);
    --mud-typography-caption-family: var(--e-font);
    --mud-typography-overline-family: var(--e-font);
    --mud-typography-button-transform: none;
    --mud-typography-button-weight: 500;
    --mud-default-borderradius: 6px;
    --mud-elevation-1: 0 1px 2px rgba(20, 20, 40, .05);
    --mud-elevation-2: 0 2px 6px rgba(20, 20, 40, .06);
    --mud-elevation-3: 0 4px 14px rgba(20, 20, 40, .08);
}

/* ============================================================= BASE ======= */
html {
    /* MudBlazor's own reset sets 16px; the design's scale is built on it */
    font-size: 16px;
}

body {
    margin: 0;
    background: var(--e-bg);
    color: var(--e-text);
    font-family: var(--e-font);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

::selection {
    background: var(--e-brand-select);
}

/*
 * Icons. The design draws Material Icons as ligature spans; we render the same
 * glyphs through MudBlazor's SVG icon set instead of shipping a ~300 KB icon
 * font for a second copy of iconography the app already carries. MudBlazor's
 * svg is `width/height: 1em`, so font-size is the size knob either way and the
 * design's sizing rules below apply unchanged.
 *
 * `.e-ico` is the base; the size comes from whichever component class sits
 * next to it, exactly as in the design.
 */
.e-ico {
    flex: 0 0 auto;
    line-height: 1;
    font-size: 18px;
    fill: currentColor;
    color: inherit;
    vertical-align: middle;
    user-select: none;
}

/* MudIcon renders `<svg class="mud-icon-root e-ico ...">`; its own size classes
   would override ours, so pin the box to the inherited font-size. */
svg.e-ico {
    width: 1em;
    height: 1em;
}

/* numbers: one class, used everywhere a process value is printed */
.e-num {
    font-family: var(--e-font-mono);
    font-variant-numeric: tabular-nums;
    font-weight: 500;
}

.e-sym {
    font-family: var(--e-font-mono);
    font-weight: 500;
    color: var(--e-brand);
}

.e-unit {
    font-family: var(--e-font);
    font-weight: 400;
    color: var(--e-text-muted);
}

/* ========================================================== LAYOUT ======= */
/*
 * The shell is viewport-capped: the document never scrolls. The page body
 * (.e-page) is the scroll container, so the scrollbar sits exactly beside
 * what scrolls - below the header and the view row, never across them.
 * Pages that render without .e-page (login, the print previews) fall back
 * to the main column's own scrollbar.
 */
.e-shell {
    height: 100vh;
    overflow: hidden;
    display: flex;
    align-items: stretch;
    background: var(--e-bg);
    color: var(--e-text);
}

.e-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
}

.e-page {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 18px 20px 28px;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

/* a page whose scrolling region is inside it (ElovizPage Fill): the trend
   pages keep title and toolbar fixed while only the e-fillscroll charts move */
.e-page--fill {
    overflow: hidden;
}

.e-fillscroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
}

/*
 * A trend set with a SINGLE chart fills the region exactly - no scrolling.
 * A solo chart is otherwise sized by a viewport guess (100vh minus a constant,
 * .e-trendchart--solo), which over- or undershoots the fill region; here the
 * flex chain hands the chart precisely the height that is left after title
 * and legend. Multi-chart sets keep their fixed heights and scroll.
 */
.e-fillscroll > .e-trendstack:has(> .e-trendstack__item:only-child) {
    flex: 1 1 auto;
    min-height: 0;
}

.e-fillscroll .e-trendstack__item:only-child {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    /* !important: the item historically carried MudBlazor's .flex-row utility
       (also !important), which flipped this into a row - title and legend then
       sat BESIDE the solo chart. The class is gone from the markup, but this
       keeps a stale binary from breaking the layout again. */
    flex-direction: column !important;
}

.e-fillscroll .e-trendstack__item:only-child .e-trendchart--solo {
    flex: 1 1 auto;
    min-height: 0;
    height: auto;
}

.e-page-head {
    display: flex;
    /* flex-start, not flex-end: bottom-aligning pushed the title down by however
       much taller a page's action buttons were, so the gap between the view row
       and the title differed from page to page */
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}

.e-page-title {
    font: 600 20px/1.2 var(--e-font);
    letter-spacing: -0.01em;
    margin: 0;
}

.e-page-sub {
    font: 400 13px/1.4 var(--e-font);
    color: var(--e-text-3);
}

.e-page-actions {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-items: center;
}

/* ========================================================= SIDEBAR ======= */
.e-sidebar {
    width: var(--e-sidebar-w);
    flex: 0 0 var(--e-sidebar-w);
    background: var(--e-surface);
    border-right: 1px solid var(--e-border);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow: hidden;
    z-index: 30;
}

.e-sidebar__brand {
    height: var(--e-header-h);
    flex: 0 0 var(--e-header-h);
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 16px;
    border-bottom: 1px solid var(--e-border);
}

/* the logo is customer-supplied artwork of unknown aspect ratio, so the height
   is pinned and the width is capped - `max-height` alone let an svg with no
   intrinsic box collapse to nothing */
.e-sidebar__brand a {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    min-width: 0;
}

.e-sidebar__brand img {
    display: block;
    height: 22px;
    width: auto;
    max-width: 110px;
    object-fit: contain;
}

/*
 * The brand tile.
 *
 * Every logo ELOVIZ ships is white artwork, drawn for the brand-coloured app bar
 * this design replaced - on a white sidebar it is an invisible image. The tile
 * gives that artwork the ground it was made for, so a plant keeps its own mark
 * without shipping a second asset. A deployment that configures
 * `Eloviz:LogoLight` with a dark-on-transparent logo gets no tile.
 */
.e-brandmark {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    background: var(--e-brand);
    border-radius: var(--e-radius);
    padding: 4px 6px;
    height: 32px;
    box-sizing: border-box;
}

.e-brandmark img {
    display: block;
    height: 22px;
    width: auto;
    max-width: 104px;
    object-fit: contain;
}

/* on the login pane the mark is the page's largest brand element */
.e-login__brandmark {
    height: 46px;
    padding: 6px 10px;
    width: fit-content;
}

.e-login__brandmark img {
    height: 34px;
    max-width: 200px;
}

.e-sidebar__rule {
    width: 1px;
    height: 20px;
    background: var(--e-border);
}

/* the product mark is branding text of unknown length - it truncates rather
   than pushing the logo out of the row */
.e-sidebar__wordmark {
    font: 600 13px/1 var(--e-font-mono);
    letter-spacing: .08em;
    color: var(--e-brand);
    text-decoration: none;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-sidebar__search {
    padding: 12px 12px 8px;
}

.e-searchbox {
    display: flex;
    align-items: center;
    gap: 8px;
    height: var(--e-control-h);
    padding: 0 10px;
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius);
    background: var(--e-surface-field);
    font: 400 13px/1 var(--e-font);
    color: var(--e-text-muted);
    cursor: pointer;
    width: 100%;
}

.e-searchbox:hover {
    border-color: var(--e-border-input);
}

.e-searchbox__text {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-align: left;
}

.e-kbd {
    font: 500 11px/1 var(--e-font-mono);
    color: var(--e-text-muted);
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius-sm);
    padding: 3px 5px;
    background: var(--e-surface);
}

/* -- command search (Ctrl+K) ----------------------------------------------- */
.e-cmdk {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.e-cmdk__box {
    display: flex;
    align-items: center;
    gap: 9px;
    height: 40px;
    padding: 0 12px;
    border: 1px solid var(--e-border-input);
    border-radius: var(--e-radius);
    background: var(--e-surface-field);
    color: var(--e-text-muted);
}

.e-cmdk__box:focus-within {
    border-color: var(--e-brand);
    box-shadow: 0 0 0 3px var(--e-brand-wash-2);
}

.e-cmdk__input {
    all: unset;
    flex: 1 1 auto;
    min-width: 0;
    font: 400 14px/1.2 var(--e-font);
    color: var(--e-text);
}

.e-cmdk__list {
    display: flex;
    flex-direction: column;
    gap: 1px;
    max-height: 420px;
    overflow-y: auto;
}

.e-cmdk__item {
    all: unset;
    box-sizing: border-box;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-radius: var(--e-radius);
    font: 400 13px/1.2 var(--e-font);
    color: var(--e-text-2);
}

.e-cmdk__item--on {
    background: var(--e-brand-wash);
    color: var(--e-brand);
}

.e-cmdk__item .e-ico {
    color: var(--e-text-muted);
    flex: 0 0 auto;
}

.e-cmdk__item--on .e-ico {
    color: var(--e-brand);
}

.e-cmdk__path {
    min-width: 0;
    font: 500 12.5px/1.2 var(--e-font-mono);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* a value row's second line: the path and name that say which value carries the tag */
.e-cmdk__name {
    flex: 1 1 auto;
    min-width: 0;
    font: 400 12px/1.2 var(--e-font);
    color: var(--e-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-cmdk__item--on .e-cmdk__name {
    color: var(--e-brand);
}

/* the section heading: pages, then values */
.e-cmdk__group {
    padding: 8px 10px 3px;
    font: 500 10.5px/1.3 var(--e-font);
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--e-text-muted);
}

/* a quiet line under a section: "only the first n values are shown" */
.e-cmdk__note {
    padding: 4px 10px 6px;
    font: 400 12px/1.3 var(--e-font);
    color: var(--e-text-muted);
}

/* -- the value page (/TagValue): the value beside its live tile, the facts as cards -- */
.e-tagvalue {
    display: grid;
    grid-template-columns: 360px minmax(0, 1fr);
    gap: 16px;
}

@media (max-width: 900px) {
    .e-tagvalue {
        grid-template-columns: minmax(0, 1fr);
    }
}

.e-tagvalue__hero {
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.e-tagvalue__row {
    display: flex;
    align-items: center;
    gap: 10px;
}

.e-tagvalue__big {
    display: flex;
    align-items: baseline;
    gap: 7px;
}

.e-tagvalue__number {
    font-size: 46px;
    line-height: 1;
    letter-spacing: -.02em;
}

.e-tagvalue__state {
    font-size: 30px;
    line-height: 1;
    overflow-wrap: anywhere;
}

.e-tagvalue__unit {
    font: 400 15px/1 var(--e-font);
}

.e-tagvalue__live {
    height: 22px;
}

.e-tagvalue__gauge {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.e-tagvalue__legend {
    display: flex;
    flex-direction: column;
    gap: 7px;
    border-top: 1px solid var(--e-border-faint);
    padding-top: 12px;
    font: 400 11.5px/1.3 var(--e-font);
    color: var(--e-text-3);
}

.e-tagvalue__legend > span {
    display: flex;
    align-items: center;
    gap: 8px;
}

.e-tagvalue__swatch {
    width: 22px;
    height: 9px;
    border-radius: 2px;
    background: var(--e-ok);
    opacity: .32;
    flex: 0 0 auto;
}

.e-tagvalue__swatch--alarm {
    background: var(--e-alarm);
    opacity: .8;
}

.e-tagvalue__facts {
    border-top: 1px solid var(--e-border-faint);
    padding-top: 12px;
}

/* the tile's height is the design's: the live panel fits it, the events list scrolls inside it */
.e-tagvalue__tile {
    display: flex;
    flex-direction: column;
    height: 402px;
}

.e-tagvalue__panel {
    padding: 14px 16px 10px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    flex: 1 1 auto;
    min-height: 0;
}

.e-tagvalue__nohistory {
    flex: 1 1 auto;
    min-height: 120px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    border: 1px dashed var(--e-border);
    border-radius: var(--e-radius);
    font: 400 12.5px/1.4 var(--e-font);
    color: var(--e-text-muted);
    text-align: center;
    padding: 12px;
}

.e-tagvalue__stats {
    border-top: 1px solid var(--e-border-faint);
    padding-top: 12px;
}

.e-tagvalue__stat--text {
    font-size: 13px;
}

.e-tagvalue__events {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

.e-tagvalue__events .e-card__foot {
    margin-top: auto;
}

.e-tagvalue__eventsnote {
    padding: 18px 16px;
    text-align: center;
}

.e-tagvalue__cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 16px;
}

/* key/value facts: a label column and a mono value column */
.e-kv {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 7px 14px;
    align-items: baseline;
    margin: 0;
}

.e-kv dt {
    font: 400 11.5px/1.4 var(--e-font);
    color: var(--e-text-muted);
    display: flex;
    align-items: center;
    gap: 7px;
}

.e-kv dd {
    margin: 0;
    font: 500 12px/1.4 var(--e-font-mono);
    color: var(--e-text);
    overflow-wrap: anywhere;
}

.e-kv__small {
    font-size: 11px;
}

.e-kv__dot {
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--e-warn);
    flex: 0 0 auto;
}

.e-kv__dot--alarm {
    background: var(--e-alarm);
}

/* a fold: the summary row opens the rest of the card */
.e-more {
    display: flex;
    flex-direction: column;
    min-height: 0;
}

.e-more__summary {
    all: unset;
    box-sizing: border-box;
    flex: 0 0 auto;
    cursor: pointer;
    padding: 10px 16px;
    font: 500 11.5px/1 var(--e-font);
    color: var(--e-text-3);
    display: flex;
    align-items: center;
    gap: 8px;
}

.e-more__summary:hover {
    background: var(--e-surface-row);
}

.e-more__summary[aria-expanded="true"] {
    border-bottom: 1px solid var(--e-border-subtle);
}

/* the value page fits the viewport (ElovizPage Fill): the fold's card takes the height
   that is left below the value, the tile and the cards, and its list scrolls inside.
   Closed, the card is its summary row. The page scrolls only as a fallback, when
   those alone need more than the viewport gives - a page column with overflow
   hidden would cut the cards off instead. The card's own overflow is hidden (its
   corners), so its minimum height has to be said: a flex item would otherwise
   shrink it to its borders. */
.e-page--fill:has(> .e-tagvalue__more) {
    overflow-y: auto;
}

.e-tagvalue__more {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
}

.e-tagvalue__more--open {
    flex: 1 1 auto;
    min-height: 140px;
}

.e-tagvalue__more > .e-more {
    flex: 1 1 auto;
}

.e-tagvalue__more .e-more__body {
    flex: 1 1 auto;
    min-height: 0;
    max-height: none;
}

/* the fold's list scrolls inside the card rather than running the page on - about
   eight rows; the table's own container must not scroll, or the sticky header
   would stick to it instead of to the fold */
.e-more__body {
    max-height: 320px;
    overflow-y: auto;
}

.e-more__body .mud-table.mud-table-sticky-header .mud-table-container {
    overflow: visible;
    max-height: none;
}

/* the state timeline of a non-numeric value: one segment per run of one state */
.e-timeline {
    display: flex;
    height: 40px;
    border-radius: var(--e-radius-sm);
    overflow: hidden;
    border: 1px solid var(--e-border-subtle);
    background: var(--e-surface-sunken);
}

.e-timeline__seg {
    flex: 0 0 auto;
    background: var(--e-ok);
    opacity: .32;
}

.e-timeline__seg--warn {
    background: var(--e-warn);
    opacity: .6;
}

.e-timeline__seg--alarm {
    background: var(--e-alarm);
    opacity: .8;
}

.e-timeline__seg--muted {
    background: var(--e-text-muted);
    opacity: .3;
}

.e-timeline__axis {
    display: flex;
    justify-content: space-between;
    font: 400 10.5px/1 var(--e-font-mono);
    color: var(--e-text-muted);
}

.e-adminlist__dot--alarm {
    background: var(--e-alarm);
}

.e-cmdk__page {
    margin-left: auto;
    flex: 0 0 auto;
    font: 400 12px/1 var(--e-font);
    color: var(--e-text-muted);
}

.e-cmdk__item--on .e-cmdk__page {
    color: var(--e-brand);
}

.e-cmdk__empty {
    padding: 18px;
    text-align: center;
    font: 400 13px/1.4 var(--e-font);
    color: var(--e-text-muted);
}

.e-nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 4px 8px 8px;
}

.e-nav__item {
    all: unset;
    box-sizing: border-box;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 10px;
    height: var(--e-control-h);
    padding: 0 10px;
    border-radius: var(--e-radius);
    font: 400 13.5px/1 var(--e-font);
    color: var(--e-text-2);
    text-decoration: none;
}

.e-nav__item:hover {
    background: var(--e-bg);
    text-decoration: none;
    color: var(--e-text-2);
}

.e-nav__item--on {
    background: var(--e-brand-wash);
    color: var(--e-brand);
    font-weight: 600;
}

.e-nav__item--on:hover {
    background: var(--e-brand-wash);
    color: var(--e-brand);
}

.e-nav__icon {
    font-size: 18px;
    color: var(--e-text-muted);
    flex: 0 0 18px;
}

.e-nav__item--on .e-nav__icon {
    color: var(--e-brand);
}

.e-nav__label {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-nav__badge {
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 9px;
    background: var(--e-text-3);
    color: var(--e-surface);
    font: 600 11px/18px var(--e-font-mono);
    text-align: center;
    flex: 0 0 auto;
}

.e-nav__badge--alarm {
    background: var(--e-alarm);
}

.e-nav__badge--warn {
    background: var(--e-warn);
}

/*
 * A nav row that opens a menu has to be indistinguishable from one that
 * navigates. MudMenu's root is a shrink-to-fit flex box and its activator is
 * `display: contents`, so without this the row wrapped to its own text width and
 * sat centred - reading as an indented submenu rather than a top-level row.
 */
.e-nav > .mud-menu {
    display: block;
    width: 100%;
}

.e-nav > .mud-menu > .mud-menu-activator {
    display: block;
    width: 100%;
}

/*
 * A nav row whose destinations only the user knows (the user-defined charts) keeps
 * its chevron: the plant tree cannot answer "which one", and a flyout would hide
 * the list behind a hover. The chevron is the tree's, so the two expanders in the
 * sidebar read as one thing; the row itself still navigates.
 */
.e-nav__chev {
    font-size: 15px;
    color: var(--e-text-faint);
    width: 15px;
    flex: 0 0 15px;
    display: flex;
    align-items: center;
}

.e-nav__item--on .e-nav__chev {
    color: var(--e-brand);
}

/* the quick links under it: the icon column's width, so they hang off the label */
.e-nav__item--sub {
    height: 26px;
    padding-left: 38px;
    font-size: 13px;
    color: var(--e-text-3);
}

.e-nav__item--quiet {
    color: var(--e-text-faint);
    cursor: default;
    font-style: italic;
}

.e-nav__item--quiet:hover {
    background: none;
}

/* -- the user trend configuration panel (design 1c) ------------------------
 * A docked surface beside the charts, not a dialog: three lists on one panel,
 * the chart selected in the first is what the other two edit, and every change
 * redraws the chart next to it. The sizes are the design's; every colour is a
 * token, so the panel comes out dark on a dark theme like the rest of the shell.
 */
.e-cfglayout {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    gap: 14px;
}

.e-cfglayout__charts {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.e-cfg {
    flex: 0 0 340px;
    align-self: stretch;
    background: var(--e-surface);
    border: 1px solid var(--e-border);
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.e-cfg__head {
    padding: 12px 14px;
    border-bottom: 1px solid var(--e-border-subtle);
    display: flex;
    align-items: center;
    gap: 8px;
}

.e-cfg__title {
    font: 600 13px/1.2 var(--e-font);
    color: var(--e-text);
    flex: 1 1 auto;
}

.e-cfg__dirty {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 22px;
    padding: 0 8px;
    border-radius: 11px;
    background: var(--e-warn-wash);
    font: 600 10.5px/1 var(--e-font);
    color: var(--e-warn-text);
    flex: 0 0 auto;
}

.e-cfg__dot {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--e-warn);
}

.e-cfg__body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 12px 14px;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.e-cfg__section {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.e-cfg__label {
    font: 500 10.5px/1 var(--e-font);
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--e-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* -- charts in this set -- */
.e-cfg__row {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 34px;
    padding: 0 8px;
    border-radius: var(--e-radius);
    border: 1px solid transparent;
    background: none;
    cursor: pointer;
}

.e-cfg__row:hover {
    background: var(--e-surface-row);
}

.e-cfg__row--on {
    border-color: var(--e-brand);
    background: var(--e-brand-wash);
}

.e-cfg__grip {
    color: var(--e-text-faint);
    cursor: grab;
    flex: 0 0 auto;
    display: inline-flex;
}

.e-cfg__rowname {
    all: unset;
    box-sizing: border-box;
    flex: 1 1 auto;
    min-width: 0;
    font: 400 12px/1 var(--e-font);
    color: var(--e-text-2);
    padding: 5px 4px;
    border-radius: var(--e-radius-sm);
    cursor: text;
    text-overflow: ellipsis;
}

.e-cfg__row--on .e-cfg__rowname {
    font-weight: 600;
    color: var(--e-brand);
}

.e-cfg__rowname:focus {
    background: var(--e-surface);
    box-shadow: inset 0 0 0 1px var(--e-border-input);
}

.e-cfg__count {
    font: 400 11px/1 var(--e-font-mono);
    color: var(--e-text-muted);
    flex: 0 0 auto;
}

.e-cfg__add {
    all: unset;
    box-sizing: border-box;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 32px;
    border-radius: var(--e-radius);
    border: 1px dashed var(--e-border-input);
    font: 600 11.5px/1 var(--e-font);
    color: var(--e-text-3);
}

.e-cfg__add:hover {
    background: var(--e-surface-row);
}

/* -- one axis -- */
.e-cfg__axis {
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius);
    padding: 9px 10px;
    display: flex;
    flex-direction: column;
    gap: 7px;
    background: var(--e-surface-inset);
}

.e-cfg__axishead {
    display: grid;
    grid-template-columns: 20px minmax(0, 1fr) 48px;
    gap: 7px;
    align-items: center;
}

.e-cfg__side {
    display: inline-grid;
    place-items: center;
    width: 20px;
    height: 20px;
    border-radius: var(--e-radius-sm);
    background: var(--e-brand-wash-2);
    font: 600 10px/1 var(--e-font-mono);
    color: var(--e-brand);
}

.e-cfg__axisgrid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 40px;
    gap: 6px;
    align-items: center;
}

.e-cfg__cap {
    font: 500 9.5px/1 var(--e-font);
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--e-text-muted);
}

.e-cfg__cap--center {
    text-align: center;
}

.e-cfg__in {
    all: unset;
    box-sizing: border-box;
    width: 100%;
    font: 500 12px/1 var(--e-font);
    color: var(--e-text);
    padding: 6px 7px;
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius-sm);
    background: var(--e-surface);
}

.e-cfg__in:focus {
    border-color: var(--e-brand);
}

.e-cfg__in--mono {
    font: 500 11.5px/1 var(--e-font-mono);
    padding: 6px;
}

.e-cfg__in--center {
    text-align: center;
    padding: 6px 4px;
}

.e-cfg__axisbtns {
    display: flex;
    gap: 5px;
}

.e-cfg__abtn {
    all: unset;
    box-sizing: border-box;
    cursor: pointer;
    flex: 1 1 0;
    text-align: center;
    height: 24px;
    border-radius: var(--e-radius-sm);
    border: 1px solid var(--e-border);
    background: var(--e-surface);
    font: 600 10.5px/24px var(--e-font);
    color: var(--e-text-3);
}

.e-cfg__abtn:hover {
    background: var(--e-surface-row);
}

/* the one of the pair that describes the scale the axis actually has */
.e-cfg__abtn--on {
    border-color: color-mix(in srgb, var(--e-brand) 40%, var(--e-surface));
    background: var(--e-brand-wash);
    color: var(--e-brand);
}

.e-cfg__abtn--on:hover {
    background: var(--e-brand-wash-2);
}

.e-cfg__abtn[disabled] {
    opacity: .5;
    cursor: default;
}

/* -- one line -- */
.e-cfg__line {
    display: flex;
    align-items: center;
    gap: 7px;
    height: 34px;
    padding: 0 8px;
    border-radius: var(--e-radius);
    border: 1px solid var(--e-border-subtle);
    background: var(--e-surface);
}

.e-cfg__swatch {
    width: 12px;
    height: 3px;
    border-radius: 2px;
    flex: 0 0 12px;
}

/*
 * A row that stands for several lines of one quantity: the chevron opens it, the
 * count says how many, and the L/R and the remove act on all of them.
 */
.e-cfg__line--group {
    background: var(--e-surface-inset);
}

.e-cfg__chev {
    all: unset;
    box-sizing: border-box;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    color: var(--e-text-faint);
    flex: 0 0 15px;
    margin-left: -3px;
}

.e-cfg__n {
    font: 500 10.5px/18px var(--e-font-mono);
    color: var(--e-text-muted);
    background: var(--e-surface-row);
    border-radius: 9px;
    padding: 0 7px;
    flex: 0 0 auto;
}

/* the members of an opened group: indented under it, and only removable */
.e-cfg__line--sub {
    margin-left: 14px;
    height: 28px;
    border-color: transparent;
    background: none;
}

.e-cfg__more {
    font: 400 11px/1.4 var(--e-font);
    color: var(--e-text-muted);
    padding: 2px 2px 2px 16px;
}

.e-cfg__sym {
    font: 500 11px/1 var(--e-font-mono);
    color: var(--e-text-3);
    flex: 0 0 66px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/*
 * The scope the line comes from, not the whole tag path: the symbol column
 * already says which quantity it is, so on a chart of 60 element voltages the
 * path column was 60 identical "…lementVoltage" strings. The scope is what
 * tells the rows apart.
 */
.e-cfg__path {
    flex: 1 1 auto;
    min-width: 0;
    font: 400 11px/1 var(--e-font-mono);
    color: var(--e-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-cfg__sides {
    display: inline-flex;
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius-sm);
    overflow: hidden;
    flex: 0 0 auto;
}

.e-cfg__sidebtn {
    all: unset;
    box-sizing: border-box;
    cursor: pointer;
    width: 24px;
    height: 22px;
    text-align: center;
    font: 600 10px/22px var(--e-font-mono);
    background: var(--e-surface);
    color: var(--e-text-muted);
}

.e-cfg__sidebtn--on {
    background: var(--e-brand);
    color: var(--e-brand-on);
}

/* -- the tag search -- */
.e-cfg__search {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 34px;
    padding: 0 10px;
    border: 1px solid var(--e-border-input);
    border-radius: var(--e-radius);
    background: var(--e-surface);
    color: var(--e-text-muted);
    box-sizing: border-box;
}

.e-cfg__search input {
    all: unset;
    flex: 1 1 auto;
    min-width: 0;
    font: 400 12px/1 var(--e-font);
    color: var(--e-text);
}

/*
 * One row of the search results. The row is a box, not the button: a folded row
 * carries the chevron that opens it beside the body that adds the whole group,
 * and a button inside a button is not a thing.
 */
.e-cfg__hit {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 0 8px;
    border-radius: var(--e-radius);
    background: var(--e-surface-inset);
    font: 400 11.5px/1.2 var(--e-font);
    color: var(--e-text-2);
}

.e-cfg__hit:hover {
    background: var(--e-surface-row);
}

.e-cfg__hitbody {
    all: unset;
    box-sizing: border-box;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1 1 auto;
    min-width: 0;
    padding: 6px 0;
}

/* the members of an opened group: indented under it, and only addable one by one */
.e-cfg__hit--sub {
    margin-left: 14px;
    background: none;
}

.e-cfg__hit--sub .e-cfg__hitbody {
    padding: 3px 0;
}

.e-cfg__hit--sub .e-cfg__hitpath {
    flex: 1 1 auto;
    max-width: none;
}

.e-cfg__hitsym {
    font: 500 11px/1 var(--e-font-mono);
    color: var(--e-brand);
    flex: 0 0 66px;
    overflow: hidden;
    white-space: nowrap;
}

.e-cfg__hitdesc {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-cfg__hitpath {
    font: 400 11px/1 var(--e-font-mono);
    color: var(--e-text-muted);
    flex: 0 0 auto;
    max-width: 40%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-cfg__hitadd {
    color: var(--e-ok);
    flex: 0 0 auto;
}

.e-cfg__none {
    font: 400 11.5px/1.4 var(--e-font);
    color: var(--e-text-muted);
    padding: 4px 2px;
}

/* -- the set-level actions, at the foot of the panel rather than in a dialog -- */
.e-cfg__foot {
    border-top: 1px solid var(--e-border-subtle);
    padding: 10px 14px;
    display: flex;
    gap: 8px;
}

/* the small row-action icon button the panel's lists use */
.e-iconbtn--sm {
    width: 22px;
    height: 22px;
    flex: 0 0 22px;
}

/* the chart card the panel is editing, marked in the stack beside it */
/*
 * Below the design's split the panel stops being a column beside the charts and
 * becomes a band under them - 340px of panel plus a readable chart does not fit
 * on a tablet in portrait.
 */
@media (max-width: 1100px) {
    .e-cfglayout {
        flex-direction: column;
    }

    .e-cfg {
        flex: 0 0 auto;
        max-height: 46vh;
    }
}

/* -- the cursor readout (design 3a) ----------------------------------------
 * The dialog that opens on a click in a chart. Its table is NOT the generic
 * .e-table: the design gives this one no card, sentence-case headings, every
 * column left aligned - the numbers too - and its own paddings, so the metrics
 * below are the artboard's rather than the shared table's.
 *
 * The pager is gone: every line is in one scroll region, rendered through
 * Virtualize, which is why the rows carry a fixed height.
 */
.e-cursordlg {
    /* the artboard's card is 1400px wide; full width beyond that only stretches
       seven columns across a 2560px screen */
    max-width: 1400px;
}

/*
 * The artboard gives this dialog 20px gutters, where the shared chrome has 16.
 * Doubled up on .mud-dialog because the shared rules are further down the file
 * and would otherwise win on source order at equal specificity; the title's
 * padding-right is left alone - that is the room MudBlazor's close button needs.
 */
.mud-dialog.e-cursordlg .mud-dialog-title {
    padding-left: 20px;
}

.mud-dialog.e-cursordlg .mud-dialog-content {
    padding: 12px 20px 18px;
}

.e-cursor {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.e-cursor__head,
.e-cursor__filters,
.e-cursor__row {
    display: grid;
    align-items: center;
    min-width: 0;
}

.e-cursor__head {
    border-bottom: 1px solid var(--e-border);
    padding: 8px 0;
}

.e-cursor__th {
    all: unset;
    box-sizing: border-box;
    cursor: pointer;
    font: 700 12.5px/1 var(--e-font);
    color: var(--e-text);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-cursor__th:hover {
    color: var(--e-brand);
}

/* -- the per-column search row -- */
.e-cursor__filters {
    gap: 10px;
    border-bottom: 1px solid var(--e-border-subtle);
    padding: 6px 0;
}

.e-cursor__filter {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    /* the design's underline: the box is the full column, not a short field */
    border-bottom: 1px solid var(--e-border-input);
    padding-bottom: 3px;
    color: var(--e-text-muted);
}

.e-cursor__filter input {
    all: unset;
    flex: 1 1 auto;
    min-width: 0;
    height: 22px;
    font: 400 12.5px/22px var(--e-font);
    color: var(--e-text);
}

/* -- the scroll region -- */
.e-cursor__rows {
    max-height: 352px;
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;
}

.e-cursor__row {
    /* 11px over and under the design's 12.5px line; fixed so Virtualize can count */
    height: 35px;
}

/* the design stripes the rows instead of ruling them */
.e-cursor__row--alt {
    background: var(--e-surface-inset);
}

.e-cursor__cell {
    min-width: 0;
    font: 400 12.5px/1 var(--e-font);
    color: var(--e-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* numbers are mono and tabular, but LEFT aligned - the design's columns are */
.e-cursor__cell--num {
    font: 400 12.5px/1 var(--e-font-mono);
    font-variant-numeric: tabular-nums;
}

/* an out-of-band value is also heavier, so it reads as a value and not a tint */
.e-cursor__cell--num.e-val--alarm,
.e-cursor__cell--num.e-val--warn {
    font-weight: 600;
}

.e-cursor__cell--tag {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--e-text-muted);
}

.e-cursor__cell--count {
    font: 400 12.5px/1 var(--e-font-mono);
    color: var(--e-text-muted);
}

.e-cursor__scope {
    font: 400 12.5px/1 var(--e-font-mono);
    color: var(--e-text-3);
    margin-right: 6px;
}

.e-cursor__sym {
    font: 400 12.5px/1 var(--e-font-mono);
}

.e-cursor__empty {
    padding: 18px 0;
    font: 400 12.5px/1 var(--e-font);
    color: var(--e-text-muted);
    text-align: center;
}

/* -- the foot: how many, and why there is no pager -- */
.e-cursor__foot {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 0 4px;
    border-top: 1px solid var(--e-border-subtle);
    font: 400 11.5px/1 var(--e-font);
}

.e-cursor__count {
    font-family: var(--e-font-mono);
    color: var(--e-text-3);
}

.e-cursor__hint {
    color: var(--e-text-faint);
}

/* -- the physical-quantity selector ----------------------------------------
 * A MudSelectExtended: it carries the search box and the filter syntax, so it is
 * skinned rather than rebuilt. `.e-qsel` is the closed control in a page header,
 * which has to line up with the e-btn next to it; `.e-qsel-pop` is the panel.
 */
.e-qsel.mud-input-control {
    margin: 0;
    min-width: 0;
    flex: 0 0 auto;
}

.e-qsel .mud-input-control-input-container {
    margin-top: 0;
}

/* repeats MudBlazor's own variant classes, as the .e-filters rules do: Mud's
   compound selectors tie a plain `.e-qsel .mud-input` and keep their own box */
.e-qsel .mud-input.mud-input-text,
.e-qsel .mud-input.mud-input-outlined,
.e-qsel .mud-input.mud-input-filled {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    height: var(--e-control-h);
    min-width: 190px;
    padding: 0 6px 0 12px;
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius);
    background: var(--e-surface);
    font: 500 12px/1 var(--e-font);
    color: var(--e-text-2);
    margin: 0;
}

/* Material's underline and its focus bar are not the design's box */
.e-qsel .mud-input.mud-input-text::before,
.e-qsel .mud-input.mud-input-text::after,
.e-qsel .mud-input-underline::before,
.e-qsel .mud-input-underline::after {
    display: none;
}

.e-qsel .mud-input-slot,
.e-qsel input {
    font: 500 12px/1 var(--e-font);
    color: var(--e-text-2);
    padding: 0;
}

.e-qsel .mud-input-adornment,
.e-qsel .mud-input-adornment .mud-icon-root {
    font-size: 18px;
    color: var(--e-text-muted);
}

/* -- the panel -- */
.e-qsel-pop.mud-popover {
    /* The panel sized itself to the longest description, which put its right edge
       past the window when the control sits in a page header. !important is the
       one thing that works here: MudBlazor writes `max-width: none` as an INLINE
       style on the popover, which no selector can out-specify. */
    max-width: min(560px, calc(100vw - 32px)) !important;
    border-radius: var(--e-radius);
    background: var(--e-surface);
    /*
     * The 1px frame is drawn as a shadow ring rather than a border, and the panel
     * does not scroll: MudBlazor caps the popover AND the list inside it at the
     * same MaxHeight and puts overflow-y: auto on both. A real border is inside
     * that cap (border-box), so the content box came out 2px shorter than the list
     * and the panel grew a second scrollbar of its own. A ring costs no layout
     * height, so the two heights agree and the list is the only scroller; hidden
     * also clips the list's square corners to the radius.
     */
    box-shadow: 0 0 0 1px var(--e-border), 0 8px 28px rgba(20, 20, 40, .10);
    overflow: hidden;
}

.e-qsel-pop .mud-list-item {
    padding: 6px 10px;
    min-height: 0;
}

/* -- one quantity: identifier, name, description, unit, on one ellipsed line -- */
.e-qsel-item {
    display: grid;
    grid-template-columns: minmax(0, auto) minmax(0, 1fr) 40px;
    grid-template-areas:
        "id   id   unit"
        "name desc desc";
    column-gap: 8px;
    align-items: baseline;
    width: 100%;
    min-width: 0;
}

.e-qsel-item > span {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-qsel-item__id {
    grid-area: id;
    font: 600 12px/1.5 var(--e-font-mono);
    color: var(--e-text);
}

.e-qsel-item__name {
    grid-area: name;
    font: 400 12px/1.4 var(--e-font);
    color: var(--e-text-2);
}

.e-qsel-item__desc {
    grid-area: desc;
    font: 400 11.5px/1.4 var(--e-font);
    color: var(--e-text-muted);
}

.e-qsel-item__unit {
    grid-area: unit;
    justify-self: end;
    font: 400 11px/1.5 var(--e-font-mono);
    color: var(--e-text-muted);
}

/* -- choosing a time range ---------------------------------------------------
 * The range is drawn across two months rather than typed into four fields: the
 * calendar owns the days, the two ends stay typeable for a timestamp read off
 * the journal, and the clock behind each time sets it without the keyboard.
 */
.e-rangedlg .mud-dialog-content {
    padding: 0;
}

.e-range {
    display: flex;
    align-items: stretch;
    min-width: 0;
}

/* -- the calendar column -- */
.e-range__cal {
    flex: 1 1 auto;
    min-width: 0;
    padding: 14px 16px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.e-range__months {
    display: flex;
    align-items: center;
    gap: 10px;
}

.e-range__month {
    flex: 1 1 0;
    text-align: center;
    font: 600 12.5px/1 var(--e-font);
    color: var(--e-text);
}

.e-range__grids {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 24px;
}

/* -- one month -- */
.e-cal__grid {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    /* no column gap: the range fill has to run unbroken across a week */
    gap: 2px 0;
}

.e-cal__wd {
    display: grid;
    place-items: center;
    height: 22px;
    font: 500 10.5px/1 var(--e-font);
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--e-text-muted);
}

.e-cal__d {
    all: unset;
    box-sizing: border-box;
    cursor: pointer;
    display: grid;
    place-items: center;
    height: 30px;
    border-radius: var(--e-radius);
    font: 400 12.5px/1 var(--e-font-mono);
    color: var(--e-text);
}

.e-cal__d:hover {
    background: var(--e-surface-row);
}

.e-cal__d--out {
    color: var(--e-text-faint);
}

/* today is marked even when it is outside the range */
.e-cal__d--today {
    box-shadow: inset 0 0 0 1px var(--e-border-input);
}

/* the fill runs edge to edge, so only the two ends are rounded */
.e-cal__d--in {
    background: var(--e-brand-wash);
    border-radius: 0;
}

.e-cal__d--in:hover {
    background: var(--e-brand-wash-2);
}

.e-cal__d--from,
.e-cal__d--to,
.e-cal__d--only {
    background: var(--e-brand);
    color: var(--e-brand-on);
    font-weight: 600;
}

.e-cal__d--from {
    border-radius: var(--e-radius) 0 0 var(--e-radius);
}

.e-cal__d--to {
    border-radius: 0 var(--e-radius) var(--e-radius) 0;
}

.e-cal__d--from:hover,
.e-cal__d--to:hover,
.e-cal__d--only:hover {
    background: var(--e-brand-hover);
}

/* -- the two ends, and the duration between them -- */
.e-range__ends {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    gap: 12px;
    align-items: end;
    border-top: 1px solid var(--e-border-subtle);
    padding-top: 14px;
}

.e-range__end {
    display: flex;
    flex-direction: column;
    gap: 5px;
    min-width: 0;
}

.e-range__box {
    position: relative;
    display: flex;
    align-items: center;
    height: var(--e-control-h);
    padding: 0 10px;
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius);
    background: var(--e-surface);
    gap: 8px;
}

.e-range__box:focus-within {
    border-color: var(--e-brand);
}

.e-range__box--bad {
    border-color: var(--e-alarm);
}

.e-range__sep {
    width: 1px;
    height: 16px;
    background: var(--e-border);
    flex: 0 0 1px;
}

.e-range__date,
.e-range__time {
    all: unset;
    box-sizing: border-box;
    min-width: 0;
    font: 500 13px/1 var(--e-font-mono);
    color: var(--e-text);
}

.e-range__date {
    flex: 1 1 auto;
}

.e-range__time {
    flex: 0 0 44px;
    text-align: right;
    /* it opens the clock as well as taking a typed time */
    cursor: pointer;
}

/*
 * The clock behind a time: hours in one column, minutes in the other, which is
 * the calendar's own vocabulary rather than a Material clock face. The field it
 * hangs off still takes a typed time, for one that is not on the five-minute grid.
 */
.e-timepick__scrim {
    position: fixed;
    inset: 0;
    z-index: 10;
}

.e-timepick {
    position: absolute;
    z-index: 11;
    /* upwards, over the calendar: the two ends sit at the foot of the dialog and
       a downward popover is clipped by its content box */
    bottom: calc(100% + 4px);
    right: -1px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 8px;
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius);
    background: var(--e-surface);
    box-shadow: 0 8px 28px rgba(20, 20, 40, .10);
}

.e-timepick__label {
    font: 500 10.5px/1 var(--e-font);
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--e-text-muted);
    padding: 2px 2px 0;
}

/* six across: 24 hours in four rows, twelve five-minute steps in two */
.e-timepick__grid {
    display: grid;
    grid-template-columns: repeat(6, 32px);
    gap: 2px;
}

.e-timepick__cell {
    all: unset;
    box-sizing: border-box;
    cursor: pointer;
    display: grid;
    place-items: center;
    height: 26px;
    border-radius: var(--e-radius-sm);
    font: 500 12.5px/1 var(--e-font-mono);
    color: var(--e-text-2);
}

.e-timepick__cell:hover {
    background: var(--e-surface-row);
}

.e-timepick__cell--on {
    background: var(--e-brand);
    color: var(--e-brand-on);
    font-weight: 600;
}

.e-timepick__cell--on:hover {
    background: var(--e-brand-hover);
}

.e-range__duration {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    padding-bottom: 9px;
}

.e-range__dur {
    display: inline-flex;
    align-items: center;
    height: 24px;
    padding: 0 10px;
    border-radius: 12px;
    background: var(--e-brand-wash);
    font: 600 12px/1 var(--e-font-mono);
    color: var(--e-brand);
    white-space: nowrap;
}

/* a range that runs backwards says so, where the duration would have been */
.e-range__dur--bad {
    background: var(--e-alarm-wash);
    color: var(--e-alarm-strong);
    font-family: var(--e-font);
    font-weight: 500;
}

.e-range__gap {
    flex: 1 1 auto;
}

/* -- the two-way switch the footer carries (timezone) -- */
.e-seg {
    display: inline-flex;
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius);
    overflow: hidden;
    background: var(--e-surface);
    flex: 0 0 auto;
}

.e-seg__btn {
    all: unset;
    box-sizing: border-box;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    height: 30px;
    padding: 0 12px;
    font: 500 11.5px/1 var(--e-font);
    color: var(--e-text-muted);
}

.e-seg__btn:hover {
    background: var(--e-surface-row);
}

.e-seg__btn--on {
    background: var(--e-brand);
    color: var(--e-brand-on);
    font-weight: 600;
}

.e-seg__btn--on:hover {
    background: var(--e-brand-hover);
}

/*
 * Below the design's split the two months stop fitting side by side; the one
 * the range ends in is what is left.
 */
@media (max-width: 880px) {
    .e-range__grids {
        grid-template-columns: minmax(0, 1fr);
    }

    /* the second month is the one the range ends in, so the first one goes */
    .e-range__grids > :first-child,
    .e-range__months > .e-range__month:first-of-type {
        display: none;
    }
}

/* -- plant tree panel ------------------------------------------------------ */
.e-treepanel {
    border-top: 1px solid var(--e-border);
    margin-top: 4px;
    padding: 12px 8px 4px;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.e-treepanel__title {
    font: 600 11px/1 var(--e-font);
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--e-text-muted);
    padding-left: 10px;
}

.e-treepanel__action {
    all: unset;
    cursor: pointer;
    font-size: 16px;
    color: var(--e-text-muted);
    padding-right: 8px;
}

.e-treepanel__action:hover {
    color: var(--e-text-2);
}

.e-tree {
    flex: 1 1 auto;
    min-height: 120px;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 0 8px 8px;
}

.e-tree__row {
    display: flex;
    align-items: center;
    gap: 7px;
    height: 30px;
    border-radius: var(--e-radius);
    cursor: pointer;
    padding-right: 8px;
    text-decoration: none;
}

.e-tree__row:hover {
    background: var(--e-bg);
    text-decoration: none;
}

.e-tree__row--on {
    background: var(--e-brand-wash);
}

.e-tree__row--on:hover {
    background: var(--e-brand-wash);
}

.e-tree__chev {
    font-size: 15px;
    color: var(--e-text-faint);
    width: 15px;
    flex: 0 0 15px;
}

.e-tree__dot {
    width: 7px;
    height: 7px;
    border-radius: 2px;
    flex: 0 0 7px;
    background: var(--e-ok);
}

.e-tree__label {
    flex: 1 1 auto;
    font: 400 13px/1 var(--e-font);
    color: var(--e-text-2);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-tree__row--on .e-tree__label {
    font-weight: 600;
}

.e-tree__value {
    font: 500 11.5px/1 var(--e-font-mono);
    color: var(--e-text-muted);
    flex: 0 0 auto;
}

/* -- user footer ----------------------------------------------------------- */
.e-sidebar__user {
    margin-top: auto;
    border-top: 1px solid var(--e-border);
    padding: 10px 12px;
    display: flex;
    align-items: center;
    gap: 10px;
}

/* the signed-in user opens the personal menu (sign out, own password); its
   MudMenu root must fill the row like the plain flex children did */
.e-sidebar__user > .mud-menu {
    flex: 1 1 auto;
    min-width: 0;
}

.e-sidebar__user-btn {
    all: unset;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-width: 0;
    cursor: pointer;
    border-radius: var(--e-radius);
    padding: 3px 4px;
    margin: -3px -4px;
}

.e-sidebar__user-btn:hover {
    background: var(--e-bg);
}

.e-avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--e-brand-wash-2);
    color: var(--e-brand);
    display: grid;
    place-items: center;
    font: 600 12px/1 var(--e-font-mono);
    flex: 0 0 28px;
    text-transform: uppercase;
}

.e-sidebar__user-name {
    font: 500 12.5px/1.2 var(--e-font);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-sidebar__user-role {
    font: 400 11px/1.2 var(--e-font);
    color: var(--e-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ========================================================== HEADER ======= */
.e-header {
    position: sticky;
    top: 0;
    z-index: 20;
    background: var(--e-header-bg);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--e-border);
}

.e-header__bar {
    min-height: var(--e-header-h);
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px 14px;
    padding: 9px 20px;
    position: relative; /* anchors the centred license chip */
}

/* the license state, FIXED in the middle of the header bar; nothing while the
   license is valid. Absolutely centred on purpose: it must not drift with the
   width of the crumbs on the left. Two classes deep: the chip base class
   opens with `all: unset` and sits later in this file, so a single-class
   selector would lose its position to the reset. */
.e-header__bar .e-header__license {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    z-index: 1;
}

.e-crumbs {
    display: flex;
    align-items: center;
    gap: 7px;
    font: 400 13px/1.4 var(--e-font);
    color: var(--e-text-muted);
    /* shrink-to-content, not greedy: the free middle space has to stay free
       for the centred license chip; the chips pin themselves right anyway */
    flex: 0 1 auto;
    min-width: 140px;
    white-space: nowrap;
    overflow: hidden;
    list-style: none;
    margin: 0;
    padding: 0;
}

.e-crumbs a {
    color: var(--e-text-muted);
    text-decoration: none;
}

.e-crumbs a:hover {
    color: var(--e-brand);
    text-decoration: underline;
}

.e-crumbs__sep {
    color: var(--e-border-input);
}

.e-crumbs__leaf {
    font-weight: 600;
    color: var(--e-text);
    overflow: hidden;
    text-overflow: ellipsis;
}

/* prev / current / next stepper */
.e-stepper {
    display: flex;
    align-items: center;
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius);
    overflow: hidden;
    background: var(--e-surface);
    flex: 0 0 auto;
}

.e-stepper__btn {
    all: unset;
    cursor: pointer;
    font-size: 17px;
    color: var(--e-text-3);
    padding: 7px 8px;
    display: grid;
    place-items: center;
}

.e-stepper__btn:hover {
    background: var(--e-bg);
}

.e-stepper__btn[disabled] {
    color: var(--e-text-faint);
    cursor: default;
    background: none;
}

.e-stepper__btn:first-child {
    border-right: 1px solid var(--e-border);
}

.e-stepper__btn:last-child {
    border-left: 1px solid var(--e-border);
}

.e-stepper__label {
    font: 500 12.5px/1 var(--e-font-mono);
    padding: 0 10px;
    color: var(--e-text-2);
    white-space: nowrap;
}

/* status chips: alarms / warnings / trips */
.e-chips {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    margin-left: auto;
}

.e-chip {
    all: unset;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    gap: 6px;
    height: 30px;
    padding: 0 10px;
    border-radius: var(--e-radius);
    border: 1px solid var(--e-border);
    background: var(--e-surface);
    cursor: pointer;
    text-decoration: none;
    font: 500 12px/1 var(--e-font);
    color: var(--e-text-3);
}

.e-chip:hover {
    filter: brightness(.98);
    text-decoration: none;
}

.e-chip__dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--e-text-faint);
    flex: 0 0 7px;
}

.e-chip__count {
    font: 600 12px/1 var(--e-font-mono);
}

.e-chip--alarm {
    background: var(--e-alarm-wash);
    border-color: var(--e-alarm-line);
    color: var(--e-alarm-strong);
}

.e-chip--alarm .e-chip__dot {
    background: var(--e-alarm);
}

.e-chip--warn {
    background: var(--e-warn-wash);
    border-color: var(--e-warn-line);
    color: var(--e-warn-strong);
}

.e-chip--warn .e-chip__dot {
    background: var(--e-warn);
}

.e-chip--quiet {
    background: var(--e-bg);
    border-color: var(--e-border);
    color: var(--e-text-3);
}

.e-chip--live {
    font-family: var(--e-font-mono);
    cursor: default;
}

.e-chip--live .e-chip__dot {
    background: var(--e-ok);
}

.e-chip--paused .e-chip__dot {
    background: var(--e-text-faint);
}

.e-header__rule {
    width: 1px;
    height: 24px;
    background: var(--e-border);
    margin: 0 4px;
}

/* the scope's view row between header and page: trends, tables,
   details/totals, alarms, events - one BUTTON per view of the shown scope.
   The row floats on the page background (no surface of its own) and stays
   put while the page below scrolls. */
.e-tabs {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 14px 20px 0;
    overflow-x: auto;
    scrollbar-width: thin;
}

.e-tab {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    gap: 7px;
    flex: 0 0 auto;
    height: var(--e-control-h);
    padding: 0 12px;
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius);
    background: var(--e-surface);
    font: 500 12.5px/1 var(--e-font);
    color: var(--e-text-2);
    text-decoration: none;
    white-space: nowrap;
}

.e-tab:hover {
    border-color: var(--e-border-input);
    background: var(--e-bg);
    color: var(--e-text);
    text-decoration: none;
}

.e-tab .e-ico {
    color: var(--e-text-muted);
}

.e-tab--on,
.e-tab--on:hover {
    background: var(--e-brand-wash);
    border-color: var(--e-brand);
    color: var(--e-brand);
    font-weight: 600;
}

.e-tab--on .e-ico {
    color: var(--e-brand);
}

.e-iconbtn {
    all: unset;
    cursor: pointer;
    font-size: 19px;
    color: var(--e-text-3);
    padding: 6px;
    border-radius: var(--e-radius-sm);
    display: grid;
    place-items: center;
}

.e-iconbtn:hover {
    background: var(--e-bg);
    color: var(--e-text);
}

/* -- alarm bar ------------------------------------------------------------- */
.e-alarmbar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 20px;
    min-height: 38px;
    background: var(--e-alarm-wash);
    border-top: 1px solid var(--e-alarm-line);
    flex-wrap: wrap;
}

.e-alarmbar--warn {
    background: var(--e-warn-wash);
    border-top-color: var(--e-warn-line);
}

.e-alarmbar__icon {
    font-size: 17px;
    color: var(--e-alarm);
    flex: 0 0 auto;
}

.e-alarmbar--warn .e-alarmbar__icon {
    color: var(--e-warn);
}

.e-alarmbar__source {
    font: 600 12.5px/1.4 var(--e-font);
    color: var(--e-alarm-strong);
    text-decoration: none;
}

.e-alarmbar__source:hover {
    text-decoration: underline;
}

.e-alarmbar--warn .e-alarmbar__source {
    color: var(--e-warn-strong);
}

.e-alarmbar__text {
    font: 400 12.5px/1.4 var(--e-font);
    color: var(--e-alarm-strong);
}

.e-alarmbar--warn .e-alarmbar__text {
    color: var(--e-warn-strong);
}

.e-alarmbar__spacer {
    flex: 1 1 auto;
}

/* ========================================================= BUTTONS ======= */
.e-btn {
    all: unset;
    box-sizing: border-box;
    cursor: pointer;
    height: var(--e-control-h);
    padding: 0 12px;
    border-radius: var(--e-radius);
    border: 1px solid var(--e-border);
    background: var(--e-surface);
    font: 500 12px/1 var(--e-font);
    color: var(--e-text-2);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    text-decoration: none;
    white-space: nowrap;
}

.e-btn:hover {
    background: var(--e-bg);
    text-decoration: none;
    color: var(--e-text-2);
}

.e-btn[disabled] {
    opacity: .5;
    cursor: default;
}

.e-btn[disabled]:hover {
    background: var(--e-surface);
}

.e-btn--primary {
    background: var(--e-brand);
    border-color: var(--e-brand);
    color: var(--e-brand-on);
}

.e-btn--primary:hover {
    background: var(--e-brand-hover);
    border-color: var(--e-brand-hover);
    color: var(--e-brand-on);
}

.e-btn--danger {
    background: var(--e-alarm);
    border-color: var(--e-alarm);
    color: var(--e-brand-on);
}

.e-btn--danger:hover {
    background: var(--e-alarm-hover);
    border-color: var(--e-alarm-hover);
    color: var(--e-brand-on);
}

.e-btn--danger-outline {
    background: transparent;
    border-color: var(--e-alarm);
    color: var(--e-alarm);
}

.e-btn--danger-outline:hover {
    background: var(--e-alarm-wash-hover);
    color: var(--e-alarm);
}

.e-btn--sm {
    height: 26px;
    padding: 0 10px;
    font-size: 12px;
    font-weight: 600;
}

.e-btn--block {
    width: 100%;
}

.e-btn .e-ico,
.e-picker .e-ico {
    font-size: 16px;
}

/* segmented control (view switch, span switch, baseline switch) */
.e-seg {
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius);
    background: var(--e-surface);
    overflow: hidden;
}

.e-seg__item {
    all: unset;
    cursor: pointer;
    font: 500 12px/1.4 var(--e-font);
    padding: 8px 11px;
    color: var(--e-text-3);
    white-space: nowrap;
    border-right: 1px solid var(--e-border);
}

.e-seg__item:last-child {
    border-right: none;
}

.e-seg__item:hover {
    background: var(--e-bg);
}

.e-seg__item--on,
.e-seg__item--on:hover {
    background: var(--e-brand);
    color: var(--e-brand-on);
}

.e-seg--mono .e-seg__item {
    font-family: var(--e-font-mono);
}

.e-seg--sm .e-seg__item {
    font-size: 11.5px;
    padding: 7px 10px;
}

/* an icon-only step, as tall as a small text step */
.e-seg__item--icon,
.e-seg--sm .e-seg__item--icon {
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    height: 30px;
    padding: 0 9px;
}

/* the live trend view of the detail page's chart card, at the bar chart's
   inset; the chart engine sizes its canvas to the host */
.e-trendlive {
    position: relative;
    box-sizing: border-box;
    padding: 16px 16px 8px;
}

.e-trendlive__chart {
    display: block;
    position: relative;
    width: 100%;
    height: 100%;
}

.e-trendlive__note {
    position: absolute;
    top: 18px;
    right: 22px;
    font: 400 11.5px/1.4 var(--e-font);
    color: var(--e-text-muted);
    background: var(--e-surface);
    border-radius: var(--e-radius-sm);
    padding: 2px 6px;
}

.e-trendlive__note--center {
    position: static;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    text-align: center;
}

/* a select-looking trigger (quantity picker, template picker) */
.e-picker {
    all: unset;
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius);
    background: var(--e-surface);
    padding: 0 11px;
    height: var(--e-control-h);
    font: 500 12px/1 var(--e-font);
    color: var(--e-text-2);
    cursor: pointer;
    max-width: 100%;
}

.e-picker:hover {
    background: var(--e-bg);
}

.e-picker__icon {
    font-size: 16px;
    color: var(--e-text-muted);
    flex: 0 0 auto;
}

.e-picker__text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ============================================================ CARD ======= */
.e-card {
    background: var(--e-surface);
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius-card);
}

.e-card--clip {
    overflow: hidden;
}

.e-card__head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px 12px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--e-border-subtle);
}

.e-card__icon {
    font-size: 18px;
    color: var(--e-brand);
    flex: 0 0 auto;
}

.e-card__title {
    font: 600 13.5px/1 var(--e-font);
    margin: 0;
}

.e-card__meta {
    font: 400 12px/1 var(--e-font-mono);
    color: var(--e-text-muted);
}

.e-card__note {
    font: 400 11.5px/1 var(--e-font);
    color: var(--e-text-muted);
}

.e-card__body {
    padding: 14px 16px;
}

.e-card__foot {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 18px;
    padding: 10px 16px;
    background: var(--e-surface-sunken);
    border-top: 1px solid var(--e-border-subtle);
    font: 400 11.5px/1.4 var(--e-font);
    color: var(--e-text-3);
}

.e-spacer {
    flex: 1 1 auto;
}

/* ============================================================= KPI ======= */
.e-grid-kpi {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
    gap: 12px;
}

.e-kpi {
    background: var(--e-surface);
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius-card);
    padding: 14px 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    text-decoration: none;
    color: inherit;
}

.e-kpi:hover {
    border-color: var(--e-border-input);
    text-decoration: none;
    color: inherit;
}

.e-kpi__head {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.e-kpi__symbol {
    font: 500 12px/1 var(--e-font-mono);
    color: var(--e-brand);
    flex: 0 0 auto;
}

.e-kpi__name {
    font: 400 12px/1 var(--e-font);
    color: var(--e-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-kpi__value {
    display: flex;
    align-items: baseline;
    gap: 6px;
}

.e-kpi__value .e-num {
    font-size: 30px;
    line-height: 1;
    letter-spacing: -0.02em;
}

.e-kpi__value .e-unit {
    font-size: 13px;
}

.e-kpi__foot {
    display: flex;
    align-items: center;
    gap: 8px;
}

.e-spark {
    flex: 1 1 auto;
    height: 22px;
    display: flex;
    align-items: flex-end;
    gap: 2px;
}

.e-spark__bar {
    flex: 1 1 0;
    background: var(--e-ok-spark);
    border-radius: 1px;
    min-height: 1px;
}

.e-delta {
    font: 500 11.5px/1 var(--e-font-mono);
    color: var(--e-text-muted);
    flex: 0 0 auto;
}

.e-delta--up {
    color: var(--e-ok-strong);
}

.e-delta--down {
    color: var(--e-warn-text);
}

/* =================================================== ELO CARD / BARS ===== */
/*
 * The electrolyzer card grid. Column counts come from the plant configuration's
 * GridConfig (a 12-column intent, e.g. col-12 col-lg-6 col-xl-4), handed in as
 * custom properties by the page - so a customer's COLUMN_WIDTH still decides the
 * layout. Without them it falls back to the design's own breakpoints.
 */
.e-grid-elo {
    display: grid;
    gap: 12px;
    grid-template-columns: repeat(var(--e-cols-xs, 1), minmax(0, 1fr));
}

@media (min-width: 960px) {
    .e-grid-elo {
        grid-template-columns: repeat(var(--e-cols-md, var(--e-cols-xs, 1)), minmax(0, 1fr));
    }
}

@media (min-width: 1280px) {
    .e-grid-elo {
        grid-template-columns: repeat(var(--e-cols-lg, var(--e-cols-md, var(--e-cols-xs, 2))), minmax(0, 1fr));
    }
}

@media (min-width: 1920px) {
    .e-grid-elo {
        grid-template-columns: repeat(var(--e-cols-xl, var(--e-cols-lg, var(--e-cols-md, var(--e-cols-xs, 3)))), minmax(0, 1fr));
    }
}

@media (min-width: 2560px) {
    .e-grid-elo {
        grid-template-columns: repeat(var(--e-cols-xxl, var(--e-cols-xl, var(--e-cols-lg, var(--e-cols-md, var(--e-cols-xs, 3))))), minmax(0, 1fr));
    }
}

.e-elo {
    background: var(--e-surface);
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius-card);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.e-elo__head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--e-border-subtle);
    flex-wrap: wrap;
}

.e-elo__flag {
    width: 3px;
    height: 20px;
    border-radius: 2px;
    background: var(--e-ok);
    flex: 0 0 3px;
}

.e-elo__name {
    font: 600 15px/1 var(--e-font);
    color: var(--e-text);
    text-decoration: none;
}

.e-elo__name:hover {
    color: var(--e-brand);
    text-decoration: none;
}

.e-state {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 22px;
    padding: 0 8px;
    border-radius: 11px;
    font: 600 11px/1 var(--e-font);
    letter-spacing: .03em;
    text-transform: uppercase;
    background: var(--e-ok-wash);
    color: var(--e-ok-strong);
    white-space: nowrap;
}

.e-state--warn {
    background: var(--e-warn-wash);
    color: var(--e-warn-text);
}

.e-state--alarm {
    background: var(--e-alarm-wash);
    color: var(--e-alarm);
}

/* the value strip under an elo head - N equal cells with hairline dividers */
.e-strip {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(102px, 1fr));
}

.e-strip--wide {
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

.e-strip__cell {
    padding: 10px 14px;
    border-right: 1px solid var(--e-border-subtle);
    display: flex;
    flex-direction: column;
    gap: 5px;
    min-width: 0;
}

.e-strip__cell:last-child {
    border-right: none;
}

.e-strip__label {
    font: 400 11px/1.4 var(--e-font-mono);
    color: var(--e-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-strip--wide .e-strip__label {
    color: var(--e-brand);
}

/* wrap, not overflow: a totalizer ("169980,086 kAh") or a state text is wider
   than a cell - the unit drops under the number, and a number wider than the
   cell is clipped with an ellipsis (the cell's tooltip and the details dialog
   carry it in full) instead of running into its neighbour */
.e-strip__value {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 2px 4px;
    min-width: 0;
}

.e-strip__value .e-num {
    font-size: 17px;
    line-height: 1;
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* a pre-redesign pill (Badge) in a strip cell wraps its words and loses its
   side margins - it read as a red bar across the neighbouring cells */
.e-strip__value .e-legacy-badge {
    display: inline-block;
    white-space: normal;
    margin: 0;
    padding: 1px 8px;
    font: 500 11.5px/1.35 var(--e-font);
    max-width: 100%;
    box-sizing: border-box;
}

.e-strip--wide .e-strip__value .e-num {
    font-size: 19px;
}

.e-strip__value .e-unit {
    font-size: 11px;
}

.e-strip__name {
    font: 400 11px/1.3 var(--e-font);
    color: var(--e-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-val--alarm {
    color: var(--e-alarm);
}

.e-val--warn {
    color: var(--e-warn-text);
}

/* the pre-redesign pill (controls/Badge): one line by default, as it always was */
.e-legacy-badge {
    white-space: nowrap;
}

/* -- the bar chart (pure CSS; no plotting library on this path) ------------ */
.e-bars {
    padding: 14px 16px 10px;
    border-top: 1px solid var(--e-border-subtle);
}

.e-bars--bare {
    border-top: none;
    padding: 16px 16px 8px;
}

.e-bars__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 8px;
    flex-wrap: wrap;
}

.e-bars__caption {
    font: 500 11px/1 var(--e-font);
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--e-text-muted);
    white-space: nowrap;
}

.e-legend {
    display: flex;
    align-items: center;
    gap: 12px;
    font: 400 11px/1 var(--e-font);
    color: var(--e-text-muted);
    flex-wrap: wrap;
}

.e-legend__item {
    display: flex;
    align-items: center;
    gap: 5px;
}

.e-legend__swatch {
    width: 8px;
    height: 8px;
    border-radius: 2px;
    background: var(--e-ok);
}

.e-legend__swatch--warn {
    background: var(--e-warn);
}

.e-legend__swatch--alarm {
    background: var(--e-alarm);
}

.e-plot {
    display: flex;
    font: 400 10.5px/1 var(--e-font-mono);
    color: var(--e-text-muted);
}

.e-plot__yaxis {
    width: 30px;
    flex: 0 0 30px;
    position: relative;
}

.e-plot--lg .e-plot__yaxis {
    width: 38px;
    flex: 0 0 38px;
    font-size: 11px;
}

.e-plot__ytick {
    position: absolute;
    right: 6px;
    transform: translateY(-50%);
}

.e-plot--lg .e-plot__ytick {
    right: 8px;
}

.e-plot__area {
    flex: 1 1 auto;
    position: relative;
    background: var(--e-surface-inset);
    border-radius: var(--e-radius-sm);
    border: 1px solid var(--e-border-subtle);
    overflow: hidden;
}

/* out-of-window bands, painted behind the gridlines */
.e-plot__band {
    position: absolute;
    left: 0;
    right: 0;
    background: var(--e-warn-wash);
}

.e-plot__band--alarm {
    background: var(--e-alarm-wash);
}

.e-plot__gridline {
    position: absolute;
    left: 0;
    right: 0;
    border-top: 1px solid var(--e-border-subtle);
}

.e-plot__limit {
    position: absolute;
    left: 0;
    right: 0;
    border-top: 1px dashed var(--e-alarm);
    cursor: pointer;
}

.e-plot__limit--warn {
    border-top-color: var(--e-warn);
}

.e-plot__limit--avg {
    border-top: 1px solid var(--e-text-faint);
    cursor: default;
}

.e-plot__limit-tag {
    position: absolute;
    right: 6px;
    top: -16px;
    font: 500 10px/1 var(--e-font-mono);
    color: var(--e-alarm);
    background: var(--e-surface);
    padding: 2px 4px;
    border-radius: 3px;
}

.e-plot__limit--warn .e-plot__limit-tag {
    color: var(--e-warn);
}

.e-plot__limit--avg .e-plot__limit-tag {
    left: 6px;
    right: auto;
    color: var(--e-text-3);
}

.e-plot__bars {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: flex-end;
    gap: 2px;
    padding: 0 4px;
}

.e-plot--lg .e-plot__bars {
    gap: 3px;
    padding: 0 6px;
}

.e-bar {
    all: unset;
    flex: 1 1 0;
    min-width: 2px;
    background: var(--e-ok);
    border-radius: 2px 2px 0 0;
    cursor: pointer;
    display: block;
}

.e-bar:hover {
    opacity: .78;
}

.e-bar--warn {
    background: var(--e-warn);
}

.e-bar--alarm {
    background: var(--e-alarm);
}

.e-bar--selected {
    background: var(--e-brand);
}

.e-bar--spare {
    background: var(--e-border-input);
}

.e-plot__xaxis {
    display: flex;
    padding-left: 30px;
    padding-top: 6px;
}

.e-plot--lg + .e-plot__xaxis,
.e-plot__xaxis--lg {
    padding-left: 38px;
    padding-top: 8px;
}

.e-plot__xaxis-track {
    flex: 1 1 auto;
    position: relative;
    height: 12px;
}

.e-plot__xtick {
    position: absolute;
    transform: translateX(-50%);
    font: 400 10px/1.4 var(--e-font-mono);
    color: var(--e-text-faint);
}

.e-plot__xaxis--lg .e-plot__xtick {
    font-size: 10.5px;
}

/* ================================================= ELEMENT CELL GRID ===== */
.e-cells {
    padding: 12px;
    display: grid;
    grid-template-columns: repeat(8, minmax(0, 1fr));
    gap: 6px;
}

.e-cell {
    all: unset;
    box-sizing: border-box;
    border: 1px solid var(--e-border-subtle);
    background: var(--e-surface-inset);
    border-radius: 5px;
    padding: 7px 4px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    cursor: pointer;
}

.e-cell:hover {
    border-color: var(--e-brand);
}

.e-cell__name {
    font: 500 10.5px/1 var(--e-font-mono);
    color: var(--e-text-muted);
}

.e-cell__value {
    font: 500 12.5px/1 var(--e-font-mono);
    font-variant-numeric: tabular-nums;
    color: var(--e-text);
}

.e-cell--warn {
    background: var(--e-warn-wash);
    border-color: var(--e-warn-line);
}

.e-cell--warn .e-cell__value {
    color: var(--e-warn-strong);
}

.e-cell--alarm {
    background: var(--e-alarm-wash);
    border-color: var(--e-alarm-line-2);
}

.e-cell--alarm .e-cell__value {
    color: var(--e-alarm-strong);
}

.e-cell--selected {
    border-color: var(--e-brand);
    box-shadow: 0 0 0 1px var(--e-brand) inset;
}

.e-cell--spare {
    opacity: .55;
}

/* the rack break: a zero-height full-row grid item forces the next cell to wrap */
.e-cells__break {
    grid-column: 1 / -1;
    height: 0;
}

/* the totals page: as many tiles as fit, 104 px and up */
.e-cells--fluid {
    grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
}

/* the deviation from the average: a hairline track with the zero in the middle,
   filled to the right for a voltage above the average, to the left for one
   below; the fill takes the tile's alarm colour */
.e-cell__bar {
    display: block;
    position: relative;
    width: 100%;
    height: 3px;
    margin-top: 1px;
    background: var(--e-border-subtle);
    border-radius: 2px;
}

.e-cell__bar-zero {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    width: 1px;
    background: var(--e-border-input);
}

.e-cell__bar-fill {
    position: absolute;
    top: 0;
    bottom: 0;
    border-radius: 2px;
    background: var(--e-brand);
    opacity: .65;
}

.e-cell--warn .e-cell__bar-fill {
    background: var(--e-warn);
}

.e-cell--alarm .e-cell__bar-fill {
    background: var(--e-alarm);
}

.e-cell__badges {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 3px;
    flex-wrap: wrap;
    margin-top: 3px;
}

/* the pre-redesign pill at tile size - in the tile, and in the legend that explains it */
.e-cell__badge {
    display: inline-block;
    padding: 0 6px;
    margin: 0;
    font: 500 10px/1.6 var(--e-font);
    border-radius: 999px;
}

/* the legend's sample of the deviation bar */
.e-legend__bar {
    display: inline-block;
    width: 22px;
    height: 3px;
    border-radius: 2px;
    background: var(--e-brand);
    opacity: .65;
}

/* ================================================== PROCESS VALUE ROWS === */
.e-pvrow {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 16px;
    border-bottom: 1px solid var(--e-border-faint);
    text-decoration: none;
    color: inherit;
}

.e-pvrow:last-child {
    border-bottom: none;
}

.e-pvrow:hover {
    background: var(--e-surface-row);
    text-decoration: none;
    color: inherit;
}

.e-pvrow__symbol {
    font: 400 11.5px/1.4 var(--e-font-mono);
    color: var(--e-brand);
    width: 96px;
    flex: 0 0 96px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-pvrow__name {
    flex: 1 1 auto;
    font: 400 12.5px/1.3 var(--e-font);
    color: var(--e-text-2);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-pvrow__value {
    font: 500 13px/1 var(--e-font-mono);
    font-variant-numeric: tabular-nums;
    flex: 0 0 auto;
}

.e-pvrow__unit {
    font: 400 11px/1 var(--e-font);
    color: var(--e-text-muted);
    width: 44px;
    flex: 0 0 44px;
    text-align: right;
}

/* ====================================================== LINEAR GAUGE ===== */
.e-gauge {
    position: relative;
    height: 26px;
    border-radius: var(--e-radius-sm);
    overflow: hidden;
    background: var(--e-ok-wash);
}

.e-gauge__zone {
    position: absolute;
    top: 0;
    bottom: 0;
    background: var(--e-warn-wash);
}

.e-gauge__zone--alarm {
    background: var(--e-alarm-wash);
}

.e-gauge__needle {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 2px;
    background: var(--e-text);
    transform: translateX(-1px);
}

.e-gauge__limit {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 1px;
    background: var(--e-warn);
}

.e-gauge__limit--alarm {
    background: var(--e-alarm);
}

.e-gauge__scale {
    display: flex;
    justify-content: space-between;
    font: 400 10.5px/1 var(--e-font-mono);
    color: var(--e-text-muted);
}

/* the dashboard's bar-with-target meter */
.e-meter {
    height: 10px;
    border-radius: 5px;
    background: var(--e-surface-row);
    position: relative;
    overflow: hidden;
}

.e-meter__fill {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    background: var(--e-ok);
}

.e-meter__fill--warn {
    background: var(--e-warn);
}

.e-meter__fill--alarm {
    background: var(--e-alarm);
}

.e-meter__target {
    position: absolute;
    top: -2px;
    bottom: -2px;
    width: 2px;
    background: var(--e-text);
}

/* ========================================================== TABLES ======= */
.e-table {
    background: var(--e-surface);
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius-card);
    overflow-x: auto;
}

.e-table__head,
.e-table__row {
    display: grid;
    padding: 0 14px;
    align-items: center;
}

.e-table__head {
    background: var(--e-surface-sunken);
    border-bottom: 1px solid var(--e-border);
    position: sticky;
    top: 0;
    z-index: 1;
}

.e-table__th {
    font: 600 10.5px/1.2 var(--e-font);
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--e-text-muted);
    padding: 11px 8px 11px 0;
    background: none;
    border: none;
    text-align: left;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 4px;
}

.e-table__th--right {
    justify-content: flex-end;
    text-align: right;
}

.e-table__th--static {
    cursor: default;
}

.e-table__th .e-ico {
    font-size: 14px;
}

.e-table__row {
    border-bottom: 1px solid var(--e-border-faint);
    cursor: pointer;
    text-decoration: none;
    color: inherit;
}

.e-table__row:hover {
    background: var(--e-surface-row);
    text-decoration: none;
    color: inherit;
}

.e-table__row--alarm {
    background: var(--e-alarm-row);
}

.e-table__cell {
    padding: 9px 8px 9px 0;
    font: 400 12.5px/1.35 var(--e-font);
    color: var(--e-text);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.e-table__cell--mono {
    font-family: var(--e-font-mono);
    font-size: 12px;
    color: var(--e-text-3);
    white-space: nowrap;
}

.e-table__cell--symbol {
    font-family: var(--e-font-mono);
    font-size: 12px;
    color: var(--e-brand);
    white-space: nowrap;
}

.e-table__cell--muted {
    color: var(--e-text-3);
    white-space: nowrap;
}

.e-table__cell--faint {
    color: var(--e-text-muted);
    font-size: 11.5px;
}

.e-table__cell--num {
    font-family: var(--e-font-mono);
    font-weight: 500;
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    text-align: right;
    white-space: nowrap;
}

.e-table__cell--right {
    text-align: right;
}

.e-table__cell--actions {
    display: flex;
    align-items: center;
    gap: 9px;
    justify-content: flex-end;
    color: var(--e-text-faint);
}

.e-table__group {
    padding: 8px 14px;
    background: var(--e-surface-row);
    border-bottom: 1px solid var(--e-border-subtle);
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
}

.e-table__group-label {
    font: 600 11.5px/1 var(--e-font);
    color: var(--e-text-2);
}

.e-table__group-count {
    font: 400 11px/1 var(--e-font-mono);
    color: var(--e-text-muted);
}

.e-table__empty {
    padding: 28px 16px;
    text-align: center;
    font: 400 13px/1.5 var(--e-font);
    color: var(--e-text-muted);
}

.e-table__foot {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 14px;
    padding: 10px 16px;
    font: 400 12px/1 var(--e-font);
    color: var(--e-text-3);
    flex-wrap: wrap;
}

/* -- event journal rows ---------------------------------------------------- */
/* the categorical fields of an event (source, priority, type, user) flow as
   chips inside one flexible cell, each as wide as its text - no column ever
   truncates them; the message takes the remaining line */
.e-table__thgroup {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    overflow: hidden;
}

.e-table__cell--flow {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 8px;
    min-width: 0;
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
}

.e-evtag {
    all: unset;
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    max-width: 100%;
    padding: 2px 7px;
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius-sm);
    background: var(--e-surface);
    font: 500 11.5px/1.4 var(--e-font);
    color: var(--e-text-3);
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.e-evtag:hover {
    border-color: var(--e-border-input);
    color: var(--e-text);
    text-decoration: none;
}

.e-evtag--source {
    font-family: var(--e-font-mono);
    color: var(--e-brand);
}

.e-evtag--source:hover {
    color: var(--e-brand);
}

.e-evtag--user {
    font-family: var(--e-font-mono);
}

.e-evtag[disabled] {
    cursor: default;
}

.e-evmsg {
    flex: 1 1 240px;
    min-width: 160px;
    font: 400 12.5px/1.4 var(--e-font);
    color: var(--e-text);
}

/* -- content-fitted table -------------------------------------------------- */
/* the CONTAINER owns the grid template (max-content columns that never cut a
   value off) and head/rows are subgrids of it, so the content-sized columns
   still align across every row; full-width parts span all columns */
.e-table--fit {
    display: grid;
    align-content: start;
}

.e-table--fit > .e-table__head,
.e-table--fit > .e-table__row {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: subgrid;
}

.e-table--fit > .e-table__group,
.e-table--fit > .e-table__empty,
.e-table--fit > .e-table__foot,
.e-table--fit > .e-print-note {
    grid-column: 1 / -1;
}

/* -- correction formula ---------------------------------------------------- */
/* one row per correction equation: a leading tag, value chips and operators */
.e-formula {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
}

.e-formula__tag {
    min-width: 80px;
    font: 600 12.5px/1 var(--e-font-mono);
    color: var(--e-text-2);
}

.e-formula__op {
    font: 400 17px/1 var(--e-font-mono);
    color: var(--e-text-muted);
}

/* a value chip of the formula: symbol, live value, unit; the edit variant is
   the one the operator may write to */
.e-fchip {
    all: unset;
    box-sizing: border-box;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-width: 150px;
    height: var(--e-control-h);
    padding: 0 10px;
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius);
    background: var(--e-surface);
    font: 400 12.5px/1 var(--e-font);
}

.e-fchip:hover {
    border-color: var(--e-border-input);
    background: var(--e-bg);
}

.e-fchip .e-num {
    margin-left: auto;
}

.e-fchip--edit {
    border-color: var(--e-brand);
    background: var(--e-brand-wash);
}

.e-fchip--edit:hover {
    border-color: var(--e-brand);
    background: var(--e-brand-wash-2);
}

.e-fchip--edit .e-ico {
    color: var(--e-brand);
}

.e-fchip--accent {
    border-color: var(--e-ok-line, var(--e-border));
    background: var(--e-ok-wash);
}

.e-fchip--accent:hover {
    background: var(--e-ok-wash);
    border-color: var(--e-ok);
}

/* -- inline note ----------------------------------------------------------- */
.e-note {
    padding: 9px 12px;
    border-radius: var(--e-radius);
    font: 400 12.5px/1.45 var(--e-font);
    background: var(--e-info-wash);
    color: var(--e-info-strong);
}

.e-note--warn {
    background: var(--e-warn-wash);
    color: var(--e-warn-strong);
}

.e-note--ok {
    background: var(--e-ok-wash);
    color: var(--e-ok-strong);
}

/* -- crosstab (totals, limit tables) --------------------------------------- */
/* a real <table> in the design's table language - the crosstab needs colspan,
   which the grid tables cannot give */
.e-xtab-wrap {
    background: var(--e-surface);
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius-card);
    overflow-x: auto;
}

.e-xtab {
    border-collapse: collapse;
    width: 100%;
    font: 400 12.5px/1.35 var(--e-font);
    color: var(--e-text);
}

.e-xtab th {
    font: 600 10.5px/1.2 var(--e-font);
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--e-text-muted);
    background: var(--e-surface-sunken);
    padding: 10px;
    text-align: left;
    white-space: nowrap;
}

.e-xtab thead th {
    border-bottom: 1px solid var(--e-border);
}

.e-xtab td {
    padding: 7px 10px;
    border-bottom: 1px solid var(--e-border-faint);
    white-space: nowrap;
}

.e-xtab tbody tr:hover {
    background: var(--e-surface-row);
}

.e-xtab__center {
    text-align: center !important;
}

.e-xtab__units {
    color: var(--e-text-muted);
    font-size: 11.5px;
}

/* a child-scope column header navigates to that scope */
.e-xtab__scopelink {
    all: unset;
    box-sizing: border-box;
    cursor: pointer;
    display: block;
    width: 100%;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    color: var(--e-brand);
    text-align: center;
}

.e-xtab__scopelink:hover {
    text-decoration: underline;
}

/* priority / severity pill inside a table cell */
.e-pill {
    display: inline-flex;
    align-items: center;
    height: 20px;
    padding: 0 7px;
    border-radius: var(--e-radius-sm);
    font: 600 10.5px/1 var(--e-font);
    letter-spacing: .03em;
    text-transform: uppercase;
    background: var(--e-bg);
    color: var(--e-text-3);
    white-space: nowrap;
    cursor: pointer;
}

.e-pill--alarm {
    background: var(--e-alarm-wash);
    color: var(--e-alarm-strong);
}

.e-pill--warn {
    background: var(--e-warn-wash);
    color: var(--e-warn-strong);
}

.e-pill--info {
    background: var(--e-info-wash);
    color: var(--e-info-strong);
}

.e-pill--ok {
    background: var(--e-ok-wash);
    color: var(--e-ok-strong);
}

/* ==================================================== FILTER / FIELDS ==== */
.e-filters {
    background: var(--e-surface);
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius-card);
    padding: 12px 14px;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
    gap: 10px;
}

.e-field {
    display: flex;
    flex-direction: column;
    gap: 5px;
    min-width: 0;
}

.e-field__label {
    font: 500 10.5px/1 var(--e-font);
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--e-text-muted);
}

.e-field__box,
.e-input {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    gap: 7px;
    height: var(--e-control-h);
    padding: 0 10px;
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius);
    background: var(--e-surface-field);
    font: 400 12.5px/1 var(--e-font);
    color: var(--e-text);
    width: 100%;
}

.e-input {
    outline: none;
    background: var(--e-surface);
}

.e-input:focus {
    border-color: var(--e-brand);
    box-shadow: 0 0 0 3px var(--e-brand-wash-2);
}

.e-field__box--live {
    color: var(--e-live-strong);
}

.e-field__text {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-field__icon {
    font-size: 15px;
    color: var(--e-text-faint);
    flex: 0 0 auto;
}

/* ============================================== TREND / SERIES LEGEND ==== */
/* the stacked charts of a trend set: each chart is its own card, cut off
   from its neighbours by the page background - not one shared surface */
.e-trendstack {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.e-trendstack__item {
    background: var(--e-surface);
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius-card);
    padding: 12px 16px 10px;
    /* the anchor for the select sheet a configuration panel puts over the card */
    position: relative;
}

/*
 * The card a configuration panel is editing. The mark is the card's OWN border
 * plus an inset ring, never an outer box-shadow: the stack scrolls inside
 * .e-fillscroll, which clips anything painted outside the border box - the ring
 * then showed on some sides and not others. This rule must stay AFTER the base
 * one, whose `border` shorthand would otherwise win over the colour.
 */
.e-trendstack__item--on {
    border-color: var(--e-brand);
    box-shadow: inset 0 0 0 1px var(--e-brand);
}

/*
 * The select sheet: while the panel is open the whole card is one click target.
 * It sits over the chart (MudFab's z-10 included) so no click, drag or wheel
 * reaches the engine - in that mode the card answers "which chart", nothing else.
 */
.e-trendstack__pick {
    position: absolute;
    inset: 0;
    z-index: 20;
    cursor: pointer;
    border-radius: var(--e-radius-card);
}

.e-trendstack__item--on > .e-trendstack__pick {
    cursor: default;
}

/* a trend chart: the axis captions above the plot - the chart engine has no
   axis titles - and the plot filling the rest. The plot is the eloviz-trend
   element; the engine sizes its canvases to it, so it needs a definite height
   from its host (a fixed one in a stack, the flex remainder solo or on a
   sheet). A caption opens the scale dialog of its axis. */
.e-trendchart {
    display: flex;
    flex-direction: column;
    min-height: 0;
}

.e-trendchart__axes {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 0 4px;
    font: 500 11px/1.4 var(--e-font);
    color: var(--e-text-muted);
}

.e-trendchart__axis {
    cursor: pointer;
    white-space: nowrap;
}

.e-trendchart__axis:hover {
    color: var(--e-text);
}

.e-trendchart__plot {
    flex: 1 1 auto;
    min-height: 0;
    display: block;
    position: relative;
    width: 100%;
    /* the plot area's own gestures: the page must not scroll under a pan */
    touch-action: none;
}

/* the note the engine leaves when the browser has no WebGPU adapter */
.e-trendchart__unavailable {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px 24px;
    text-align: center;
    font: 400 11.5px/1.4 var(--e-font);
    color: var(--e-text-muted);
    pointer-events: none;
}

@media screen {
    .e-trendchart--many {
        height: 300px;
    }

    .e-trendchart--solo {
        height: calc(100vh - 350px);
    }
}

.e-serieslegend {
    display: flex;
    gap: 24px;
    flex-wrap: wrap;
    margin-bottom: 14px;
}

.e-series {
    display: flex;
    align-items: center;
    gap: 8px;
}

.e-series__swatch {
    width: 14px;
    height: 3px;
    border-radius: 2px;
    flex: 0 0 14px;
}

.e-series__symbol {
    font: 400 11.5px/1 var(--e-font-mono);
    color: var(--e-text-muted);
}

.e-series__value {
    font: 500 13px/1 var(--e-font-mono);
    font-variant-numeric: tabular-nums;
}

.e-series__unit {
    font: 400 11px/1 var(--e-font);
    color: var(--e-text-muted);
}

.e-follow {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: var(--e-control-h);
    padding: 0 11px;
    border: 1px solid var(--e-live-line);
    border-radius: var(--e-radius);
    background: var(--e-live-wash);
    font: 500 12px/1 var(--e-font);
    color: var(--e-live-strong);
    white-space: nowrap;
}

.e-follow__dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--e-live);
    flex: 0 0 7px;
}

.e-follow--paused {
    border-color: var(--e-border);
    background: var(--e-bg);
    color: var(--e-text-3);
}

.e-follow--paused .e-follow__dot {
    background: var(--e-text-faint);
}

/* ================================================== ALARM ASSISTANT ====== */
.e-matrix {
    display: grid;
    min-width: 800px;
}

.e-matrix__corner {
    background: var(--e-surface-sunken);
    border-bottom: 1px solid var(--e-border);
}

.e-matrix__group {
    padding: 10px 12px;
    background: var(--e-surface-sunken);
    border-left: 1px solid var(--e-border-subtle);
    border-bottom: 1px solid var(--e-border);
    font: 600 10.5px/1 var(--e-font);
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--e-text-3);
}

.e-matrix__colhead {
    padding: 9px 12px;
    border-left: 1px solid var(--e-border-subtle);
    border-bottom: 1px solid var(--e-border);
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.e-matrix__colsymbol {
    font: 400 11px/1 var(--e-font-mono);
    color: var(--e-brand);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.e-matrix__colname {
    font: 400 11.5px/1.35 var(--e-font);
    color: var(--e-text-3);
}

.e-matrix__rowhead {
    padding: 12px 8px;
    display: grid;
    place-items: center;
    border-bottom: 1px solid var(--e-border-faint);
    font: 600 12px/1 var(--e-font-mono);
    background: var(--e-warn-wash);
    color: var(--e-warn-strong);
}

.e-matrix__rowhead--hh {
    background: var(--e-alarm-wash);
    color: var(--e-alarm-strong);
}

.e-matrix__cell {
    border-left: 1px solid var(--e-border-subtle);
    border-bottom: 1px solid var(--e-border-faint);
    padding: 8px 10px;
    min-height: 46px;
    display: flex;
    align-items: center;
}

.e-tip {
    all: unset;
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 28px;
    padding: 0 9px;
    border-radius: var(--e-radius);
    border: 1px solid var(--e-border);
    background: var(--e-surface-row);
    color: var(--e-text-3);
    font: 500 11.5px/1 var(--e-font-mono);
    cursor: pointer;
    white-space: nowrap;
}

.e-tip:hover {
    filter: brightness(.97);
}

.e-tip .e-ico {
    font-size: 14px;
}

.e-tip--warn {
    background: var(--e-warn-wash);
    border-color: var(--e-warn-line);
    color: var(--e-warn-strong);
}

.e-tip--alarm {
    background: var(--e-alarm-wash);
    border-color: var(--e-alarm-line-2);
    color: var(--e-alarm-strong);
}

.e-tip--selected {
    box-shadow: 0 0 0 2px var(--e-brand-wash-2);
    border-color: var(--e-brand);
}

.e-tip[disabled] {
    opacity: .45;
    cursor: default;
}

.e-explain {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.e-explain__title {
    font: 600 10.5px/1 var(--e-font);
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--e-text-muted);
}

.e-explain__body {
    font: 400 12.5px/1.55 var(--e-font);
    color: var(--e-text-2);
}

/* ====================================================== ALARM LIST ======= */
.e-alarmitem {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 0;
    border-bottom: 1px solid var(--e-border-faint);
    text-decoration: none;
    color: inherit;
}

.e-alarmitem:last-child {
    border-bottom: none;
}

.e-alarmitem:hover {
    text-decoration: none;
    color: inherit;
}

.e-alarmitem:hover .e-alarmitem__title {
    color: var(--e-brand);
}

.e-alarmitem__flag {
    width: 6px;
    height: 24px;
    border-radius: 3px;
    background: var(--e-warn);
    flex: 0 0 6px;
}

.e-alarmitem__flag--alarm {
    background: var(--e-alarm);
}

.e-alarmitem__title {
    font: 500 12.5px/1.35 var(--e-font);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-alarmitem__meta {
    font: 400 11px/1.4 var(--e-font-mono);
    color: var(--e-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-alarmitem__state {
    font: 500 11px/1 var(--e-font);
    color: var(--e-warn);
    flex: 0 0 auto;
}

.e-alarmitem__state--alarm {
    color: var(--e-alarm);
}

/* =========================================================== LOGIN ======= */
.e-login {
    min-height: 100vh;
    display: grid;
    grid-template-columns: 1fr 1fr;
    background: var(--e-surface);
}

.e-login__pane {
    display: grid;
    place-items: center;
    padding: 48px;
}

.e-login__form {
    width: 100%;
    max-width: 380px;
    display: flex;
    flex-direction: column;
    gap: 28px;
}

.e-login__logo {
    display: block;
    width: fit-content;
    max-height: 34px;
}

.e-login__title {
    font: 600 26px/1.2 var(--e-font);
    color: var(--e-text);
    letter-spacing: -0.01em;
    margin: 0;
}

.e-login__sub {
    font: 400 14px/1.5 var(--e-font);
    color: var(--e-text-3);
}

.e-login__fields {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.e-login__label {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.e-login__label > span {
    font: 500 12px/1 var(--e-font);
    color: var(--e-text-3);
    letter-spacing: .04em;
    text-transform: uppercase;
}

.e-login__input {
    box-sizing: border-box;
    height: 42px;
    padding: 0 12px;
    border: 1px solid var(--e-border-input);
    border-radius: var(--e-radius);
    background: var(--e-surface);
    font: 400 15px/1 var(--e-font);
    color: var(--e-text);
    outline: none;
    width: 100%;
}

.e-login__input:focus {
    border-color: var(--e-brand);
    box-shadow: 0 0 0 3px var(--e-brand-wash-2);
}

.e-login__submit {
    all: unset;
    box-sizing: border-box;
    cursor: pointer;
    height: 44px;
    border-radius: var(--e-radius);
    background: var(--e-brand);
    color: var(--e-brand-on);
    font: 600 15px/44px var(--e-font);
    text-align: center;
    width: 100%;
}

.e-login__submit:hover {
    background: var(--e-brand-hover);
}

.e-login__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    font: 400 13px/1 var(--e-font);
    color: var(--e-text-3);
}

.e-login__note {
    padding: 10px 12px;
    border-radius: var(--e-radius);
    font: 400 13px/1.45 var(--e-font);
    background: var(--e-info-wash);
    color: var(--e-info-strong);
}

.e-login__note--error {
    background: var(--e-alarm-wash);
    color: var(--e-alarm-strong);
}

.e-login__art {
    background: var(--e-brand);
    position: relative;
    overflow: hidden;
    display: grid;
    place-items: end start;
    padding: 48px;
}

.e-login__art-bars {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: flex-end;
    gap: 3px;
    opacity: .22;
}

.e-login__art-bars > i {
    flex: 1 1 0;
    background: var(--e-brand-on);
    display: block;
}

.e-login__art-text {
    position: relative;
    color: var(--e-brand-on);
    max-width: 460px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.e-login__art-kicker {
    font: 600 13px/1 var(--e-font-mono);
    letter-spacing: .12em;
    text-transform: uppercase;
    opacity: .8;
}

.e-login__art-claim {
    font: 400 30px/1.3 var(--e-font);
    letter-spacing: -0.01em;
}

/* ======================================================= RESPONSIVE ====== */
@media (max-width: 1000px) {
    .e-login {
        grid-template-columns: 1fr;
    }

    .e-login__art {
        display: none;
    }
}

/* the two-column splits of the detail, assistant and dashboard pages */
@media (max-width: 1100px) {
    .e-details-split {
        grid-template-columns: minmax(0, 1fr) !important;
    }
}

@media (max-width: 900px) {
    .e-sidebar {
        position: fixed;
        left: 0;
        top: 0;
        transform: translateX(-100%);
        transition: transform .18s ease;
        box-shadow: var(--e-shadow-pop);
    }

    .e-shell--drawer-open .e-sidebar {
        transform: translateX(0);
    }

    .e-page {
        padding: 14px 12px 24px;
    }

    .e-cells {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/* the burger only exists below the sidebar breakpoint */
.e-burger {
    display: none;
}

@media (max-width: 900px) {
    .e-burger {
        display: grid;
    }
}

/* ------------------------------------------------ fix-pass additions ---- */

/* the base-line modes draw a bar from a base value, not from the plot floor -
   the bottom offset needs a positioned element */
.e-bar {
    position: relative;
}

/* rack boundaries in the bar chart, as the OxyPlot chart drew them */
.e-plot__rack {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 0;
    border-left: 2px solid var(--e-border);
    pointer-events: none;
}

/* the rows-per-page choice in a table footer */
.e-table__pagesize {
    display: inline-flex;
    align-items: center;
}

.e-table__pagesize-select {
    font: 500 12px/1.4 var(--e-font-mono);
    color: var(--e-text-muted);
    background: var(--e-surface);
    border: 1px solid var(--e-border-input);
    border-radius: var(--e-radius-sm);
    padding: 2px 4px;
}

/* the table footer is hidden in print - this line keeps the provenance on paper */
.e-print-note {
    display: none;
}

@media print {
    .e-print-note {
        display: block;
        font: 400 10px/1.4 var(--e-font-mono);
        color: var(--e-text-muted);
        padding: 4px 0;
    }
}

/* a centred column heading - EColumn.Align == Center */
.e-table__th--center {
    justify-content: center;
    text-align: center;
}

/* the icon of a system-alert card keeps its size beside a long message */
.e-alertcard__icon {
    flex: 0 0 auto;
    align-self: flex-start;
}

/* the committed search mode/case of an event filter, visible while the field
   carries a value (a placeholder only shows on an empty field) */
.e-field__mode {
    flex: 0 0 auto;
    font: 500 10px/1.4 var(--e-font-mono);
    color: var(--e-brand);
    background: color-mix(in srgb, var(--e-brand) 10%, var(--e-surface));
    border-radius: var(--e-radius-sm);
    padding: 1px 5px;
    white-space: nowrap;
}

/* the unit beside an element cell's value */
.e-cell__unit {
    font-size: 9px;
    color: var(--e-text-faint);
}

/* an assistant cell whose alarms are ALL acknowledged: seen, still standing -
   distinct from both quiet and unacknowledged, as before the redesign */
.e-tip--ack {
    color: var(--e-info-strong, var(--e-brand));
    background: var(--e-info-wash, color-mix(in srgb, var(--e-brand) 8%, var(--e-surface)));
    border-color: color-mix(in srgb, var(--e-info-strong, var(--e-brand)) 30%, var(--e-border));
}

/* ============================================================ PRINT ====== */
@media print {
    .e-sidebar,
    .e-header,
    .e-page-actions,
    .e-alarmbar,
    .e-table__foot,
    .no-print {
        display: none !important;
    }

    /* the viewport-capped shell prints in full - every scroll region expands */
    .e-shell {
        display: block;
        height: auto;
        overflow: visible;
    }

    .e-main,
    .e-page,
    .e-page--fill,
    .e-fillscroll {
        overflow: visible;
    }

    .e-card,
    .e-elo,
    .e-kpi,
    .e-table,
    .e-trendstack__item {
        break-inside: avoid;
        box-shadow: none;
    }

    body {
        background: #fff;
        color: #000;
    }
}

/* ============================================== MUDBLAZOR BRIDGE ========= */
/*
 * The pages this redesign did not hand-rewrite (dialogs, identity, settings,
 * translations, deviation tests, ...) are MudBlazor. Rather than leave them on
 * the stock Material look, map MudBlazor's own CSS variables onto the tokens
 * above so they inherit the palette, the type and the radii. The theme .scss
 * carries the same values for the parts MudBlazor renders from C# (charts,
 * OxyPlot), this covers the parts it renders from CSS.
 */
/*
 * The palette is deliberately NOT overridden here - the theme owns it, and the
 * tokens at the top of this file already follow it, so every design surface
 * changes with the selected theme. What follows is form only.
 */

/* MudBlazor draws dialogs, menus and data grids at Material's density; the
   design is tighter and squarer everywhere. */
.mud-paper,
.mud-dialog,
.mud-popover {
    border-radius: var(--e-radius-card);
}

.mud-table-cell,
.mud-table-head .mud-table-cell {
    font-family: var(--e-font);
}

.mud-table-head .mud-table-cell {
    font: 600 10.5px/1.2 var(--e-font);
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--e-text-muted);
    background: var(--e-surface-sunken);
}

.mud-input-outlined-border {
    border-radius: var(--e-radius);
}

/* dialog titles read as card heads */
.mud-dialog-title {
    font: 600 15px/1.3 var(--e-font);
}

/*
 * MudBlazor controls placed inside a design surface.
 *
 * Material's own density is taller than the design's rows, and these controls
 * carry real behaviour we did not want to reimplement (the multi-select, the
 * date picker, the favourite toggle). Rather than rebuild them, the density is
 * brought down to the row height the design specifies.
 */
.e-table__cell--actions .mud-icon-button,
.e-table__cell--actions .mud-button-root {
    padding: 2px;
    margin: 0;
    min-width: 0;
    height: auto;
    width: auto;
}

.e-table__cell--actions .mud-icon-button .mud-icon-root,
.e-table__cell--actions .mud-icon-root {
    font-size: 16px;
    width: 1em;
    height: 1em;
}

/* Every filter field renders the same box: the plain text fields, the MudBlazor
   selects, the date pickers and the switch line up on one height, one border
   and one text inset - each variant brought its own alignment before. */
.e-filters .mud-input-control,
.e-filters .mud-input-control-input-container {
    margin-top: 0;
}

/* the selectors repeat MudBlazor's own variant classes on purpose: Mud's
   compound rules (with-label margin, outlined dense padding) tie or beat a
   plain `.e-filters .mud-input` and would keep each variant's own alignment */
.e-filters .mud-input.mud-input-text,
.e-filters .mud-input.mud-input-outlined {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    height: var(--e-control-h);
    padding: 0 10px;
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius);
    background: var(--e-surface-field);
    font: 400 12.5px/1.2 var(--e-font);
    color: var(--e-text);
    margin: 0;
}

/* MudBlazor reserves 16px above a labelled text field for its floating label;
   the design's label sits outside the field, so the reservation goes - the
   selector mirrors Mud's own to out-specify it */
.e-filters .mud-input-control > .mud-input-control-input-container > div.mud-input.mud-input-text.mud-input-text-with-label {
    margin-top: 0;
}

/* the box above carries the border - MudBlazor's own underline and outline
   are off so a text-variant field and an outlined select look identical */
.e-filters .mud-input.mud-input-underline:before,
.e-filters .mud-input.mud-input-underline:after {
    display: none;
}

.e-filters .mud-input-outlined-border {
    display: none;
}

.e-filters .mud-input > input.mud-input-slot,
.e-filters .mud-input > div.mud-input-slot {
    padding: 0;
    height: auto;
    min-height: 0;
    font: inherit;
    color: inherit;
}

.e-filters .mud-input-control .mud-input-label {
    display: none; /* the design's label sits above the field, not inside it */
}

.e-filters .mud-switch {
    margin: 0;
    height: var(--e-control-h);
    align-items: center;
}

/* the adornment / clear icons stay inside the control-height box */
.e-filters .mud-input-adornment-end .mud-icon-button,
.e-filters .mud-input .mud-icon-button {
    padding: 2px;
}

/* toolbar controls the pages hand to the header/action rows keep the design's
   control height so a row never grows a second line */
.e-page-actions .mud-button-root,
.e-chips .mud-button-root {
    min-height: var(--e-control-h);
    text-transform: none;
}

/* a stock MudIconButton is 48px of padding - inside an action row it inflated
   the whole head and left a blank band under the page title */
.e-page-actions .mud-icon-button,
.e-chips .mud-icon-button {
    box-sizing: border-box;
    height: var(--e-control-h);
    width: var(--e-control-h);
    min-height: 0;
    padding: 5px;
}

/* ELOVIZ legacy classes kept alive on the new palette: `.elo-box` is assigned
   from customer configuration files, so it cannot be renamed. */
div.elo-box {
    border-radius: var(--e-radius-card);
    border: 1px solid var(--e-border);
    background: var(--e-surface);
    transition: none;
    margin: 0;
}

div.elo-box:hover {
    background-color: var(--e-surface);
}

/* ================================================ CONTROLS (v2) ========== */
/*
 * The rest of the control inventory from the design's components sheet. Same
 * rules as everything above: tokens only, `e-` prefix, and a MudBlazor bridge
 * where a real MudBlazor control has to end up looking like the design's.
 */

/* -- buttons: the remaining two kinds --------------------------------------- */
.e-btn--text {
    background: transparent;
    border-color: transparent;
    color: var(--e-brand);
}

.e-btn--text:hover {
    background: var(--e-brand-wash);
    color: var(--e-brand);
}

/* "quiet" is the dialog's cancel: no border, no fill, muted label */
.e-btn--quiet {
    background: transparent;
    border-color: transparent;
    color: var(--e-text-3);
}

.e-btn--quiet:hover {
    background: var(--e-bg);
    color: var(--e-text-2);
}

/* -- numeric input with unit and steppers ---------------------------------- */
.e-inputgroup {
    display: flex;
    align-items: center;
    height: 36px;
    border: 1px solid var(--e-border-input);
    border-radius: var(--e-radius);
    background: var(--e-surface);
    padding: 0 10px;
    gap: 8px;
    box-sizing: border-box;
}

.e-inputgroup:focus-within {
    border-color: var(--e-brand);
    box-shadow: 0 0 0 3px var(--e-brand-wash-2);
}

.e-inputgroup--invalid,
.e-inputgroup--invalid:focus-within {
    border-color: var(--e-alarm);
    box-shadow: none;
}

.e-inputgroup--readonly {
    background: var(--e-surface-row);
    border-color: var(--e-border-subtle);
}

.e-inputgroup__input {
    all: unset;
    flex: 1 1 auto;
    min-width: 0;
    font: 500 13.5px/1.4 var(--e-font-mono);
    color: var(--e-text);
}

.e-inputgroup--text .e-inputgroup__input {
    font: 400 13px/1.4 var(--e-font);
}

.e-inputgroup__unit {
    font: 400 12px/1.4 var(--e-font);
    color: var(--e-text-muted);
    flex: 0 0 auto;
}

.e-inputgroup__steppers {
    display: flex;
    flex-direction: column;
    gap: 1px;
    flex: 0 0 auto;
}

.e-inputgroup__stepper {
    all: unset;
    cursor: pointer;
    font-size: 13px;
    color: var(--e-text-muted);
    display: grid;
    place-items: center;
}

.e-inputgroup__stepper:hover {
    color: var(--e-brand);
}

.e-field__error {
    font: 400 11px/1.4 var(--e-font);
    color: var(--e-alarm-strong);
}

/* -- switch, checkbox, select, slider -------------------------------------- */
.e-switch {
    all: unset;
    cursor: pointer;
    width: 38px;
    height: 22px;
    border-radius: 11px;
    background: var(--e-border);
    position: relative;
    flex: 0 0 38px;
    transition: background .12s ease;
}

.e-switch__knob {
    position: absolute;
    top: 3px;
    left: 3px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--e-surface);
    transition: left .12s ease;
}

.e-switch--on {
    background: var(--e-brand);
}

.e-switch--on .e-switch__knob {
    left: 19px;
}

@media (prefers-reduced-motion: reduce) {
    .e-switch,
    .e-switch__knob {
        transition: none;
    }
}

.e-check {
    all: unset;
    cursor: pointer;
    width: 17px;
    height: 17px;
    border-radius: var(--e-radius-sm);
    border: 1px solid var(--e-border-input);
    flex: 0 0 17px;
    display: grid;
    place-items: center;
    color: transparent;
    box-sizing: border-box;
}

.e-check--on {
    background: var(--e-brand);
    border-color: var(--e-brand);
    color: var(--e-brand-on);
}

.e-checkrow {
    display: flex;
    align-items: center;
    gap: 10px;
    font: 400 12.5px/1.4 var(--e-font);
    cursor: pointer;
}

.e-selectbox {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    height: 36px;
    border: 1px solid var(--e-border-input);
    border-radius: var(--e-radius);
    padding: 0 10px;
    font: 400 13px/1.4 var(--e-font);
    background: var(--e-surface);
    cursor: pointer;
    box-sizing: border-box;
}

.e-slider {
    height: 4px;
    border-radius: 2px;
    background: var(--e-border-subtle);
    position: relative;
}

.e-slider__fill {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    background: var(--e-brand);
    border-radius: 2px;
}

.e-slider__knob {
    position: absolute;
    top: -6px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--e-surface);
    border: 2px solid var(--e-brand);
    margin-left: -8px;
    box-sizing: border-box;
}

/* -- badges: the full alarm-state set -------------------------------------- */
.e-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 22px;
    padding: 0 8px;
    border-radius: var(--e-radius-sm);
    font: 600 10.5px/1.3 var(--e-font);
    letter-spacing: .04em;
    text-transform: uppercase;
    white-space: nowrap;
    background: var(--e-bg);
    color: var(--e-text-3);
}

.e-badge--alarm {
    background: var(--e-alarm-wash);
    color: var(--e-alarm-strong);
}

.e-badge--warn {
    background: var(--e-warn-wash);
    color: var(--e-warn-strong);
}

.e-badge--ok {
    background: var(--e-ok-wash);
    color: var(--e-ok-strong);
}

.e-badge--info {
    background: var(--e-info-wash);
    color: var(--e-info-strong);
}

.e-badge--brand {
    background: var(--e-brand-wash);
    color: var(--e-brand);
}

.e-badge--stale {
    background: var(--e-bg);
    color: var(--e-text-muted);
}

/* -- element state chip ---------------------------------------------------- */
.e-statechip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 26px;
    padding: 0 9px;
    border-radius: 13px;
    border: 1px solid var(--e-ok-wash);
    background: var(--e-ok-wash);
    color: var(--e-ok-strong);
    font: 500 11.5px/1.3 var(--e-font);
    white-space: nowrap;
}

.e-statechip--warn {
    border-color: var(--e-warn-line);
    background: var(--e-warn-wash);
    color: var(--e-warn-strong);
}

.e-statechip--alarm {
    border-color: var(--e-alarm-line-2);
    background: var(--e-alarm-wash);
    color: var(--e-alarm-strong);
}

.e-statechip--spare,
.e-statechip--stale {
    border-color: var(--e-border);
    background: var(--e-bg);
    color: var(--e-text-3);
}

.e-statechip--stale {
    color: var(--e-text-muted);
}

/* -- limit marker legend --------------------------------------------------- */
.e-limitmark {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font: 500 11.5px/1.3 var(--e-font-mono);
    color: var(--e-alarm-strong);
}

.e-limitmark__line {
    width: 18px;
    border-top: 2px dashed var(--e-alarm);
}

.e-limitmark--warn {
    color: var(--e-warn-strong);
}

.e-limitmark--warn .e-limitmark__line {
    border-top-color: var(--e-warn);
}

.e-limitmark--avg {
    color: var(--e-text-3);
}

.e-limitmark--avg .e-limitmark__line {
    border-top: 2px solid var(--e-text-faint);
}

/* -- feedback: toasts, spinner, progress ----------------------------------- */
.e-toast {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 11px 12px;
    border-radius: 7px;
    background: var(--e-info-wash);
    border: 1px solid var(--e-info-wash);
    color: var(--e-info-strong);
    font: 400 12.5px/1.5 var(--e-font);
}

.e-toast--ok {
    background: var(--e-ok-wash);
    border-color: var(--e-ok-wash);
    color: var(--e-ok-strong);
}

.e-toast--warn {
    background: var(--e-warn-wash);
    border-color: var(--e-warn-line);
    color: var(--e-warn-strong);
}

.e-toast--alarm {
    background: var(--e-alarm-wash);
    border-color: var(--e-alarm-line);
    color: var(--e-alarm-strong);
}

.e-toast__text {
    flex: 1 1 auto;
    min-width: 0;
}

.e-progress {
    height: 6px;
    border-radius: 3px;
    background: var(--e-border-subtle);
    overflow: hidden;
}

.e-progress__fill {
    height: 100%;
    background: var(--e-brand);
}

.e-spinner {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 2px solid var(--e-brand-wash-2);
    border-top-color: var(--e-brand);
    animation: e-spin .8s linear infinite;
    flex: 0 0 18px;
}

@keyframes e-spin {
    to {
        transform: rotate(360deg);
    }
}

@media (prefers-reduced-motion: reduce) {
    .e-spinner {
        animation-duration: 2.4s;
    }
}

/* ============================================ DATA DISPLAY (v2) ========== */
/*
 * The four value densities of the design, as one block with modifiers - a value
 * is the most repeated thing in this app, so it gets one class rather than
 * inline type at every call site.
 */
.e-value {
    display: flex;
    align-items: baseline;
    gap: 6px;
    min-width: 0;
}

.e-value__symbol {
    font: 500 11.5px/1.4 var(--e-font-mono);
    color: var(--e-brand);
    flex: 0 0 auto;
}

.e-value__number {
    font: 500 19px/1 var(--e-font-mono);
    font-variant-numeric: tabular-nums;
}

.e-value__unit {
    font: 400 11px/1.4 var(--e-font);
    color: var(--e-text-muted);
}

/* the hero density: a dashboard tile or a dialog's headline value */
.e-value--xl {
    gap: 8px;
}

.e-value--xl .e-value__number {
    font-size: 34px;
    letter-spacing: -0.02em;
}

.e-value--xl .e-value__unit {
    font-size: 13px;
    color: var(--e-text-3);
}

/* a labelled row: symbol, name, value, unit */
.e-value--row {
    align-items: center;
    gap: 8px;
    width: 100%;
    font: 400 12.5px/1.4 var(--e-font);
    color: var(--e-text-2);
}

.e-value--row .e-value__symbol {
    font-weight: 400;
}

.e-value--row .e-value__name {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-value--row .e-value__number {
    font-size: 13px;
    margin-left: auto;
}

/* inline: value plus the limit badges standing on it */
.e-value--inline {
    align-items: center;
    gap: 8px;
}

.e-value--inline .e-value__number {
    font-size: 13px;
}

/* a value the driver has not refreshed keeps the number and loses contrast */
.e-value--stale .e-value__number,
.e-value--stale .e-value__symbol,
.e-value--stale .e-value__unit {
    color: var(--e-text-faint);
}

/* spare elements are hatched, so "no value" never reads as "value zero" */
.e-cell--spare {
    opacity: 1;
    background: repeating-linear-gradient(45deg,
            var(--e-bg) 0 4px,
            var(--e-surface-row) 4px 8px);
    border-color: var(--e-border);
}

.e-cell--spare .e-cell__value {
    color: var(--e-text-muted);
}

/* -- table row states ------------------------------------------------------ */
.e-table__row--stale .e-table__cell,
.e-table__row--stale .e-table__cell--num {
    color: var(--e-text-faint);
}

/* =============================================== DIALOGS (v2) ============ */
/*
 * The dialog chrome, applied to MudBlazor's dialog rather than reimplemented:
 * every one of the ~40 dialogs in this app is a <MudDialog>, so styling the
 * three parts MudBlazor renders (title, content, actions) gives them all the
 * design's chrome at once. The structural pieces the design specifies inside a
 * dialog - labelled fields, bordered lists, notes, mini charts - are the
 * `.e-dlg-*` classes below, used by the dialogs converted by hand.
 */
.mud-dialog {
    border-radius: 10px;
    border: 1px solid var(--e-border);
    box-shadow: 0 8px 28px rgba(20, 20, 40, .10);
    overflow: hidden;
    background: var(--e-surface);
}

.mud-dialog .mud-dialog-title {
    padding: 14px 16px 12px;
    border-bottom: 1px solid var(--e-border-subtle);
    margin-bottom: 0;
}

.mud-dialog .mud-dialog-title,
.mud-dialog .mud-dialog-title .mud-typography {
    font: 600 14px/1.35 var(--e-font);
    color: var(--e-text);
}

.mud-dialog .mud-dialog-content {
    padding: 14px 16px;
    font: 400 12.5px/1.55 var(--e-font);
    color: var(--e-text-2);
}

.mud-dialog .mud-dialog-actions {
    padding: 12px 16px;
    background: var(--e-surface-sunken);
    border-top: 1px solid var(--e-border-subtle);
    gap: 8px;
    margin: 0;
}

/* the action buttons take the design's kinds from their MudBlazor colour */
.mud-dialog-actions .mud-button-root {
    min-height: 32px;
    height: 32px;
    padding: 0 13px;
    border-radius: var(--e-radius);
    font: 500 12.5px/30px var(--e-font);
    text-transform: none;
}

.mud-dialog-actions .mud-button-root.mud-button-text-primary,
.mud-dialog-actions .mud-button-root.mud-button-outlined-primary,
.mud-dialog-actions .mud-button-root.mud-button-filled-primary {
    background: var(--e-brand);
    border-color: var(--e-brand);
    color: var(--e-brand-on);
}

.mud-dialog-actions .mud-button-root.mud-button-text-error,
.mud-dialog-actions .mud-button-root.mud-button-outlined-error,
.mud-dialog-actions .mud-button-root.mud-button-filled-error {
    background: var(--e-alarm);
    border-color: var(--e-alarm);
    color: var(--e-brand-on);
}

.mud-dialog-actions .mud-button-root.mud-button-text-default,
.mud-dialog-actions .mud-button-root.mud-button-text-secondary,
.mud-dialog-actions .mud-button-root.mud-button-outlined-default,
.mud-dialog-actions .mud-button-root.mud-button-outlined-secondary {
    background: var(--e-surface);
    border: 1px solid var(--e-border);
    color: var(--e-text-2);
}

/* -- the structural pieces inside a dialog body ---------------------------- */
.e-dlg {
    display: flex;
    flex-direction: column;
    gap: 11px;
    min-width: min(420px, 78vw);
    max-width: 100%;
}

.e-dlg--wide {
    min-width: min(640px, 88vw);
}

/* the subtitle the design puts under a dialog title */
.e-dlg__subtitle {
    font: 400 11.5px/1.45 var(--e-font-mono);
    color: var(--e-text-muted);
}

.e-dlg__lead {
    font: 400 12.5px/1.55 var(--e-font);
    color: var(--e-text-2);
}

.e-dlg__fields {
    display: flex;
    flex-direction: column;
    gap: 9px;
}

.e-dlg__field {
    display: flex;
    align-items: center;
    gap: 10px;
}

.e-dlg__label {
    font: 400 11.5px/1.4 var(--e-font);
    color: var(--e-text-muted);
    width: 104px;
    flex: 0 0 104px;
}

.e-dlg__control {
    flex: 1 1 auto;
    min-width: 0;
}

.e-dlg__list {
    border: 1px solid var(--e-border-subtle);
    border-radius: 7px;
    overflow: hidden;
}

.e-dlg__item {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 8px 11px;
    border-bottom: 1px solid var(--e-border-faint);
    background: var(--e-surface);
    text-decoration: none;
    color: inherit;
}

.e-dlg__item:last-child {
    border-bottom: none;
}

.e-dlg__item--alarm {
    background: var(--e-alarm-row);
}

.e-dlg__item--muted {
    background: var(--e-surface-sunken);
}

a.e-dlg__item:hover {
    background: var(--e-surface-row);
    text-decoration: none;
}

.e-dlg__item-label {
    flex: 1 1 auto;
    font: 400 12.5px/1.45 var(--e-font);
    color: var(--e-text-2);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-dlg__item-value {
    font: 500 12px/1.4 var(--e-font-mono);
    white-space: nowrap;
    flex: 0 0 auto;
}

.e-dlg__note {
    font: 400 11.5px/1.5 var(--e-font);
    color: var(--e-text-muted);
    background: var(--e-surface-row);
    border: 1px solid var(--e-border-subtle);
    border-radius: var(--e-radius);
    padding: 8px 10px;
}

/* the small bar strip a result dialog shows instead of a full chart */
.e-dlg__chart {
    height: 116px;
    border: 1px solid var(--e-border-subtle);
    border-radius: var(--e-radius);
    background: var(--e-surface-inset);
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: flex-end;
    gap: 2px;
    padding: 6px;
    box-sizing: border-box;
}

.e-dlg__chart-limit {
    position: absolute;
    left: 0;
    right: 0;
    border-top: 1px dashed var(--e-alarm);
}

/* the record stepper a per-item dialog puts in its action bar */
.e-dlg__nav {
    display: flex;
    align-items: center;
    gap: 2px;
    flex: 0 0 auto;
    margin-right: auto;
}

/* ================================================= PAGES (v2) ============ */

/* -- system alerts: one card per alert, severity on the left edge ---------- */
.e-alertcard {
    background: var(--e-surface);
    border: 1px solid var(--e-border);
    border-left: 3px solid var(--e-info);
    border-radius: var(--e-radius-card);
    padding: 13px 16px;
    display: flex;
    align-items: flex-start;
    gap: 12px;
}

.e-alertcard--ok {
    border-left-color: var(--e-ok);
}

.e-alertcard--warn {
    border-left-color: var(--e-warn);
}

.e-alertcard--alarm {
    border-left-color: var(--e-alarm);
}

.e-alertcard__body {
    display: flex;
    flex-direction: column;
    gap: 5px;
    flex: 1 1 auto;
    min-width: 0;
}

.e-alertcard__head {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.e-alertcard__title {
    font: 600 13.5px/1.35 var(--e-font);
}

.e-alertcard__source {
    font: 400 11.5px/1.35 var(--e-font-mono);
    color: var(--e-text-muted);
}

.e-alertcard__text {
    font: 400 12.5px/1.55 var(--e-font);
    color: var(--e-text-2);
}

.e-alertcard__side {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 7px;
    flex: 0 0 auto;
}

.e-alertcard__time {
    font: 400 11.5px/1.35 var(--e-font-mono);
    color: var(--e-text-muted);
}

/* -- the three linked lists of the identity pages -------------------------- */
.e-adminlist__row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 14px;
    border-bottom: 1px solid var(--e-border-faint);
    cursor: pointer;
    background: var(--e-surface);
    text-decoration: none;
    color: inherit;
}

.e-adminlist__row:last-child {
    border-bottom: none;
}

.e-adminlist__row:hover {
    background: var(--e-surface-row);
    text-decoration: none;
    color: inherit;
}

.e-adminlist__row--on,
.e-adminlist__row--on:hover {
    background: var(--e-brand-wash);
}

.e-adminlist__dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--e-ok);
    flex: 0 0 7px;
}

.e-adminlist__dot--off {
    background: var(--e-border);
}

.e-adminlist__dot--info {
    background: var(--e-info);
}

.e-adminlist__dot--warn {
    background: var(--e-warn);
}

.e-adminlist__dot--brand {
    background: var(--e-brand);
}

.e-adminlist__text {
    display: flex;
    flex-direction: column;
    gap: 3px;
    flex: 1 1 auto;
    min-width: 0;
}

.e-adminlist__name {
    font: 500 12.5px/1.35 var(--e-font);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.e-adminlist__meta {
    font: 400 11px/1.35 var(--e-font-mono);
    color: var(--e-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* -- compact / control-room wall view -------------------------------------- */
.e-compact {
    background: var(--e-surface);
    border: 1px solid var(--e-border);
    border-top: 3px solid var(--e-ok-strong);
    border-radius: var(--e-radius-card);
    padding: 12px 14px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    text-decoration: none;
    color: inherit;
}

.e-compact:hover {
    text-decoration: none;
    color: inherit;
    border-color: var(--e-border-input);
}

.e-compact--warn {
    border-top-color: var(--e-warn-text);
}

.e-compact--alarm {
    border-top-color: var(--e-alarm);
}

.e-compact__head {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.e-compact__name {
    font: 600 16px/1.2 var(--e-font);
}

.e-compact__state {
    font: 600 10.5px/1.3 var(--e-font);
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--e-ok-strong);
    background: var(--e-ok-wash);
    padding: 3px 7px;
    border-radius: 10px;
    white-space: nowrap;
}

.e-compact__state--warn {
    color: var(--e-warn-text);
    background: var(--e-warn-wash);
}

.e-compact__state--alarm {
    color: var(--e-alarm);
    background: var(--e-alarm-wash);
}

.e-compact__big {
    margin-left: auto;
    font: 500 26px/1 var(--e-font-mono);
    font-variant-numeric: tabular-nums;
}

.e-compact__stats {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    font: 400 11.5px/1.4 var(--e-font);
    color: var(--e-text-3);
}

/* -- print sheet ----------------------------------------------------------- */
/*
 * A report on paper. The wrapper (.e-printpage) is the grey desk the white
 * sheet lies on and carries the orientation; the sheet (.e-sheet) is the A4
 * page with the report head and foot (ElovizPrintSheet). Two ways onto the
 * desk: the print layouts of the report windows, and the overlay ElovizPage
 * puts over a page when its print button is pressed.
 */
.e-printpage {
    box-sizing: border-box;
    min-height: 100vh;
    padding: 18px 20px 40px;
    display: flex;
    flex-direction: column;
    gap: 14px;
    align-items: center;
    background: var(--e-bg);
}

/* the orientation is a named page (@page below), set on BODY while a sheet is
   up so it names every page of the document. Naming only the sheet's own box
   put a blank portrait page in front of it - the empty boxes before the sheet
   (popover providers, the main column) sat on the default page, the named
   page forced a break, and Chrome then kept the paper portrait and rotated
   the landscape pages onto it. `page` propagates down from the body. */
body:has(.e-printpage--landscape) {
    page: e-landscape;
}

body:has(.e-printpage--portrait) {
    page: e-portrait;
}

/* a landscape sheet previews wider, at the page's aspect */
.e-printpage--landscape .e-printbar,
.e-printpage--landscape .e-sheet {
    max-width: 1120px;
}

/* the sheet a page puts up over itself: a full-screen preview above the
   sidebar, scrolling on its own; on paper it is the document */
.e-printpage--overlay {
    position: fixed;
    inset: 0;
    z-index: 50;
    overflow: auto;
}

.e-printbar {
    width: 100%;
    max-width: 900px;
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px;
}

.e-sheet {
    width: 100%;
    max-width: 900px;
    background: #fff;
    color: #1d2129;
    box-shadow: 0 2px 16px rgba(20, 20, 40, .12);
    padding: 34px 38px;
    display: flex;
    flex-direction: column;
    gap: 18px;
    box-sizing: border-box;
}

.e-sheet__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    border-bottom: 2px solid #1d2129;
    padding-bottom: 10px;
}

.e-sheet__title {
    font: 600 15px/1.3 var(--e-font);
}

.e-sheet__meta {
    font: 400 11px/1.4 var(--e-font-mono);
    color: #5b616e;
}

.e-sheet__brand {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
}

.e-sheet__brand img {
    display: block;
    height: 16px;
    width: auto;
    max-width: 120px;
}

.e-sheet__stamp {
    font: 400 10px/1.4 var(--e-font-mono);
    color: #8a909c;
}

.e-sheet__table {
    display: flex;
    flex-direction: column;
}

.e-sheet__row {
    display: grid;
    padding: 4px 0;
    border-bottom: 1px solid #eef0f3;
}

.e-sheet__row--head {
    border-bottom: 1px solid #1d2129;
    padding-bottom: 5px;
}

.e-sheet__th {
    font: 600 9.5px/1.3 var(--e-font);
    letter-spacing: .05em;
    text-transform: uppercase;
    color: #1d2129;
}

.e-sheet__cell {
    font: 400 10px/1.45 var(--e-font);
    color: #1d2129;
    padding-right: 6px;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* a mono cell is a timestamp, a path or a number: one line, cut with an
   ellipsis rather than wrapped - a wrapped timestamp doubles the row */
.e-sheet__cell--mono {
    font-family: var(--e-font-mono);
    white-space: nowrap;
}

.e-sheet__foot {
    margin-top: auto;
    padding-top: 10px;
    border-top: 1px solid #cfd3da;
    display: flex;
    justify-content: space-between;
    gap: 16px;
    font: 400 9.5px/1.4 var(--e-font-mono);
    color: #8a909c;
}

/* one printed page of a sheet - a trend report is one chart per page; the
   break is previewed as a dashed rule */
.e-sheet__page {
    display: flex;
    flex-direction: column;
    gap: 10px;
    break-inside: avoid;
}

.e-sheet__page + .e-sheet__page {
    border-top: 1px dashed #cfd3da;
    padding-top: 18px;
    break-before: page;
}

.e-sheet__caption {
    font: 600 12px/1.3 var(--e-font);
    color: #1d2129;
}

/* a chart on the sheet: the printable width of A4 landscape at the page
   margins below, the same on screen and on paper - the chart's canvas is
   drawn at its on-screen size and does not follow the print re-layout. The height
   leaves room on the 186 mm page for the sheet head, the caption, a wrapped
   legend and the foot: taller, and break-inside: avoid pushes the chart to a
   page of its own, leaving the head alone on the first. */
.e-sheet__chart {
    width: 273mm;
    max-width: 100%;
    height: 125mm;
}

/* a paragraph on the sheet - a comment, a note */
.e-sheet__text {
    font: 400 10.5px/1.5 var(--e-font);
    color: #1d2129;
    white-space: pre-wrap;
}

/* on paper the sheet is the page: no shadow, no outer chrome */
@media print {
    @page e-landscape {
        size: A4 landscape;
        margin: 12mm;
    }

    @page e-portrait {
        size: A4 portrait;
        margin: 12mm;
    }

    .e-printpage {
        min-height: 0;
        padding: 0;
        background: #fff;
    }

    .e-printpage--overlay {
        position: static;
        overflow: visible;
    }

    .e-printbar {
        display: none !important;
    }

    .e-sheet,
    .e-printpage--landscape .e-sheet {
        max-width: none;
        box-shadow: none;
        padding: 0;
    }

    .e-sheet__page + .e-sheet__page {
        border-top: none;
        padding-top: 0;
    }

    /* a page that put its sheet up prints the sheet, not the screen page behind it */
    .e-main:has(> .e-printpage) > :not(.e-printpage) {
        display: none !important;
    }

    /* the brand tile keeps its colour - white artwork on white paper is no mark */
    .e-brandmark {
        print-color-adjust: exact;
        -webkit-print-color-adjust: exact;
    }
}

/* -- error / empty / permission states ------------------------------------- */
.e-statecard {
    background: var(--e-surface);
    border: 1px solid var(--e-border);
    border-radius: var(--e-radius-card);
    padding: 22px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    align-items: flex-start;
}

.e-statecard__icon {
    font-size: 26px;
    color: var(--e-info);
}

.e-statecard__icon--ok {
    color: var(--e-ok);
}

.e-statecard__icon--warn {
    color: var(--e-warn);
}

.e-statecard__icon--alarm {
    color: var(--e-alarm);
}

.e-statecard__icon--muted {
    color: var(--e-text-3);
}

.e-statecard__title {
    font: 600 15px/1.35 var(--e-font);
    margin: 0;
}

.e-statecard__body {
    font: 400 12.5px/1.55 var(--e-font);
    color: var(--e-text-3);
}

.e-statecard__detail {
    font: 400 11.5px/1.5 var(--e-font-mono);
    color: var(--e-text-muted);
    background: var(--e-surface-row);
    border: 1px solid var(--e-border-subtle);
    border-radius: var(--e-radius);
    padding: 8px 10px;
    width: 100%;
    box-sizing: border-box;
    overflow-wrap: anywhere;
}

.e-statecard__actions {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}

/* -- about page ------------------------------------------------------------ */
.e-about__rows {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.e-about__row {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--e-border-faint);
}

.e-about__label {
    font: 400 12px/1.4 var(--e-font);
    color: var(--e-text-muted);
    width: 130px;
    flex: 0 0 130px;
}

.e-about__value {
    font: 500 12.5px/1.4 var(--e-font-mono);
    color: var(--e-text);
    overflow-wrap: anywhere;
}

.e-about__link {
    display: flex;
    align-items: center;
    gap: 9px;
    font: 400 12.5px/1.5 var(--e-font);
    color: var(--e-brand);
    text-decoration: none;
}

.e-about__link:hover {
    text-decoration: underline;
}

/* -- single value trend: the stat strip above the plot --------------------- */
.e-trendstats {
    display: flex;
    gap: 20px;
    flex-wrap: wrap;
}

.e-trendstat {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.e-trendstat__label {
    font: 500 10.5px/1.3 var(--e-font);
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--e-text-muted);
}

.e-trendstat__value {
    font: 500 17px/1.2 var(--e-font-mono);
    font-variant-numeric: tabular-nums;
}
